Article summary — original

Cloudflare Migrates Blog to EmDash CMS with Redesigned Interface and Worker Architecture Cloudflare transitioned its official blog to EmDash, an Astro- and Cloudflare-focused CMS, serving as 'Customer Zero' to validate the platform. The migration paired a modern architecture powered by Cloudflare Workers and multi-layer caching with a visual redesign, improved performance metrics, and native Model Context Protocol (MCP) integrations. Cloudflare migrated its blog to EmDash on August 12, acting as Customer Zero to surface bugs such as post-scheduling issues ahead of version 1.0. A multi-layered caching setup allows Cloudflare to serve 99.5% of static files and 70% of total requests directly from cache. Traffic routing was executed safely using a proxy Worker with service bindings and fallback handling, rolling out gradually from 1% to 100% in a single day. The new platform demonstrated flat p95 response latencies without the spikes seen on the legacy stack, handling loads up to 850 requests per second (RPS) and absorbing a 28,000 RPS DDoS attack. New MCP servers were launched for readers' AI agents to query blog content and for internal authors to manage posts via EmDash. Adopting EmDash as Customer Zero In line with Cloudflare's internal standard of acting as 'Customer Zero,' the engineering team shifted away from its prior CMS vendor to EmDash. Evaluating the pre-1.0 platform against standard workflows revealed initial gaps, most notably in scheduled post functionality, which was resolved in EmDash version 0.19.0 prior to launch. Architecture and Performance Engineering The Cloudflare Blog handles base traffic around 75 RPS with traffic spikes exceeding 5,000 RPS. Using the open-source k6 tool, Cloudflare tested varying load scenarios to design an architecture utilizing Cloudflare Workers and tiered caching layers. Under regular operation, the configuration serves 99.5% of static assets and 70% of overall requests from cache, significantly reducing database load. Visual Refresh and User Experience Updates Alongside backend changes, the frontend was rebuilt to align with Cloudflare's Kumo design system. Improvements include native light and dark mode toggles tied to system preferences, sidebars featuring a table of contents and social discussion links, and moving the email subscription form from the top right header to the end of posts to prevent users from mistaking it for a search bar. Zero-Downtime Migration and Latency Gains To guarantee zero downtime, a proxy Worker managed traffic distribution between the legacy and new sites using version cookies and automatic fallback rules for 500 errors. A NEW_BLOG service binding enabled direct worker-to-worker communication to avoid public network overhead. Traffic was transitioned incrementally from 1% to 100% across the day, with production metrics revealing flatter, lower p95 latency curves compared to the previous setup. AI Agent Support and Live Stress Testing The migration integrated Model Context Protocol (MCP) tooling, releasing a public MCP server for reader agents to search and retrieve posts, alongside EmDash's built-in MCP server for authoring. During Cloudflare's 'Agents Week,' the site served roughly 3 million pageviews across 28 posts in 9 days, safely handling frontend rates up to 450 RPS alongside an unrelated 28,000 RPS DDoS attack on August 10.

Article summary — zh

Cloudflare 博客迁移至基于 Astro 的 CMS EmDash:全流程与性能架构解析 Cloudflare 宣布其官方博客已正式迁移至专为 Astro 与 Cloudflare 构建的 CMS 平台 EmDash,同时完成了前端重新设计。作为内部的“零号客户”,Cloudflare 结合多层缓存与 Workers 架构,实现了更平稳的延迟表现与更高的性能,并新增了对 AI Agent 工具的支持。 Cloudflare 践行“零号客户”文化,将官方博客迁移至早期 CMS 平台 EmDash,协助发现并修复了定时发布等早期问题。 采用多层缓存策略,实现静态文件 99.5% 和请求 70% 的缓存命中率,使高负载下的 p95 响应延迟保持平稳,并成功防御 28,000 RPS 的 DDoS 攻击。 基于 Kumo 设计系统重构前端,加入深色模式支持,优化了邮件订阅位置并新增目录与社交讨论侧边栏。 迁移采用代理 Worker 与 service binding 实现基于 Cookie 的灰度路由与快速回退,保障零停机上线。 架构验证与高并发性能 面对常规 75 RPS 到突发超 5,000 RPS 的流量波动,团队使用 k6 进行了严苛的性能测试。最终生产架构利用多层缓存机制,将 99.5% 的静态文件和 70% 的请求直接由缓存响应,大幅减轻数据库压力。在运行至 850 RPS 期间,系统的 p95 延迟曲线较旧平台更平稳,并在 Agents Week 期间平稳支撑了近 300 万次页面浏览及高达 28,000 RPS 的 DDoS 攻击。 前端体验与平滑迁移机制 结合 Kumo 设计系统,博客重构了界面并正式上线原生深浅色主题切换。原先易被误认为搜索框的右上角邮件订阅框被移至文末,文章页新增了目录导航和社区讨论栏。迁移上线阶段,团队部署了一个代理 Worker,通过服务绑定(service binding)直连新博客 Worker,利用 Cookie 实现从 1%、5%、15% 到 100% 的平滑灰度发布,并在检测到 500 错误时自动回退至旧版,确保零停机时间。 集成面向 Agent 的 MCP 服务 迁移后博客增强了对 AI Agent 的支持。团队发布了针对博客的 MCP 服务器,提供 search_posts、list_posts、get_post 和 list_tags 等工具接口;同时 EmDash 本身也免费内置了供作者使用的 MCP 服务,允许通过 Agent 完成内容浏览、创建、排期发布和文件清理等管理操作。

Saved original article

You likely noticed the recent redesign of the Cloudflare Blog. We added dark mode, modernized the look and feel, and made a lot of other small improvements along the way. What you might not have noticed – well, except for those who are [more terminally online](https://x.com/CherryJimbo/status/2077475003386220610) – is that the redesign was part of a much bigger migration project. On Wednesday, August 12, we moved the blog to [EmDash](https://blog.cloudflare.com/emdash-wordpress/), a content management system (CMS) built especially to work on Astro and with Cloudflare. We’ll take you into the migration story – what we learned and how EmDash got better – as well as into the benefits we’re already seeing from a new platform. At Cloudflare, Cloudflare itself is Customer Zero. This means that we use our products. And – in use – we make them better for ourselves and our customers. This is a very real cultural value at Cloudflare. The burden of proof is on you if you want to use an external vendor. Why can’t that team support you, what gaps are there, why can’t those gaps be filled, and are those “gaps” true requirements? This preference is even enshrined in our internal engineering standards, known as our Codex. *We don’t just build products for others; we build them to run Cloudflare itself. We are our own first, most demanding customer.* *We validate scale, security, and usability on our own massive infrastructure before a paying customer ever touches the product. If a product breaks, it breaks us first. This forces us to fix issues immediately, ensuring that by the time a feature reaches the enterprise, it has already survived the harshest production environment on earth.* With the launch of EmDash and some limitations with our current CMS vendor, we knew that we’d likely be the Customer Zero for EmDash internally at Cloudflare. When we began our initial migration conversations, we started with two main questions: Our first question was the most broad, **does EmDash work for us**? This is something you’d want to know broadly about any new platform, but especially one that’s pre-1.0. To answer this question, we ran through a bunch of common user flows, such as: By and large, EmDash held up pretty well to these usability tests. The gaps we found were generally related to: The biggest oversight we found was around [scheduled posts](https://github.com/emdash-cms/emdash/pull/1312), which didn’t work until EmDash version 0.19.0. This gap was understandable given the early version of EmDash, but it was also definitely something we didn’t want to be finding out *after* the scheduled time for a post. Our biggest concerns were whether our proposed EmDash setup could handle the traffic we saw on the Cloudflare Blog. The traffic pattern to our blog is incredibly varied. Normal load sits in the neighborhood of 75 requests per second (RPS), but also spikes up to over 5,000 RPS. Some of these spikes line up with the publishing times of new posts, meaning those posts went viral and attracted a lot of attention. Others happen during all points of the day and night, which likely means folks are sending some [extra traffic](https://www.cloudflare.com/learning/ddos/what-is-a-ddos-attack/) our way, just to see what happens. Performance also matters for our systems (and our readers). Cloudflare is a web performance company, after all, so the speed at which a page loads becomes incredibly important. With those two concerns in mind, we built out some scenarios using [k6](https://grafana.com/docs/k6/latest/), an open-source performance testing tool: For each of those scenarios, we evaluated: Armed with these tests – and a lot of internal discussion and data points – we came to our production architecture: The multiple layers of caching we put in place play a key role in making the blog both fast and resilient. In the diagram below, they are ordered from top to bottom by proximity to the user: With this setup, we’re typically serving 99.5% of static files from a cache and 70% of requests from a cache, improving frontend performance and decreasing load on the database. Once we had that architecture in place, we could start thinking about the frontend redesign as well. Beyond updating the backend architecture, the migration offered us the perfect opportunity to bring the blog's interface into alignment with Cloudflare’s updated visual language. We rebuilt the frontend experience using patterns established by the [Kumo design system](https://kumo-ui.com/), creating visual and structural consistency between the Cloudflare homepage, dashboard, and marketing sites. The result is a cohesive reading experience that feels like a natural extension of the broader Cloudflare ecosystem. A major priority for this redesign, and a long-overdue request from our readers, was native support for light and dark modes. We implemented theme switching tied directly to system preferences, alongside an explicit toggle, and ensured that accessibility guidelines were strictly met across both themes. Regardless of preference, the updated palette and code syntax highlighting adapt seamlessly without sacrificing legibility. We also took the opportunity to solve a few long-standing user experience quirks, starting with our email subscription form. Previously, the subscription box lived in the top right corner of the page. Because of its placement, readers frequently mistook it for a search bar and typed their search queries directly into the input field. To fix this, we moved the email sign-up into a dedicated call-to-action block at the bottom of posts. Now, once a reader finishes an article and wants to stay updated, the prompt to subscribe appears naturally at the end of a post. Finally, we introduced two dedicated sidebar features on interior post pages to improve navigation and community engagement. On the right, an "On this page" table of contents tracks your progress and lets you jump directly to specific sections of longer technical posts. On the left, a new "Discuss Online" section makes it effortless to share articles and engage in conversations across social platforms and developer communities. As we got nearer to our migration, we started focusing on the broader question of “how do we make this change safely?” Ensuring zero downtime for our readers was a non-negotiable requirement, alongside guaranteeing a seamless fallback mechanism if something went wrong at the last minute. To achieve this, we deployed a proxy Worker to intelligently route traffic between the legacy blog and the new EmDash-powered site. This Worker set a version cookie on requests, which then let us route incoming traffic to the new or legacy experience accordingly. Additionally, this strategy allowed us to fall back to the legacy blog if the new site experienced any 500 errors. Thanks to the flexibility of Cloudflare Workers, this proxy was relatively simple to create and scaled without any issues. The ability to configure a direct worker-to-worker connection through the NEW\_BLOG service binding was particularly useful here, as it reduced latency for any end user going through the proxy. This service binding let the proxy Worker dispatch incoming requests directly to the new blog Worker instead of sending them through a public hostname, DNS, TLS, and an outbound HTTP connection. On launch day, we initiated a gradual rollout, starting at just 1% of total traffic, then incrementally stepping up to 5%, 15%, and beyond as we validated system health. This phased approach allowed us to observe how the platform handled real-world production load while catching a few last-minute edge cases without impacting the vast majority of our audience. By the end of the day, we had comfortably shifted 100% of traffic over to the new platform. One of our primary objectives for this migration was to deliver a faster, more reliable site to our readers, and the early data shows we accomplished exactly that. Comparing p95 response latencies between the old architecture (green line) and the new EmDash setup (yellow line) revealed a stark difference. Where the previous platform experienced periodic latency spikes under load, the new system maintains a remarkably flat, consistent response profile. By running EmDash on Cloudflare Workers alongside our new caching layers, we’ve delivered a significantly faster and more performant reading experience across the board. We’ve seen all these performance gains – and minimal errors – while serving up to 850 RPS. With this change, the blog also got more accessible for agents, in two distinct ways. The first is that we released a new Model Context Protocol (MCP) server for the [Cloudflare Blog](https://github.com/cloudflare/mcp-server-cloudflare/tree/main/apps/cloudflare-blog). An MCP server bundles up a bunch of specific tools that your agent can then use to interact with an external resource, almost like an API for agents. Using that MCP, you can now use the following tools with your agents: `search_posts``list_posts``get_post``list_tags` With the new, intuitive EmDash APIs and AI search endpoints exposed by our Worker, creating this new MCP took just a few hours of work. The second is that – for our blog authors – EmDash has an [MCP server](https://docs.emdashcms.com/guides/ai-tools/#the-mcp-server) for EmDash itself, meaning that they can browse, create, and edit content, publish and schedule posts, remove files, and more. Though this sort of agentic tooling is becoming more standardized in the CMS industry, what’s not standard is that it’s available *without any additional cost*. The MCP is just another part of the platform, reflecting a growing trend of [designing for agents](https://blog.cloudflare.com/markdown-for-agents/), as well as humans. At Cloudflare, we run multiple innovation “weeks” a year, where we set ambitious goals for internal teams around specific themes. These weeks push our products forward, as well as help customers digest the changes that are constantly happening at Cloudflare. The latest of these, [Agents Week](https://blog.cloudflare.com/tag/agents-week/), was quite a test for the new blog. We launched 28 new posts over 9 days. And those posts got a lot of traffic, close to 3 million pageviews. On the frontend, our new blog Worker did very well, serving up to 450 RPS without any noticeable issues. Thanks to Cloudflare’s [built-in DDoS protection](https://blog.cloudflare.com/500-tbps-of-capacity/), we also absorbed a 28,000 RPS DDoS attack on August 10th, also without any noticeable issues. On the editing side, we continued to find some issues. Most of these involved [small quirks](https://github.com/emdash-cms/emdash/issues/2336) of the editing experience, though we also found some bugs specifically around [scheduled](https://github.com/emdash-cms/emdash/issues/2343) [posts](https://github.com/emdash-cms/emdash/issues/2335). We’ve since raised these to the EmDash team and are confident that they’ll be fixed before Birthday Week. We want to give a heartfelt thank you to the EmDash team, who made this migration about as smooth as possible and were incredibly receptive to our feedback. This is how Customer Zero is supposed to work, and it’s incredibly gratifying to share an inside look into that process with all of our readers as well. If you’re in the market for a new CMS, try out [EmDash](https://www.emdashcms.com/) today. It’s pretty amazing and – with the upcoming [launch to v1](https://github.com/emdash-cms/emdash/milestone/1) – it’ll be getting even better soon.