Skip to content

PATTERN Cited by 1 source

Per-entrypoint cache stage

Problem

Applications have parts that must run on every request (authentication, rate limiting, routing) and parts that produce cacheable output (rendering, data aggregation, API reads). Traditional CDN caches force a binary choice — cache the entire response or don't — because the cache sits at a single boundary in front of the whole application.

Solution

Place the cache between internal entrypoints of a single deployable unit. Each entrypoint independently opts in or out of caching:

  1. Disable caching on gateway/auth entrypoints (they must always run; their output should never be served from cache because that would skip the auth check).
  2. Enable caching on expensive compute entrypoints (they produce responses keyed by entrypoint + path + query + caller identity).

The caller always runs; the callee runs only on a miss. The cache stage isn't bolted on — it's a layer of the program, configured by the code on either side.

Structure

Request → [Gateway entrypoint: cache OFF — always runs]
                    ↓ ctx.exports.CachedBackend.fetch(req, { props: { userId } })
          [Cache evaluation: hit? return cached. miss? run callee]
                    ↓ (on miss)
          [CachedBackend entrypoint: cache ON — runs, stores response]

Configuration (Cloudflare Workers)

{
  "cache": { "enabled": true },
  "exports": {
    "default": { "type": "worker", "cache": { "enabled": false } },
    "CachedBackend": { "type": "worker", "cache": { "enabled": true } }
  }
}

Consequences

  • Composable: Stack multiple cache stages — auth → normalization → cached read → cached sub-read — each with its own key/TTL/tag namespace.
  • Write-path invalidation is co-located: The entrypoint that owns the cached response also owns ctx.cache.purge() — writes can invalidate precisely.
  • No infrastructure to provision: No separate cache service, no rules engine, no zone configuration.

Known uses

Last updated · 568 distilled / 1,686 read