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.
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.
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?
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`
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
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.
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