Inside Cloudflare’s own migration to EmDash

The recent Cloudflare Blog redesign brought dark mode, a refreshed look, and a handful of subtle usability fixes. But behind those visible changes was a larger project: moving the blog to EmDash, a CMS purpose-built for Astro and Cloudflare. The migration served as a real-world stress test for EmDash, with Cloudflare acting as its own first customer.

The “Customer Zero” mandate

Cloudflare’s engineering culture prioritizes internal dogfooding. The company’s internal standards, called Codex, state that products must be robust enough to run Cloudflare itself before reaching paying customers. When EmDash launched and the existing CMS vendor showed limitations, the blog became the proving ground.

Initial migration conversations centered on two questions: Does EmDash work for our workflows, and can it handle our scale?

Evaluating usability

Testing began with common editorial flows: publishing and unpublishing posts, authoring content, scheduling, and adding media. EmDash largely passed these checks, though gaps surfaced in areas tied to the blog’s size and complexity:

  • Media handling, content entity search, and bylines at scale
  • Localization, SEO, and Content Security Policy (CSP) nuances
  • Admin editor usability, including finding custom HTML blocks, in-entity editing bugs, and keeping the formatting toolbar visible in long posts

The most significant finding was that scheduled posts didn’t work until EmDash version 0.19.0. For an early-stage platform this was understandable, but it was not something the team wanted to discover after a post missed its scheduled time.

Stress testing for scale

The blog’s traffic pattern is highly variable, sitting around 75 requests per second (RPS) at baseline but spiking above 5,000 RPS during viral posts or attacks. Using k6, the team built three load scenarios to probe limits:

  • Ramp: Gradually increase requests to triple the production baseline, then cool down
  • Breakpoint: Ramp from 0 to 100 RPS over 10 minutes until something breaks
  • Burst: Throw an immediate load of 7,000 RPS and observe

Success criteria were strict: failure if more than 0.01% of requests returned 5xx errors, if P95 latency exceeded 500ms for more than 5% of responses, or if P99 latency exceeded 1000ms for more than 1% of responses.

These tests led to the production architecture:

  • EmDash running on a Cloudflare Worker
  • Served behind Workers Cache, which Cloudflare believes is a first for a major site
  • A new EmDash object cache on Workers KV, built specifically for this use case
  • Cloudflare’s first-party Hyperdrive integration with PlanetScale

Multiple caching layers are ordered by proximity to the user. In practice, the setup serves 99.5% of static files and 70% of requests from cache, improving frontend performance and reducing database load.

Frontend refresh

The backend migration also created an opportunity to align the blog with Cloudflare’s current visual language. The frontend was rebuilt using the Kumo design system, making the blog visually and structurally consistent with Cloudflare’s homepage, dashboard, and marketing sites.

A long-requested addition was native light and dark mode support. Theme switching follows system preferences and includes an explicit toggle. Both themes meet accessibility guidelines, and code syntax highlighting adapts without losing legibility.

The redesign also fixed a persistent UX issue: the email subscription form previously sat in the page’s top right corner, where readers frequently mistook it for a search bar. The sign-up now lives in a dedicated call-to-action block at the bottom of posts, appearing naturally after readers finish an article.

Interior post pages gained two sidebar features. On the right, an “On this page” table of contents tracks progress and links to specific sections. On the left, a “Discuss Online” section makes it easy to share articles across social platforms and developer communities.

A gradual, reversible rollout

The migration plan required zero downtime and a clean fallback if anything went wrong. A proxy Worker routed traffic between the legacy blog and the new EmDash site by setting a version cookie on requests. If the new site returned any 500 errors, the proxy fell back to the legacy experience.

A key detail: the proxy Worker connected directly to the new blog Worker through a service binding, avoiding a public hostname, DNS, TLS, and outbound HTTP connection. This reduced latency for end users going through the proxy.

On launch day, traffic shifted gradually — starting at 1%, then stepping up to 5%, 15%, and beyond as system health was validated. The phased approach let the team observe real-world load and catch edge cases without affecting most readers. By day’s end, 100% of traffic was on the new platform.

Performance and agent-readiness

Measured gains

Comparing p95 response latencies between the old and new architectures shows a stark difference. The previous platform had periodic latency spikes under load; the EmDash setup maintains a flat, consistent response profile. These gains come with minimal errors while serving up to 850 RPS.

Built for agents

The migration also made the blog more accessible to AI agents in two ways. First, Cloudflare released a Model Context Protocol (MCP) server for the Cloudflare Blog, exposing tools such as search_posts, list_posts, get_post, and list_tags. The EmDash APIs and AI search endpoints behind the Worker made building this MCP a matter of hours.

Second, EmDash itself ships an MCP server for blog authors, allowing them to browse, create, edit, publish, schedule, and remove content through agentic tooling. Unlike growing CMS industry trends, this MCP comes at no additional cost — it’s part of the platform itself, reflecting a broader shift toward designing for both agents and humans.

Agents Week: a live-fire test

The first major workload for the new platform arrived during Cloudflare’s Agents Week, a nine-day stretch that saw 28 posts published. That content drew close to 3 million pageviews. The blog Worker handled the frontend load without issue, serving up to 450 RPS. A 28,000 RPS DDoS attack on August 10th was absorbed by Cloudflare’s built-in DDoS protection, also without any visible degradation.

Editorial rough edges

The editing side of the system surfaced more problems than the serving side. Most were minor quirks in the editing experience, but several bugs were specific to scheduled posts. These issues have been reported to the EmDash team and fixes are expected before Birthday Week.

Customer Zero, in practice

The cloudflare.com migration put EmDash through its paces as Customer Zero. The team was receptive to feedback, and the process went about as smoothly as a first major deployment could. For those evaluating CMS options, EmDash is available now and is nearing its v1 milestone.