Edge computing usually starts small. A team deploys one Cloudflare Worker that rewrites a header or routes a request, and it works beautifully. Then the product grows. In a detailed article for InfoQ, Chintan Tank describes what happened when that single worker sat in front of web traffic for hundreds of thousands of tenant accounts, and how his team broke it apart without paying the latency penalty that usually comes with splitting a monolith.
The monolith problem, now at the edge
Over time, the one worker took on image optimization, failover pages, routing, header and cookie rewriting and per-tenant configuration lookups. Each feature belonged to a different team, yet they all shipped in the same script. Tank identifies four ways this hurts.
First, deployment coupling: any change redeploys everything, so a tiny fix waits behind a half-finished experiment, and rolling back one feature rolls back all of them. Second, blast radius: a worker is the request path itself, so one bad regular expression or unhandled exception degrades every feature for every tenant at the same time. Third, platform limits: workers have a per-request CPU budget and a script size cap, and every team's dependencies inflate a shared bundle. Fourth, ownership: rarely changing failover logic and a fast-moving image pipeline end up fighting over the same file.
None of this is new. It is the same story that led application teams toward services a decade ago. The difference is that at the edge, coupling quickly becomes an availability risk.
Gateway plus feature workers
Splitting a backend monolith normally adds network hops: DNS, TLS and a round trip per internal call. At the edge, where the point is to shave milliseconds, that looks unaffordable. Tank's argument is that on Cloudflare it is not, thanks to service bindings. Cloudflare's documentation says that by default a worker calling another worker over a service binding runs on the same thread of the same server, with no added latency, unless features such as Smart Placement move them apart.
The resulting design is a thin gateway worker in front of single-purpose feature workers. The gateway handles composition, meaning which features apply and in what order, plus cross-cutting concerns such as request preparation and observability. It does not contain feature logic. Each feature exposes a cheap predicate that the gateway runs inline, and only if that predicate says work is needed does the gateway call the feature worker. Tank sums this up as deciding inline and executing remotely.
Two resilience rules follow. A feature that fails must never fail the request: if a feature worker errors or times out, the gateway serves the unmodified origin response. And all workers live in one monorepo, with each one built and deployed independently, so teams share a single source of truth for the contract without sharing a deployment.
The trade-off he highlights is observability. A monolith sees the whole request; a chain of workers sees only fragments, and diagnostics captured inside a downstream worker do not automatically flow back to the gateway. End-to-end tracing becomes real work.
Two CDNs, two architectures
The platform also runs on Akamai, and this is where the article becomes especially useful. Tank built the same image optimization feature on both providers and found that porting it meant re-architecting it.
On Cloudflare the worker owns the request and can call other workers and the image transform directly. On Akamai the core unit is a property, a rules engine, and image optimization is a managed product enabled by a rule. An EdgeWorker runs at defined lifecycle events and, in this case, could only write a decision into a request variable that a rule downstream reads. Data storage differed too: Cloudflare Workers KV is global, while the Akamai EdgeKV namespaces his team used were regional at the time, so the Akamai code had to map continents to stores. Akamai later added a global option, which illustrates his point that parity between providers is never finished.
What did carry over were the invariants the edge itself imposes. Both platforms cap memory, so both implementations put a small, bounded, short-lived cache in front of the key-value store.
Image optimization as a build-or-buy lesson
Rather than use a coarse zone-wide toggle, the team wrote its own policy in code, made of three ordered decisions. Security comes first: never optimize an image that might be private, because caching it at a shared edge could serve it to someone the origin would have refused. Next is format: pick AVIF or WebP only if the client's Accept header says it can decode them. Finally, size: cap width according to device class. A per-tenant opt-out lets any customer disable optimization without a deployment, and any failure in the transform falls back to the original image. In Tank's framing, the original image is the guarantee and optimization is only a bonus.
Deploying to hundreds of thousands of tenants
At this scale, replacing everything at once is a deliberate choice of maximum blast radius. The team pins each release as an immutable set of worker versions under a tag, so rollback simply means redeploying the previous tag. Rollouts move through cohorts, starting with internal and pre-production accounts, with automated checks and a human gate between phases. Tank describes a regression involving streamed request bodies and redirects that surfaced in the canary cohort and was fixed by redeploying the previous release. Configuration such as tenant opt-outs lives in a separate data plane and changes without a code deployment.
Testing edge code like application code
The predicate design pays off in testing. Because each predicate is a pure function of the request and configuration, it can be unit tested quickly without any edge runtime. Integration tests at the gateway focus on failure, forcing feature workers to throw or time out and checking that users still get a valid response. Finally, synthetic monitoring runs scripted requests against production per region and per CDN, because some platform behavior can only be observed live.
Why it matters and what to take away
Even if you never run a multi-CDN platform, the patterns transfer well.
Decompose along cost boundaries: run cheap decisions inline and invoke heavier modules only when needed.
Treat optional enhancements as optional; the worst case should be invisible to users.
When you cannot standardize the vendor, standardize the invariants and expect the vendor-specific parts to drift.
Separate code changes from configuration changes by how often they happen and how much they can break.
Version releases immutably and roll out by cohort, so rollback is routine rather than heroic.
Edge code deserves the same testing discipline as backend services, including production synthetics.
For teams putting more logic at the edge, the article is a reminder that small scripts become critical infrastructure surprisingly quickly, and that it is far easier to design for modularity before the monolith forms.
Source: Chintan Tank, InfoQ, original article linked below.