Skip to content
On this page

Cache Invalidation ​

Invalidate cached session data for efficient cache management in distributed systems.


Overview ​

The cache invalidation endpoint allows authenticated users to clear their own cached session data. This is particularly useful when:

  • Backend systems update user data directly in the database
  • You need to ensure fresh data is loaded on the next request
  • Profile changes made outside the standard flow need to be reflected immediately
  • Multiple backend services share the same Flowless core

Endpoint ​

http
POST /auth/invalidate/me

Authentication: Required (Session-based)

Rate Limit: 10 requests per 5 minutes (per user)


How It Works ​

Cache Invalidation Flow ​

Dual Cache Architecture ​

Flowless uses a hybrid caching system for maximum performance:

  1. UnifiedSessionCache (LRU) - Fast in-memory local cache
  2. Ultra/Redis - Distributed cache shared across instances

When you call /auth/invalidate/me, both caches are cleared simultaneously, ensuring:

  • No stale data in any cache layer
  • Next request fetches from database
  • Automatic repopulation with fresh data

Request ​

Headers ​

http
X-Session-ID: your-session-id-here
Content-Type: application/json

Request Body ​

No request body required. The endpoint invalidates the cache for the authenticated user making the request.


Response ​

Success Response (200 OK) ​

json
{
  "success": true,
  "message": "Cache invalidated successfully. Fresh data will be loaded on next request.",
  "data": {
    "invalidatedSessions": 2,
    "executionTime": 15,
    "strategy": "invalidate",
    "nextRequestSource": "database"
  },
  "rateLimitInfo": {
    "remaining": 9,
    "resetTime": 1738483200000
  }
}

Response Fields:

  • invalidatedSessions - Number of cached sessions cleared (user may have multiple active sessions)
  • executionTime - Time taken to invalidate cache (milliseconds)
  • strategy - Cache update strategy used (always "invalidate" for this endpoint)
  • nextRequestSource - Indicates next request will fetch from "database"
  • rateLimitInfo.remaining - Remaining invalidation requests in current window
  • rateLimitInfo.resetTime - Unix timestamp when rate limit resets

Rate Limit Exceeded (429) ​

json
{
  "success": false,
  "error": "Too many cache invalidation requests. Please try again later.",
  "resetTime": 1738483200000,
  "remaining": 0,
  "code": "RATE_LIMIT_EXCEEDED"
}

Unauthorized (401) ​

json
{
  "success": false,
  "error": "Invalid or expired session"
}

Rate Limiting ​

The cache invalidation endpoint uses intelligent rate limiting to prevent abuse:

Limit TypeValueWindowIdentifier
Per User10 requests5 minutesUser ID

Why per-user limiting?

  • Self-service model - users manage their own cache
  • Prevents individual user abuse
  • Doesn't block other users
  • Distributed tracking via Redis

Why 10 requests per 5 minutes?

  • Balances legitimate use (profile updates, app synchronization) vs abuse
  • More permissive than password reset (3/hour) - cache invalidation is less critical
  • Less permissive than registration (10/min) - prevents spam
  • Allows occasional bursts while preventing sustained abuse

Use Cases ​

1. Backend Direct Updates ​

When your backend (Flowfull) updates user data directly:

typescript
// Backend updates user profile directly in database
await db.updateTable('users')
  .set({ name: 'New Name', picture: 'new-url.jpg' })
  .where('id', '=', userId)
  .execute();

// Notify user to invalidate cache on their next interaction
// OR call invalidate from backend using the user's session
await fetch(`${FLOWLESS_URL}/auth/invalidate/me`, {
  method: 'POST',
  headers: {
    'X-Session-ID': userSessionId,
  }
});

2. Multi-Backend Synchronization ​

When multiple backends share the same Flowless instance:

typescript
// Backend A updates user
await backendA.updateUser(userId, { role: 'premium' });

// Backend B needs fresh data
// User calls invalidate/me, then next request to Backend B gets fresh data

3. Profile Import/Migration ​

When importing user data from external systems:

typescript
// Import data from legacy system
await importUserData(userId, externalData);

// Clear cache so user sees updated data immediately
await invalidateUserCache(sessionId);

Best Practices ​

✅ DO ​

  • Call this endpoint after updating user data in your backend
  • Use it for occasional cache refreshes when needed
  • Implement proper error handling for rate limits
  • Monitor rate limit headers to avoid hitting limits

❌ DON'T ​

  • Call on every request (defeats the purpose of caching)
  • Use as a substitute for proper cache update strategies
  • Ignore rate limit errors (implement backoff)
  • Call from frontend without user action (waste of resources)

Example Integration ​

Frontend Example (React) ​

typescript
import { useState } from 'react';

function ProfileSync() {
  const [syncing, setSyncing] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const handleSyncProfile = async () => {
    setSyncing(true);
    setError(null);

    try {
      const sessionId = localStorage.getItem('session_id');

      // 1. Invalidate cache
      const invalidateResponse = await fetch(
        `${FLOWLESS_URL}/auth/invalidate/me`,
        {
          method: 'POST',
          headers: {
            'X-Session-ID': sessionId!,
          },
        }
      );

      const invalidateData = await invalidateResponse.json();

      if (!invalidateData.success) {
        throw new Error(invalidateData.error);
      }

      // 2. Fetch fresh profile data
      const profileResponse = await fetch(`${FLOWLESS_URL}/auth/me`, {
        headers: {
          'X-Session-ID': sessionId!,
        },
      });

      const profileData = await profileResponse.json();

      if (profileData.success) {
        console.log('Profile synced with fresh data:', profileData.data.user);
      }

    } catch (err: any) {
      if (err.message.includes('rate limit')) {
        setError('Too many sync requests. Please wait a few minutes.');
      } else {
        setError(err.message);
      }
    } finally {
      setSyncing(false);
    }
  };

  return (
    <div>
      <button onClick={handleSyncProfile} disabled={syncing}>
        {syncing ? 'Syncing...' : 'Sync Profile'}
      </button>
      {error && <p className="error">{error}</p>}
    </div>
  );
}

Backend Example (Node.js/Hono) ​

typescript
// After updating user data in your backend
async function updateUserAndInvalidateCache(
  userId: string,
  updates: Record<string, any>,
  sessionId: string
) {
  // 1. Update user data in your database
  await db.updateTable('users')
    .set(updates)
    .where('id', '=', userId)
    .execute();

  // 2. Invalidate Flowless cache
  try {
    await fetch(`${process.env.FLOWLESS_URL}/auth/invalidate/me`, {
      method: 'POST',
      headers: {
        'X-Session-ID': sessionId,
      },
    });
    console.log('Cache invalidated, next request will fetch fresh data');
  } catch (error) {
    console.warn('Cache invalidation failed (non-critical):', error);
    // Don't fail the operation if cache invalidation fails
  }

  return { success: true };
}

Performance Characteristics ​

MetricValue
Average Response Time~15-30ms
Cache Layers Cleared2 (UnifiedCache + Ultra/Redis)
Database Operations0 (no DB writes)
Sessions AffectedAll active sessions for the user

Security Considerations ​

  • ✅ Authentication Required - Only authenticated users can invalidate cache
  • ✅ Self-Service Only - Users can only invalidate their own cache
  • ✅ Rate Limited - 10 requests per 5 minutes prevents abuse
  • ✅ Audit Logging - All invalidation attempts are logged
  • ✅ Distributed Tracking - Rate limits tracked in Redis across instances


FAQ ​

When should I use this endpoint? ​

Use it when:

  • Your backend updates user data directly in the database
  • You need to force fresh data loading
  • Multiple backends share the same Flowless instance
  • You're debugging cache-related issues

How often can I call this? ​

Up to 10 times per 5 minutes per user. If you need more frequent invalidation, consider:

  • Using the standard update endpoints (they auto-update cache)
  • Adjusting your architecture to use cache-aware updates
  • Implementing a cache warming strategy

What happens to other users? ​

Nothing. This endpoint only invalidates the cache for the authenticated user making the request. Other users' caches are unaffected.

Does this log me out? ​

No. This only clears cached session data. Your session remains active. The next request will simply fetch fresh data from the database and repopulate the cache.

What if I have multiple devices/sessions? ​

All cached sessions for your user ID are invalidated across all devices. The next request from any device will fetch fresh data.


Next Steps ​