The Scale and Legacy Architecture of cdnjs
As of June 23, 2026, cdnjs runs entirely on Cloudflare’s Developer Platform. Serving roughly 12% of all websites and capturing a 48.3% share of the JavaScript CDN market, cdnjs handles an average of 108,000 requests per second—totaling 9 billion requests a day—across more than 330 Cloudflare data centers. Despite the rise of modern bundlers, Vite, and ES Modules, LLMs, tutorials, and legacy projects continue to drive immense traffic to its immutable, SRI-verified script tags.
In 2020, file serving was moved to Cloudflare Workers and KV, but the publishing pipeline—the ingestion, unpacking, and processing of new library versions—remained on Google Cloud Platform (GCP). This hybrid legacy architecture featured several distinct friction points:
- No shared trace: A single package update traversed Cloud Functions, GCS object events, Pub/Sub, a git-sync VM, and Workers KV without a common correlation ID.
- Split-brain storage: Files existed in both Workers KV and a massive GitHub repository that eventually crossed 1.1TB, leading to drift between the two stores.
- Gluing via object events: Storage buckets functioned as ad-hoc message queues without dead-letter queues or backlog visibility.
- Sharded complexity: Checking npm for updates required 26 separate Cloud Functions (one for each letter of the alphabet).
- GitHub limitations: The backing git repository grew so large that GitHub’s archive service refused to generate tarballs, burdened by a 274-entry .gitignore file.
Re-Architecting the Publishing Pipeline with Cloudflare Workflows
The new publishing pipeline leverages Cloudflare Workflows to achieve durable execution. Every ten minutes, a cron trigger initiates PackageUpdatesWorkflow, scanning npm and GitHub for new versions. When a new version is detected, it spawns a DownloadPackageWorkflow to pull the tarball directly into R2 object storage, followed by a ProcessingWorkflow for individual files.
Because Workflows maintain state across steps, network timeouts or temporary faults do not corrupt the pipeline. If a step fails, execution resumes cleanly from the last successful checkpoint without requiring manual intervention or complex state reconciliation.
Handling CPU-Intensive Tasks with Cloudflare Containers
While Workers execute fast HTTP logic efficiently, text-based asset compression (Brotli and gzip) demands heavy CPU resources that exceed standard Worker execution profiles. To solve this, the architecture orchestrates a hybrid approach using Cloudflare Containers:
- The uncompressed file is written to an intermediate R2 bucket.
- A message is pushed to a Cloudflare Queue, and the workflow hibernates.
- A Rust-based compression service running inside a Cloudflare Container picks up the job, performs the compression, and writes the output back to storage.
- An R2 event notification wakes the workflow up, allowing it to proceed to the publishing phase.
Managing Parallelism with Durable Objects
A single npm package update can contain thousands of individual files, requiring massive parallel execution across child workflows. To track completion without relying on external databases, the system utilizes a lightweight Durable Object as an atomic counter.
The parent workflow increments the counter as it spawns child processing tasks. As each child finishes its execution, it decrements the counter. Once the counter reaches zero, the Durable Object signals the parent workflow to wake up and move forward to the publishing stage.
Refining Storage Hierarchies: R2, KV, and DigitalOcean
The data storage layout has been restructured to match the strengths of each platform component:
- R2 Object Storage: Serves as the absolute single source of truth for all file content. Free from traditional size constraints, it securely houses large bundles, source maps, and font packs alongside standard scripts.
- Workers KV: Dedicated exclusively to lightweight metadata, including package info, version lists, and Subresource Integrity (SRI) hashes, optimized for high read volume.
- Workers Cache: Replaces custom intermediate caching layers, sitting directly in front of the Worker to accelerate global edge delivery.
- DigitalOcean Spaces: Acts as a live disaster-recovery mirror. The serving worker transparently falls back to DigitalOcean Spaces if R2 encounters availability issues.
Overcoming Platform Limits at Scale
Migrating millions of legacy files without breaking existing SRI hashes required copying historical data rather than regenerating files. During this massive backfill, the engineering team encountered strict platform thresholds:
- Worker Subrequests: Capped at 1,000 subrequests per invocation on paid plans, which was quickly burned through by packages containing thousands of files.
- Workflow Steps: Standard workflow step limits were tested by deep execution trees.
Rather than engineering brittle workarounds, the team collaborated with the Workers and Workflows product groups to raise these platform limits globally. Subrequest caps were increased up to 10 million per invocation, and workflow step limits were raised to a default of 10,000 (configurable up to 25,000)—benefits that are now available to all developers using Cloudflare’s platform.
Practical Implementation Takeaways
Migrating a monolithic open-source CDN to a serverless edge architecture highlights several best practices for enterprise-scale applications:
- Separate raw content storage (R2) from lookup metadata (KV) to optimize read and write performance profiles.
- Use Durable Objects for lightweight, real-time coordination of distributed asynchronous sub-tasks.
- Offload heavy compute workloads to specialized infrastructure like Cloudflare Containers while retaining orchestration control via Workflows.
- Identify hard platform bottlenecks early and engage platform engineering teams to adjust system limits rather than building complex sharding workarounds.
Frequently asked questions
What is cdnjs?
cdnjs is a free, open-source content delivery network for JavaScript and CSS libraries, used on roughly 12% of all websites to serve static assets via simple HTML script tags.
Why did cdnjs migrate away from Google Cloud Platform?
The previous GCP-backed pipeline suffered from split-brain storage synchronization issues, lack of shared tracing across 26 distinct functions, and a massive 1.1TB git repository that became unsustainable to maintain.
How are CPU-heavy tasks like compression handled in the new architecture?
Workflows place uncompressed assets into R2, queue the job, and hibernate while a Rust-based service running inside Cloudflare Containers processes the compression before waking the workflow via R2 event notifications.
What platform limits were adjusted during the migration?
Cloudflare raised Worker subrequests up to 10 million per invocation and increased default workflow steps to 10,000 (configurable up to 25,000) to support massive asset migrations.
Primary reference: Review the original announcement for exact release details. This article is an independent explanation and does not reproduce the source text.
