Skip to content

PATTERN Cited by 1 source

Cache between service bindings

Problem

Web applications face a tension between running code close to the user (minimizes user-to-server RTT) and running code close to the data (minimizes server-to-database RTT). Choosing one makes the other slow.

Solution

Compose two Workers connected by a service binding, with a cache stage between them:

  • Worker A runs near the user — handles cheap, latency-sensitive parts (auth, routing, shell rendering).
  • Worker B runs near the data (via Smart Placement or explicit Placement Hints) — handles expensive work (server-rendering, DB reads, aggregation).
  • Workers Cache sits in front of Worker B: When Worker A calls B over a service binding, the cache is checked first. On a hit, Worker A gets the response without the data-hop.

The cache hit path: user → Worker A (near user) → cache hit for Worker B → response. The data hop is paid only on a miss.

Structure

User (nearby)
  → Worker A [near user, no cache — always runs]
      → service binding call to Worker B
          → [Cache: hit? return. miss? route to Worker B]
              → Worker B [near data via Smart Placement — runs on miss]

Configuration

// Worker B's wrangler.jsonc
{ "cache": { "enabled": true } }

No special setup in Worker A. Just point a service binding at Worker B and turn caching on in B's config.

Consequences

  • Near-user latency for hot pages: Cache hits avoid any data-center hop.
  • Near-data efficiency for cold pages: Misses still benefit from Smart Placement.
  • No expert configuration: Write two Workers, connect with a service binding, enable caching on the data-heavy one.
  • Current limitation: Upper-tier cache and Smart Placement target are chosen separately; a full miss may traverse the network twice. Fix in progress.

Known uses

Last updated · 568 distilled / 1,686 read