Pages: Removing the routing bottleneck

Cloudflare Pages has spent two years serving fast applications, but the architecture that got it there began to show strain. The problem: as projects grew past thousands of deployments, every request picked up measurable latency. With tens of thousands of deployments — common for teams that create preview deployments for every commit — the platform risked punishing the very workflow it encouraged.

The fix, rolled out this week, cuts that overhead dramatically. For asset requests, time to first byte (TTFB) is now up to 10x faster. The engineering story is how Pages adopted Workers for Platforms — Cloudflare's system for building SaaS platforms on Workers — to turn an O(n) runtime lookup into an O(1) hash.

Where the latency came from

Pages runs static asset serving through a highly optimized Worker called the Asset Server Worker. Users can add dynamic behavior with Pages Functions, which compile into separate Workers. Every deployment corresponds to a pipeline of these Workers, and when a request arrives, Cloudflare must decide which pipeline to execute — a decision based on the hostname in the URL. For https://2b469e16.example.pages.dev/index.html, the hostname is unique across all Pages deployments; 2b469e16 is the commit hash and example is the project name.

Each project kept a routing table: a JSON object mapping regexes for every deployment's possible paths to their pipelines. A request to a project meant downloading that table from Quicksilver, parsing it, and iterating the regexes until hitting the match. That approach had a real ceiling on performance. In one realistic case, parsing the JSON alone took 107ms; iterating the regexes added 29ms. For a project with 10,000 deployments, a request needed 136ms just to pick the right pipeline. Projects reaching 50,000 deployments could see seconds of added latency, causing timeouts as browsers fetched multiple assets. This created an experience that was as unstable as it was slow.

Workers for Platforms was designed for exactly this kind of dispatch problem. Lookups there were built as O(1), not O(n), regardless of how many Workers an account holds. Pages needed to dispatch by hostname, however, not a Worker name — so the team decided to hash the thing they had.

At deployment time, they created a hash of the pipeline for the deployment by its hostname using a predefined secret. At request time, Pages hashes the hostname from the URL and uses that directly to look up the pipeline. No more fetching, parsing, or traversing a multi-megabyte routing table JSON.

Verifying on a real user: Developer Docs

Before migrating everyone, the team needed proof at scale. Cloudflare's own Developer Docs site, running on Pages since early 2022, became the test subject. The team A/B-tested the new setup, keeping the ability to revert per site if anything broke.

The results were clear. Before the switch, Developer Docs TTFB averaged about 600ms. After opting in, the average dropped to 60ms. Page load times followed, and Lighthouse scores moved from an average of 78 toward a perfect 100 — all without downtime or engineering changes on the Developer Docs side.

The big migration: 14 million deployments

Migrating every Pages deployment ever created was the real challenge. That number had reached 14 million, and the team wanted no user left behind — and no site taken down. The migration strategy was governed by a few key principles:

  • No downtime. Everything must happen under the hood without affecting sites.
  • A/B rollout. The team needed to route traffic to old or new infrastructure per site or per data center, with an explicit opt-out for edge cases.
  • Slow and patient. Migrations at this scale exceed the request capacity of typical APIs if run in a short window, so the process was deliberately paced.
  • Observable and retryable. Long-running migrations need usable metrics and the ability to retry failures.

The first step was deploying both the legacy routing table and the new Workers for Platforms hashed pipeline for every deployment, which allowed switching at any time. A feature flag controlled routing per site or per data center. The actual migration duplicated every deployment to the new pipelines rather than replacing the old setup — lower risk, with cleanup deferred, but A/B remained possible throughout.

After a few days, all 14 million deployments had been duplicated. Rollout to the new infrastructure then proceeded as a percentage-based release, allowing the team to catch issues before serving all Pages runtime traffic.

Side benefits beyond speed

The migrations' size highlighted another problem: those routing tables were expensive before they were even parsed.

  • Lower CPU usage. Removing the large JSON parse and thousands of regex matches saved CPU time across thousands of machines.
  • Higher LRU hit rate. Quicksilver-backed LRU caches were easily filled by just one or a few large routing tables. Now, with tiny single-entry JSONs, cache hit rates improved for all Workers.
  • Quicksilver storage reduction. Routing table storage dropped by 92% — about 12 GiB freed on each of hundreds of data centers.

Faster still to come

Pages now claims the top spot among comparable hosting platforms in independent page-load comparisons, with the foundation laid to go further. The team points to projects like Flame, aimed at reducing latency on every request, as the next step in making Pages even quicker.

For now, the win is architectural: Pages turned a data-dependent lookup tree into a cheap, constant-time hash. That removes a growth constraint that was beginning to punish the platform's most active users — and does it under the hood, without asking anyone to change how they deploy.