Cdnjs, Serving 9 Billion Daily Requests, Just Moved Entirely Onto Cloudflare's Own Platform!
Hey everyone, it's Shiichan! Today I've got a story about Cloudflare really eating its own dog food — kind of a "look what we built" flex.
Cloudflare BlogWhat was announced?
On the Cloudflare Blog, Cloudflare announced it has fully migrated cdnjs, an open-source CDN for JavaScript and CSS libraries, onto its own Developer Platform. cdnjs is used by roughly 12% of all websites and holds about a 48.3% share among JavaScript CDNs. It handles an average of 108,000 requests per second — about 9 billion requests a day — with a 98.6% cache hit rate, served from 330+ Cloudflare data centers.
The story so far
Before the migration, cdnjs ran on a system split across Google Cloud Platform and Cloudflare, with Cloud Functions, GCS events, Pub/Sub, a git-sync VM, and Workers KV scattered across the stack. That created some real headaches:
- Observability gap: pipeline stages had no shared correlation IDs, so partial failures — processing succeeding but the GitHub sync failing — could go unnoticed for weeks
- Split storage: files lived as "authoritative" in both Workers KV and the GitHub repo, with no clean way to reconcile the two
- Tight coupling via events: stages were chained together using storage events as message passing, with no dead-letter queues, backlog visibility, or replay
- Alphabet sharding: npm checks were split across 26 separate Cloud Functions, one per letter, each deployed and logged independently
- An unsustainable repo: the git repository had grown to 1.1TB, exceeding GitHub's archive generation limits and making forking or cloning impractical
What changes
All of that is now consolidated onto Cloudflare's Developer Platform:
- R2 is the authoritative file store, with no practical size limit — so large files like source maps, bundles, and font packs, which didn't fit in KV before, now have a home. An S3-compatible API exposes the catalog externally
- KV now holds only metadata — package info, version lists, SRI hashes — matching its strength for high-read, low-write workloads
- Workers Cache replaces a separate internal caching layer
- Workflows orchestrates the publishing pipeline
- Containers handle CPU-heavy compression work
- Durable Objects count child workflow completions
- Queues distribute migration work by package name with at-least-once delivery
- DigitalOcean Spaces serves as a disaster-recovery mirror and fallback
Six separate technology layers are gone, and so is the observability gap.
Dive Deep
The publishing pipeline runs across four Workflows:
PackageUpdatesWorkflow: checks npm and GitHub every 10 minutesDownloadPackageWorkflow: fetches tarballs into R2ProcessingWorkflow: extracts, minifies, and compresses each filePublishingWorkflow: writes results and updates the Algolia search index
The migration itself wasn't smooth sailing. An early attempt to regenerate every file from scratch failed because minifiers and compressors aren't fully deterministic across versions — the content was correct, but the SRI hashes changed. The team pivoted to copying existing content as-is from KV into R2, spreading the migration of millions of files across many Worker invocations via Queues to avoid exhausting the subrequest limit.
That process pushed Cloudflare to raise its own platform limits for Workers and Workflows:
- Subrequests per Worker invocation: 1,000 → up to 10 million on paid plans
- Workflow steps: 1,024 default → 10,000 default, configurable up to 25,000
That's not a cdnjs-only perk — it benefits every developer building on Workers and Workflows. The post also mentions Cloudflare is considering doing ES module transformation at publish time, using the same Workflows-plus-Containers pattern used for compression today, though nothing is committed yet.
Wrap-up
- cdnjs — 9 billion requests a day, 98.6% cache hit rate — is now fully migrated onto Cloudflare's own Developer Platform (R2, KV, Workers Cache, Workflows, Containers, Durable Objects, Queues)
- The old GCP-plus-Cloudflare split system's five pain points (observability, split storage, tight coupling, sharding, an oversized repo) are resolved
- SRI hash non-determinism during migration led Cloudflare to raise the Worker subrequest limit to 10 million and the Workflow step limit to 10,000 (up to 25,000)
- Those higher limits aren't just for cdnjs — every developer using Workers and Workflows benefits
If you're building large-scale delivery infrastructure or complex pipelines on Workers, or you're curious how Cloudflare dogfoods its own platform, this one's for you.