Scope and Visibility of Cached Data

Who is allowed to reuse a cached entry and why scope mistakes become correctness and security bugs.

Cache scope answers a simple but critical question: who may reuse this entry? The answer might be one function call, one request, one user session, one tenant, one region, or every user globally. That is not just a performance detail. It is a correctness and security boundary. If the cache is broader than the real audience, the system can leak data or reuse the wrong answer across callers.

This is why scope and key design are tightly linked. The key must encode any dimension that changes who can safely see or reuse the value. If it does not, the cache may be fast and wrong in a very serious way.

    flowchart TD
	    A["Possible cache scopes"] --> B["Request-local"]
	    A --> C["User-specific"]
	    A --> D["Tenant-specific"]
	    A --> E["Region-specific"]
	    A --> F["Global/shared"]
	    F --> G["Highest reuse\nhighest risk if mis-scoped"]

Why It Matters

Many of the worst cache incidents are really scope incidents:

  • one tenant sees another tenant’s data
  • one user gets a response shaped by another user’s entitlements
  • a region-specific price or regulation is reused globally
  • an internal response is accidentally cached in a public layer

Those are not minor tuning problems. They are category errors in cache visibility.

Common Cache Scopes

Some scopes are naturally low-risk:

  • request-local memoization
  • process-local caches for non-sensitive shared metadata

Some need much stronger discipline:

  • user-scoped caches
  • tenant-scoped shared caches
  • region-scoped content with regulatory or pricing differences
  • globally shared caches in front of mixed public and private data

The broader the scope, the more explicitly the system should prove that reuse is safe.

Example

This cache policy sketch makes scope explicit instead of burying it in code comments.

 1caches:
 2  exchange_rates:
 3    scope: global
 4    key_dimensions: [base_currency, quote_currency]
 5
 6  user_dashboard:
 7    scope: user
 8    key_dimensions: [user_id, locale, dashboard_version]
 9
10  tenant_catalog:
11    scope: tenant
12    key_dimensions: [tenant_id, category_id, locale]

What to notice:

  • scope is named explicitly, not implied
  • broader scope requires stronger confidence that the value is truly shareable
  • key dimensions should reflect the scope boundary directly

Visibility Should Match Trust Boundaries

Cache layers often cross infrastructure boundaries that application developers forget about. A CDN is broader than an application-instance cache. A shared distributed cache is broader than request-local memoization. As visibility expands, trust assumptions must be revisited. A value safe for one scope may be unsafe in a broader one even if the payload looks similar.

This is why moving a cache “one layer up” is rarely just an infrastructure decision. It changes who may see and reuse the answer.

Common Mistakes

  • treating personalized responses as globally cacheable because the payload looks small
  • forgetting tenant or role scope in a shared cache key
  • promoting a cache from local to shared infrastructure without revisiting visibility assumptions
  • assuming “read-only” means “safe to share globally”

Design Review Question

What should a team ask before moving a cacheable response from an application-local cache to a CDN or reverse proxy?

The stronger answer is not just whether the response is frequently requested. It is whether the response is truly safe for that broader visibility scope, and whether every key dimension needed to preserve that safety is explicit.

Quiz Time

Loading quiz…
Revised on Thursday, April 23, 2026