Skip to content

PATTERN Cited by 1 source

Intercepting proxy for transparent cache

Pattern

Deploy a cache as an external service that intercepts requests at an existing routing / load-balancing layer (a Router, Broker, L7 LB, or API gateway). Requests matching cacheable shapes are redirected to the cache; requests not matching pass through unchanged. On a cache miss, the cache issues a (possibly narrowed) request back through the routing layer but bypasses the redirect so the call reaches the real backend.

Key properties:

  • Zero-change for clients — dashboards / consumers send the same requests to the same endpoint; the cache is injected by infrastructure.
  • Pass-through for uncacheable requests — metadata queries, non-time-group-by queries, anything the cache doesn't understand — falls through transparently.
  • Back-through for cache misses — the cache uses the same routing layer to fetch from the backend (no separate backend client), with a flag that tells the router not to redirect again (avoiding infinite loops).
  • Response byte-for-byte identical — the client should not be able to tell from the response whether the cache was involved.

Netflix's Druid Router implementation

Netflix's Druid interval cache uses this shape (Source: sources/2026-04-06-netflix-stop-answering-the-same-question-twice-interval-aware-caching-for-druid):

  • Requests hit the Druid Router first.
  • Router redirects cacheable queries (timeseries, groupBy with a time group-by) to the cache.
  • Cache returns a result if it fully satisfies the request.
  • On a partial hit, the cache shrinks the interval to the uncached portion and calls back into the Router, bypassing the redirect, to query Druid.
  • Non-cacheable queries (metadata, queries without time group-bys) pass straight through to Druid unchanged.

Netflix's explicit framing:

"This intercepting proxy design allows us to enable or disable caching without any client changes and is a key to its adoption."

When to use

  • Existing routing layer already sits in front of the backend.
  • Clients are numerous / diverse / hard to change (many dashboard tools, multiple SDK versions).
  • The caching capability is experimental — you want to enable / disable without client awareness.
  • You plan to eventually upstream the capability into the backend and want to minimise client coupling during the transition phase.

When not to use

  • Clients are few and co-owned — you can just make them use a cache client library.
  • Request patterns are so asymmetric / shape-specific that parsing the request at the proxy layer is expensive.
  • The proxy layer itself is under-provisioned — adding a cache intercept adds hop latency + CPU for parsing.

Trade-offs Netflix calls out

Netflix explicitly flags the downsides of the external-proxy shape (Source: sources/2026-04-06-netflix-stop-answering-the-same-question-twice-interval-aware-caching-for-druid):

"We see this setup as temporary while we work out a way to better integrate this capability into Druid more natively. ... an external proxy adds infrastructure to manage, extra network hops, and workarounds (like SQL templating) to extract intervals. Implemented inside Druid, it could be more efficient, with direct access to the query planner and segment metadata."

The pattern is a good first implementation — low coupling, reversible, testable — but not a permanent architecture.

Relationship to patterns/caching-proxy-tier

The caching-proxy tier pattern is the broader shape — deploying a cache as its own network tier. Intercepting-proxy-for-transparent-cache is the zero-client-change variant of that pattern — the proxy is injected transparently via routing rather than fronting clients explicitly. Fly.io's Hyperdrive (front-of-Postgres), CDNs (front-of-origin), and this Netflix-Druid cache are all instances of the broader caching-proxy-tier pattern; Netflix's specific twist is the Router-level interception that preserves a single client endpoint.

Seen in

Last updated · 319 distilled / 1,201 read