All guides

LEARN \u00b7 DEBUGGING GUIDE

Stale cache key bug: how to debug cache key collisions

User A makes a request and sees User B's data. The cache key is `user-profile` instead of `user-profile:user-123`. A single cache slot is shared across everyone.

IntermediateDatabase/debugging

What this usually means

A cache key must uniquely identify the exact piece of data being cached. If the key misses a dimension — a user ID, a tenant ID, a locale, a query parameter — the cache will return data that was cached for a different context. The most dangerous version of this is a cache key that omits the user or tenant identifier, causing cross-tenant data leaks.

( 01 )Fast diagnosis

The first ten minutes \u2014 establish facts before touching code.

  • 1Look at the cache key generation code. List every variable that influences the cached data. Is every variable included in the key?
  • 2Check if the cache key includes the tenant or user ID. A key like `product-list` is shared across all tenants.
  • 3Inspect the cache directly (Redis `KEYS *`, or your cache dashboard). Look for keys that would collide across users.
  • 4Trace two different users making the same request. Do they hit the same cache key? They should not.
  • 5Check if the cache key is built from the request URL only, without auth context. Different authenticated users get the same key.
( 02 )Where to look

The specific files, logs, configs, and dashboards that usually own this bug.

  • searchCache key generation function — what variables are used to build the key?
  • searchCache middleware or decorator — how is the cache key derived from the request?
  • searchRedis or cache dashboard — list keys, inspect values, check TTLs
  • searchApplication code that reads from and writes to cache — are reads and writes using the same key logic?
  • searchUser/tenant context in the request — is it available when the cache key is built?
( 03 )Common root causes

Practical causes, not theory. These are the things you will actually find.

  • warningCache key omits the user ID — all users share one cache slot
  • warningCache key omits the tenant or organisation ID — cross-tenant data leak
  • warningCache key includes a query parameter that differs between users but not the auth context
  • warningCache key uses a non-unique identifier (e.g. `username` instead of `userId`)
  • warningCache key is built before auth middleware adds the user context to the request
  • warningMultiple data types share the same key namespace — a user profile and an order both use key `:123`
( 04 )Fix patterns

Concrete fix directions. Pick the one that matches your root cause.

  • buildAlways include the user ID, tenant ID, and any request-specific parameters in the cache key
  • buildUse a key builder function that constructs keys from a structured object, not string concatenation
  • buildAdd a namespace prefix per data type: `user:123:profile`, `order:456:details`, `tenant:789:products`
  • buildValidate that the cache key contains all required dimensions before reading or writing
  • buildAdd integration tests that verify different users get different cached data for the same endpoint
( 05 )How to verify

A fix you cannot prove is a guess. Close the loop.

  • verifiedMake the same API request as two different users. Confirm the responses differ and are correct for each user.
  • verifiedCheck the cache directly — two different keys should exist for two different users.
  • verifiedAdd an assertion in code that the cache key contains the user/tenant ID before cache operations.
  • verifiedRun a test where User A's data is cached, then User B makes the same request. User B should not see User A's data.
  • verifiedDeploy to staging and verify multi-tenant isolation with real tenant data.
( 06 )Mistakes to avoid

Things that make this bug worse or harder to find.

  • warningUsing the request URL alone as the cache key without auth context
  • warningNot testing cache isolation across different users or tenants
  • warningUsing cache libraries with default key generation that does not include auth context
  • warningAdding the user ID to the cache key later but forgetting to invalidate old keys
  • warningAssuming 'it only happens in production' — test cache key isolation in all environments