
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
    <channel>
        <title><![CDATA[ The Cloudflare Blog ]]></title>
        <description><![CDATA[ Get the latest news on how products at Cloudflare are built, technologies used, and join the teams helping to build a better Internet. ]]></description>
        <link>https://blog.cloudflare.com</link>
        <atom:link href="https://blog.cloudflare.com/" rel="self" type="application/rss+xml"/>
        <language>en-us</language>
        <image>
            <url>https://blog.cloudflare.com/favicon.png</url>
            <title>The Cloudflare Blog</title>
            <link>https://blog.cloudflare.com</link>
        </image>
        <lastBuildDate>Tue, 05 May 2026 17:41:34 GMT</lastBuildDate>
        <item>
            <title><![CDATA[The AI engineering stack we built internally — on the platform we ship]]></title>
            <link>https://blog.cloudflare.com/internal-ai-engineering-stack/</link>
            <pubDate>Mon, 20 Apr 2026 13:00:00 GMT</pubDate>
            <description><![CDATA[ We built our internal AI engineering stack on the same products we ship. That means 20 million requests routed through AI Gateway, 241 billion tokens processed, and inference running on Workers AI, serving more than 3,683 internal users. Here's how we did it.
 ]]></description>
            <content:encoded><![CDATA[ <p></p><p>In the last 30 days, 93% of Cloudflare’s R&amp;D organization used AI coding tools powered by infrastructure we built on our own platform.</p><p>Eleven months ago, we undertook a major project: to truly integrate AI into our engineering stack. We needed to build the internal MCP servers, access layer, and AI tooling necessary for agents to be useful at Cloudflare. We pulled together engineers from across the company to form a tiger team called iMARS (Internal MCP Agent/Server Rollout Squad). The sustained work landed with the Dev Productivity team, who also own much of our internal tooling including CI/CD, build systems, and automation.</p><p>Here are some numbers that capture our own agentic AI use over the last 30 days:</p><ul><li><p><b>3,683 internal users</b> actively using AI coding tools (60% company-wide, 93% across R&amp;D), out of approximately 6,100 total employees</p></li><li><p><b>47.95 million</b> AI requests </p></li><li><p><b>295 teams</b> are currently utilizing agentic AI tools and coding assistants.</p></li><li><p><b>20.18 million</b> AI Gateway requests per month</p></li><li><p><b>241.37 billion</b> tokens routed through AI Gateway</p></li><li><p><b>51.83 billion</b> tokens processed on Workers AI</p></li></ul><p>The impact on developer velocity internally is clear: we’ve never seen a quarter-to-quarter increase in merge requests to this degree.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3lMKwBTT3m7DDmS4BnoNhB/9002104b9c6c09cf72f4052d71e22363/BLOG-3270_2.png" />
          </figure><p>As AI tooling adoption has grown the 4-week rolling average has climbed from ~5,600/week to over 8,700. The week of March 23 hit 10,952, nearly double the Q4 baseline.</p><p>MCP servers were the starting point, but the team quickly realized we needed to go further: rethink how standards are codified, how code gets reviewed, how engineers onboard, and how changes propagate across thousands of repos.</p><p>This post dives deep into what that looked like over the past eleven months and where we ended up. We're publishing now, to close out Agents Week, because the AI engineering stack we built internally runs on the same products we’re shipping and enhancing this week.</p>
    <div>
      <h2>The architecture at a glance</h2>
      <a href="#the-architecture-at-a-glance">
        
      </a>
    </div>
    <p>The engineer-facing tools layer (<a href="https://opencode.ai/"><u>OpenCode</u></a>, Windsurf, and other MCP-compatible clients) include both open-source and third-party coding assistant tools.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2oZJhdVNbW05lJaSnN3hds/21c5427f275ba908388333884530f455/image8.png" />
          </figure><p>Each layer maps to a Cloudflare product or tool we use:</p><table><tr><th><p>What we built</p></th><th><p>Built with</p></th></tr><tr><td><p>Zero Trust authentication</p></td><td><p><a href="https://developers.cloudflare.com/cloudflare-one/"><b><u>Cloudflare Access</u></b></a></p></td></tr><tr><td><p>Centralized LLM routing, cost tracking, BYOK, and Zero Data Retention controls</p></td><td><p><a href="https://developers.cloudflare.com/ai-gateway/"><b><u>AI Gateway</u></b></a></p></td></tr><tr><td><p>On-platform inference with open-weight models</p></td><td><p><a href="https://developers.cloudflare.com/workers-ai/"><b><u>Workers AI</u></b></a></p></td></tr><tr><td><p>MCP Server Portal with single OAuth</p></td><td><p><a href="https://developers.cloudflare.com/workers/"><b><u>Workers</u></b></a> + <a href="https://developers.cloudflare.com/cloudflare-one/"><b><u>Access</u></b></a></p></td></tr><tr><td><p>AI Code Reviewer CI integration</p></td><td><p><a href="https://developers.cloudflare.com/workers/"><b><u>Workers</u></b></a> + <a href="https://developers.cloudflare.com/ai-gateway/"><b><u>AI Gateway</u></b></a></p></td></tr><tr><td><p>Sandboxed execution for agent-generated code (Code Mode)</p></td><td><p><a href="https://blog.cloudflare.com/dynamic-workers/"><b><u>Dynamic Workers</u></b></a></p></td></tr><tr><td><p>Stateful, long-running agent sessions</p></td><td><p><a href="https://developers.cloudflare.com/agents/"><b><u>Agents SDK</u></b></a> (McpAgent, Durable Objects)</p></td></tr><tr><td><p>Isolated environments for cloning, building, and testing</p></td><td><p><a href="https://developers.cloudflare.com/sandbox/"><b><u>Sandbox SDK</u></b></a> — GA as of Agents Week</p></td></tr><tr><td><p>Durable multi-step workflows</p></td><td><p><a href="https://developers.cloudflare.com/workflows/"><b><u>Workflows</u></b></a> — scaled 10x during Agents Week</p></td></tr><tr><td><p>16K+ entity knowledge graph</p></td><td><p><a href="https://backstage.io/"><b><u>Backstage</u></b></a> (OSS)</p></td></tr></table><p>None of this is internal-only infrastructure. Everything (besides Backstage) listed above is a shipping product, and many of them got substantial updates during Agents Week.</p><p>We’ll walk through this in three acts:</p><ol><li><p><b>The platform layer</b> — how authentication, routing, and inference work (AI Gateway, Workers AI, MCP Portal, Code Mode)</p></li><li><p><b>The knowledge layer</b> — how agents understand our systems (Backstage, AGENTS.md)</p></li><li><p><b>The enforcement layer</b> — how we keep quality high at scale (AI Code Reviewer, Engineering Codex)</p></li></ol>
    <div>
      <h2>Act 1: The platform layer</h2>
      <a href="#act-1-the-platform-layer">
        
      </a>
    </div>
    
    <div>
      <h3>How AI Gateway helped us stay secure and improve the developer experience</h3>
      <a href="#how-ai-gateway-helped-us-stay-secure-and-improve-the-developer-experience">
        
      </a>
    </div>
    <p>When you have over 3,600+ internal users using AI coding tools daily, you need to solve for access and visibility across many clients, use cases, and roles.</p><p>Everything starts with <a href="https://developers.cloudflare.com/cloudflare-one/"><b><u>Cloudflare Access</u></b></a>, which handles all authentication and zero-trust policy enforcement. Once authenticated, every LLM request routes through <a href="https://developers.cloudflare.com/ai-gateway/"><b><u>AI Gateway</u></b></a>. This gives us a single place to manage provider keys, cost tracking, and data retention policies.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5zorZ21OXIbNg7VACGzwZX/e1b35951622bab6ae7ca9fa9b8a5c844/BLOG-3270_4.png" />
          </figure><p><sup><i>The OpenCode AI Gateway overview: 688.46k requests per day, 10.57B tokens per day, routing to four providers through one endpoint.</i></sup></p><p>AI Gateway analytics show how monthly usage is distributed across model providers. Over the last month, internal request volume broke down as follows.</p><table><tr><th><p>Provider</p></th><th><p>Requests/month</p></th><th><p>Share</p></th></tr><tr><td><p>Frontier Labs (OpenAI, Anthropic, Google)</p></td><td><p>13.38M</p></td><td><p>91.16%</p></td></tr><tr><td><p>Workers AI</p></td><td><p>1.3M</p></td><td><p>8.84%</p></td></tr></table><p>Frontier models handle the bulk of complex agentic coding work for now, but Workers AI is already a significant part of the mix and handles an increasing share of our agentic engineering workloads.</p>
    <div>
      <h4>How we increasingly leverage Workers AI</h4>
      <a href="#how-we-increasingly-leverage-workers-ai">
        
      </a>
    </div>
    <p><a href="https://developers.cloudflare.com/workers-ai/"><b><u>Workers AI</u></b></a> is Cloudflare's serverless AI inference platform which runs open-source models on GPUs across our global network. Beyond huge cost improvements compared to frontier models, a key advantage is that inference stays on the same network as your Workers, Durable Objects, and storage. No cross-cloud hops to deal with, which cause more latency, network flakiness, and additional networking configuration to manage.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2WFqiZSL1RGbD2O7gOPDfR/2edc8c69fdea89fef76e600cb3ee5384/BLOG-3270_5.png" />
          </figure><p><sup><i>Workers AI usage in the last month: 51.47B input tokens, 361.12M output tokens.</i></sup></p><p><a href="https://blog.cloudflare.com/workers-ai-large-models/"><b><u>Kimi K2.5</u></b></a>, launched on Workers AI in March 2026, is a frontier-scale open-source model with a 256k context window, tool calling, and structured outputs. As we described in our <a href="https://blog.cloudflare.com/workers-ai-large-models/"><u>Kimi K2.5 launch post</u></a>, we have a security agent that processes over 7 billion tokens per day on Kimi. That would cost an estimated $2.4M per year on a mid-tier proprietary model. But on Workers AI, it's 77% cheaper.</p><p>Beyond security, we use Workers AI for documentation review in our CI pipeline, for generating AGENTS.md context files across thousands of repositories, and for lightweight inference tasks where same-network latency matters more than peak model capability.</p><p>As open-source models continue to improve, we expect Workers AI to handle a growing share of our internal workloads. </p><p>One thing we got right early: routing through a single proxy Worker from day one. We could have had clients connect directly to AI Gateway, which would have been simpler to set up initially. But centralizing through a Worker meant we could add per-user attribution, model catalog management, and permission enforcement later without touching any client configs. Every feature described in the bootstrap section below exists because we had that single choke point. The proxy pattern gives you a control plane that direct connections don't, and if we plug in additional coding assistant tools later, the same Worker and discovery endpoint will handle them.</p>
    <div>
      <h4>How it works: one URL to configure everything</h4>
      <a href="#how-it-works-one-url-to-configure-everything">
        
      </a>
    </div>
    <p>The entire setup starts with one command:</p>
            <pre><code>opencode auth login https://opencode.internal.domain
</code></pre>
            <p>That command triggers a chain that configures providers, models, MCP servers, agents, commands, and permissions, without the user touching a config file.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3sK7wVF3QbeNJ0rjLBabXh/05b9098197b7a3d084e6d860ed22b169/BLOG-3270_6.png" />
          </figure><p><b>Step 1: Discover auth requirements.</b> OpenCode fetches <a href="https://opencode.ai/docs/config/"><u>config</u></a> from a URL like <code>https://opencode.internal.domain/.well-known/opencode</code>. </p><p>This discovery endpoint is served by a Worker and the response has an <code>auth</code> block telling OpenCode how to authenticate, along with a <code>config</code> block with providers, MCP servers, agents, commands, and default permissions:</p>
            <pre><code>{
  "auth": {
    "command": ["cloudflared", "access", "login", "..."],
    "env": "TOKEN"
  },
  "config": {
    "provider": { "..." },
    "mcp": { "..." },
    "agent": { "..." },
    "command": { "..." },
    "permission": { "..." }
  }
}
</code></pre>
            <p><b>Step 2: Authenticate via Cloudflare Access.</b> OpenCode runs the auth command and the user authenticates through the same SSO they use for everything else at Cloudflare. <code>cloudflared</code> returns a signed JWT. OpenCode stores it locally and automatically attaches it to every subsequent provider request.</p><p><b>Step 3: Config is merged into OpenCode.</b> The config provided is shared defaults for the entire organization, but local configs always take priority. Users can override the default model, add their own agents, or adjust project and user scoped permissions without affecting anyone else.</p><p><b>Inside the proxy Worker.</b> The Worker is a simple Hono app that does three things:</p><ol><li><p><b>Serves the shared config.</b> The config is compiled at deploy time from structured source files and contains placeholder values like {baseURL} for the Worker's origin. At request time, the Worker replaces these, so all provider requests route through the Worker rather than directly to model providers. Each provider gets a path prefix (<code>/anthropic, /openai, /google-ai-studio/v1beta, /compat</code> for Workers AI) that the Worker forwards to the corresponding AI Gateway route.</p></li><li><p><b>Proxies requests to AI Gateway.</b> When OpenCode sends a request like <code>POST /anthropic/v1/messages</code>, the Worker validates the Cloudflare Access JWT, then rewrites headers before forwarding:
</p>
            <pre><code>Stripped:   authorization, cf-access-token, host
Added:      cf-aig-authorization: Bearer &lt;API_KEY&gt;
            cf-aig-metadata: {"userId": "&lt;anonymous-uuid&gt;"}
</code></pre>
            <p>The request goes to AI Gateway, which routes it to the appropriate provider. The response passes straight through with zero buffering. The <code>apiKey</code> field in the client config is empty because the Worker injects the real key server-side. No API keys exist on user machines.</p></li><li><p><b>Keeps the model catalog fresh.</b> An hourly cron trigger fetches the current OpenAI model list from <code>models.dev</code>, caches it in Workers KV, and injects <code>store: false</code> on every model for Zero Data Retention. New models get ZDR automatically without a config redeploy.</p></li></ol><p><b>Anonymous user tracking.</b> After JWT validation, the Worker maps the user's email to a UUID using D1 for persistent storage and KV as a read cache. AI Gateway only ever sees the anonymous UUID in <code>cf-aig-metadata</code>, never the email. This gives us per-user cost tracking and usage analytics without exposing identities to model providers or Gateway logs.</p><p><b>Config-as-code. </b>Agents and commands are authored as markdown files with YAML frontmatter. A build script compiles them into a single JSON config validated against the OpenCode JSON schema. Every new session picks up the latest version automatically.</p><p>The overall architecture is simple and easy for anyone to deploy with our developer platform: a proxy Worker, Cloudflare Access, AI Gateway, and a client-accessible discovery endpoint that configures everything automatically. Users run one command and they're done. There’s nothing for them to configure manually, no API keys on laptops or MCP server connections to manually set up. Making changes to our agentic tools and updating what 3,000+ people get in their coding environment is just a <code>wrangler deploy</code> away.</p>
    <div>
      <h3>The MCP Server Portal: one OAuth, multiple MCP tools</h3>
      <a href="#the-mcp-server-portal-one-oauth-multiple-mcp-tools">
        
      </a>
    </div>
    <p>We described our full approach to governing MCP at enterprise scale in a <a href="https://blog.cloudflare.com/enterprise-mcp/"><u>separate post</u></a>, including how we use <a href="https://developers.cloudflare.com/cloudflare-one/access-controls/ai-controls/mcp-portals/"><u>MCP Server Portals</u></a>, Cloudflare Access, and Code Mode together. Here's the short version of what we built internally.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/36gUHwTs8CzZeS03l9yno1/42953a6dc2ac944f4dbe31e3ae51570e/BLOG-3270_7.png" />
          </figure><p>Our internal portal aggregates 13 production MCP servers exposing 182+ tools across Backstage, GitLab, Jira, Sentry, Elasticsearch, Prometheus, Google Workspace, our internal Release Manager, and more. This unifies access and simplifies everything giving us one endpoint and one Cloudflare Access flow governing access to every tool.</p><p>Each MCP server is built on the same foundation: McpAgent from the Agents SDK, <a href="https://github.com/cloudflare/workers-oauth-provider"><b><u>workers-oauth-provider</u></b></a> for OAuth, and Cloudflare Access for identity. The whole thing lives in a single monorepo with shared auth infrastructure, Bazel builds, CI/CD pipelines, and <code>catalog-info.yaml </code>for Backstage registration. Adding a new server is mostly copying an existing one and changing the API it wraps. For more on how this works and the security architecture behind it, see <a href="https://blog.cloudflare.com/enterprise-mcp/"><u>our enterprise MCP reference architecture</u></a>.</p>
    <div>
      <h3>Code Mode at the portal layer</h3>
      <a href="#code-mode-at-the-portal-layer">
        
      </a>
    </div>
    <p>MCP is the right protocol for connecting AI agents to tools, but it has a practical problem: every tool definition consumes context window tokens before the model even starts working. As the number of MCP servers and tools grows, so does the token overhead, and at scale, this becomes a real cost. <a href="https://blog.cloudflare.com/code-mode/"><u>Code Mode </u></a>is the emerging fix: instead of loading every tool schema up front, the model discovers and calls tools through code.</p><p>Our GitLab MCP server originally exposed 34 individual tools (<code>get_merge_request</code>, <code>list_pipelines</code>, <code>get_file_content</code>, and so on). Those 34 tool schemas consumed roughly 15,000 tokens of context window per request. On a 200K context window, that's 7.5% of the budget gone before asking a question. Multiplied across every request, every engineer, every day, it adds up.</p><p>MCP Server Portals now support Code Mode proxying, which lets us solve that problem centrally instead of one server at a time. Rather than exposing every upstream tool definition to the client, the portal collapses them into two portal-level tools: <code>portal_codemode_search and portal_codemode_execute</code>.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7jQa4HPmrOaOhUojZCJQ8q/4e81201065a50dd67c07e257b725e8b8/BLOG-3270_8.png" />
          </figure><p>The nice thing about doing this at the portal layer is that it scales cleanly. Without Code Mode, every new MCP server adds more schema overhead to every request. With portal-level Code Mode, the client still only sees two tools even as we connect more servers behind the portal. That means less context bloat, lower token cost, and a cleaner architecture overall.</p>
    <div>
      <h2>Act 2: The knowledge layer</h2>
      <a href="#act-2-the-knowledge-layer">
        
      </a>
    </div>
    
    <div>
      <h3>Backstage: the knowledge graph underneath all of it</h3>
      <a href="#backstage-the-knowledge-graph-underneath-all-of-it">
        
      </a>
    </div>
    <p>Before the iMARS team could build MCP servers that were actually useful, we needed to solve a more fundamental problem: structured data about our services and infrastructure. We need our agents to understand context outside the code base, like who owns what, how services depend on each other, where the documentation lives, and what databases a service talks to.</p><p>We run <a href="https://backstage.io/"><u>Backstage</u></a>, the open-source internal developer portal originally built by Spotify, as our service catalog. It's self-hosted (not on Cloudflare products, for the record) and it tracks things like:</p><ul><li><p>2,055 services, 167 libraries, and 122 packages</p></li><li><p>228 APIs with schema definitions</p></li><li><p>544 systems (products) across 45 domains</p></li><li><p>1,302 databases, 277 ClickHouse tables, 173 clusters</p></li><li><p>375 teams and 6,389 users with ownership mappings</p></li><li><p>Dependency graphs connecting services to the databases, Kafka topics, and cloud resources they rely on</p></li></ul><p>Our Backstage MCP server (13 tools) is available through our MCP Portal, and an agent can look up who owns a service, check what it depends on, find related API specs, and pull Tech Insights scores, all without leaving the coding session.</p><p>Without this structured data, agents are working blind. They can read the code in front of them, but they can't see the system around it. The catalog turns individual repos into a connected map of the engineering organization.</p>
    <div>
      <h3>AGENTS.md: getting thousands of repos ready for AI</h3>
      <a href="#agents-md-getting-thousands-of-repos-ready-for-ai">
        
      </a>
    </div>
    <p>Early in the rollout, we kept seeing the same failure mode: coding agents produced changes that looked plausible and were still wrong for the repo. Usually the problem was local context: the model didn't know the right test command, the team's current conventions, or which parts of the codebase were off-limits. That pushed us toward AGENTS.md: a short, structured file in each repo that tells coding agents how the codebase actually works and forces teams to make that context explicit.</p>
    <div>
      <h4>What AGENTS.md looks like</h4>
      <a href="#what-agents-md-looks-like">
        
      </a>
    </div>
    <p>We built a system that generates AGENTS.md files across our GitLab instance. Because these files sit directly in the model's context window, we wanted them to stay short and high-signal. A typical file looks like this:</p>
            <pre><code># AGENTS.md

## Repository
- Runtime: cloudflare workers
- Test command: `pnpm test`
- Lint command: `pnpm lint`

## How to navigate this codebase
- All cloudflare workers  are in src/workers/, one file per worker
- MCP server definitions are in src/mcp/, each tool in a separate file
- Tests mirror source: src/foo.ts -&gt; tests/foo.test.ts

## Conventions
- Testing: use Vitest with `@cloudflare/vitest-pool-workers` (Codex: RFC 021, RFC 042)
- API patterns: Follow internal REST conventions (Codex: API-REST-01)

## Boundaries
- Do not edit generated files in `gen/`
- Do not introduce new background jobs without updating `config/`

## Dependencies
- Depends on: auth-service, config-service
- Depended on by: api-gateway, dashboard
</code></pre>
            <p></p><p>When an agent reads this file, it doesn't have to infer the repo from scratch. It knows how the codebase is organized, which conventions to follow and which Engineering Codex rules apply.</p>
    <div>
      <h4>How we generate them at scale</h4>
      <a href="#how-we-generate-them-at-scale">
        
      </a>
    </div>
    <p>The generator pipeline pulls entity metadata from our Backstage service catalog (ownership, dependencies, system relationships), analyzes the repository structure to detect the language, build system, test framework, and directory layout, then maps the detected stack to relevant Engineering Codex standards. A capable model then generates the structured document, and the system opens a merge request so the owning team can review and refine it.</p><p>We've processed roughly 3,900 repositories this way. The first pass wasn't always perfect, especially for polyglot repos or unusual build setups, but even that baseline was much better than asking agents to infer everything from scratch.</p><p>The initial merge request solved the bootstrap problem, but keeping these files current mattered just as much. A stale AGENTS.md can be worse than no file at all. We closed that loop with the AI Code Reviewer, which can flag when repository changes suggest that AGENTS.md should be updated.</p>
    <div>
      <h2>Act 3: The enforcement layer</h2>
      <a href="#act-3-the-enforcement-layer">
        
      </a>
    </div>
    
    <div>
      <h3>The AI Code Reviewer</h3>
      <a href="#the-ai-code-reviewer">
        
      </a>
    </div>
    <p>Every merge request at Cloudflare gets an AI code review. Integration is straightforward: teams add a single CI component to their pipeline, and from that point every MR is reviewed automatically.</p><p>We use GitLab's self-hosted solution as our CI/CD platform. The reviewer is implemented as a GitLab CI component that teams include in their pipeline. When an MR is opened or updated, the CI job runs <a href="https://opencode.ai/"><u>OpenCode</u></a> with a multi-agent review coordinator. The coordinator classifies the MR by risk tier (trivial, lite, or full) and delegates to specialized review agents: code quality, security, codex compliance, documentation, performance, and release impact. Each agent connects to the AI Gateway for model access, pulls Engineering Codex rules from a central repo, and reads the repository's AGENTS.md for codebase context. Results are posted back as structured MR comments.</p><p>A separate Workers-based config service handles centralized model selection per reviewer agent, so we can shift models without changing the CI template. The review process itself runs in the CI runner and is stateless per execution.</p>
    <div>
      <h3>The output format</h3>
      <a href="#the-output-format">
        
      </a>
    </div>
    
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5CKN6frPHygTkAHBDrY3y7/e04eb00702a25627291c904fbde2e7ea/BLOG-3270_9.png" />
          </figure><p>We spent time getting the output format right. Reviews are broken into categories (Security, Code Quality, Performance) so engineers can scan headers rather than reading walls of text. Each finding has a severity level (Critical, Important, Suggestion, or Optional Nits) that makes it immediately clear what needs attention versus what's informational.</p><p>The reviewer maintains context across iterations. If it flagged something in a previous review round that has since been fixed, it acknowledges that rather than re-raising the same issue. And when a finding maps to an Engineering Codex rule, it cites the specific rule ID, turning an AI suggestion into a reference to an organizational standard.</p><p>Workers AI handles about 15% of the reviewer's traffic, primarily for documentation review tasks where Kimi K2.5 performs well at a fraction of the cost of frontier models. Models like Opus 4.6 and GPT 5.4 handle security-sensitive and architecturally complex reviews where reasoning capability matters most.</p><p>Over the last 30 days:</p><ul><li><p><b>100%</b> AI code reviewer coverage across all repos on our standard CI pipeline.</p></li><li><p>5.47M AI Gateway requests</p></li><li><p>24.77B tokens processed</p></li></ul><p>We're releasing a <a href="http://blog.cloudflare.com/ai-code-review"><u>detailed technical blog post</u></a> alongside this one that covers the reviewer's internal architecture, including how we route between models, the multi-agent orchestration, and the cost optimization strategies we've developed.</p>
    <div>
      <h3>Engineering Codex: engineering standards as agent skills</h3>
      <a href="#engineering-codex-engineering-standards-as-agent-skills">
        
      </a>
    </div>
    <p>The <b>Engineering Codex</b> is Cloudflare's new internal standards system where our core engineering standards live. We have a multi-stage AI distillation process, which outputs a set of codex rules ("If you need X, use Y. You must do X, if you are doing Y or Z.") along with an agent skill that uses progressive disclosure and nested hierarchical information directories and links across markdown files. </p><p>This skill is available for engineers to use locally as they build with prompts like “how should I handle errors in my Rust service?” or “review this TypeScript code for compliance.” Our Network Firewall team audited <code>rampartd</code> using a multi-agent consensus process where every requirement was scored COMPLIANT, PARTIAL, or NON-COMPLIANT with specific violation details and remediation steps reducing what previously required weeks of manual work to a structured, repeatable process.</p><p>At review time, the AI Code Reviewer cites specific Codex rules in its feedback.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6vXFmpfwqv1Xqo5CszCsEB/ada6417470b2b7533a12244578cbd9d0/BLOG-3270_10.png" />
          </figure><p><sup> </sup><sup><i>AI Code Review: showing categorized findings (Codex Compliance in this case) noting the codex RFC violation.</i></sup></p><p>None of these pieces are especially novel on their own. Plenty of companies run service catalogs, ship reviewer bots, or publish engineering standards. The difference is the wiring. When an agent can pull context from Backstage, read AGENTS.md for the repo it’s editing, and get reviewed against Codex rules by the same toolchain, the first draft is usually close enough to ship. That wasn’t true six months ago.</p>
    <div>
      <h2>The scoreboard</h2>
      <a href="#the-scoreboard">
        
      </a>
    </div>
    <p>From launching this effort to 93% R&amp;D adoption took less than a year.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1OtTpHobBRjorxOV2dWG8w/9b9dc80cba9741ee65e8565f63091e1a/BLOG-3270_11.png" />
          </figure><p><b>Company-wide adoption (Feb 5 – April 15, 2026):</b></p><table><tr><th><p>Metric</p></th><th><p>Value</p></th></tr><tr><td><p>Active users</p></td><td><p><b>3,683</b> (60% of the company)</p></td></tr><tr><td><p>R&amp;D team adoption</p></td><td><p><b>93%</b></p></td></tr><tr><td><p>AI messages</p></td><td><p><b>47.95M</b></p></td></tr><tr><td><p>Teams with AI activity</p></td><td><p><b>295</b></p></td></tr><tr><td><p>OpenCode messages</p></td><td><p><b>27.08M</b></p></td></tr><tr><td><p>Windsurf messages</p></td><td><p><b>434.9K</b></p></td></tr></table><p><b>AI Gateway (last 30 days, combined):</b></p><table><tr><th><p>Metric</p></th><th><p>Value</p></th></tr><tr><td><p>Requests</p></td><td><p><b>20.18M</b></p></td></tr><tr><td><p>Tokens</p></td><td><p><b>241.37B</b></p></td></tr></table><p><b>Workers AI (last 30 days):</b></p><table><tr><th><p>Metric</p></th><th><p>Value</p></th></tr><tr><td><p>Input tokens</p></td><td><p><b>51.47B</b></p></td></tr><tr><td><p>Output tokens</p></td><td><p><b>361.12M</b></p></td></tr></table>
    <div>
      <h2>What's next: background agents</h2>
      <a href="#whats-next-background-agents">
        
      </a>
    </div>
    <p>The next evolution in our internal engineering stack will include background agents: agents that can be spun up on demand with the same tools available locally (MCP portal, git, test runners) but running entirely in the cloud. The architecture uses Durable Objects and the Agents SDK for orchestration, delegating to Sandbox containers when the job requires a full development environment like cloning a repo, installing dependencies, or running tests. The <a href="https://blog.cloudflare.com/sandbox-ga/"><u>Sandbox SDK went GA</u></a> during Agents Week.</p><p>Long-running agents, <a href="https://blog.cloudflare.com/project-think/"><u>shipped natively into the Agents SDK</u></a> during Agents Week, solve the durable session problem that previously required workarounds. The SDK now supports sessions that run for extended periods without eviction, enough for an agent to clone a large repo, run a full test suite, iterate on failures, and open a MR in a single session.</p><p>This represents an eleven-month effort to rethink not just how code gets written, but how it gets reviewed, how standards are enforced, and how changes ship safely across thousands of repos. Every layer runs on the same products our customers use.</p>
    <div>
      <h2>Start building</h2>
      <a href="#start-building">
        
      </a>
    </div>
    <p>Agents Week just <a href="https://blogs.cloudflare.com/agents-week-in-review"><u>shipped</u></a> everything you need. The platform is here.</p>
            <pre><code>npx create-cloudflare@latest --template cloudflare/agents-starter
</code></pre>
            <p>That agents starter gets you running. The diagram below is the full architecture for when you’re ready to grow it, your tools layer on top (chatbot, web UI, CLI, browser extension), the Agents SDK handling session state and orchestration in the middle, and the Cloudflare services you call from it underneath.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3Ebzq5neZbshbrhb5WysYY/54335791b2f731e2095fd57a4fe11cf3/image11.png" />
          </figure><p><b>Docs:</b> <a href="https://developers.cloudflare.com/agents/"><u>Agents SDK</u></a> · <a href="https://developers.cloudflare.com/sandbox/"><u>Sandbox SDK</u></a> · <a href="https://developers.cloudflare.com/ai-gateway/"><u>AI Gateway</u></a> · <a href="https://developers.cloudflare.com/workers-ai/"><u>Workers AI</u></a> · <a href="https://developers.cloudflare.com/workflows/"><u>Workflows</u></a> · <a href="https://developers.cloudflare.com/agents/api-reference/codemode/"><u>Code Mode</u></a> · <a href="https://blog.cloudflare.com/model-context-protocol/"><u>MCP on Cloudflare</u></a></p><p><b>Repos:</b> <a href="https://github.com/cloudflare/agents"><u>cloudflare/agents</u></a> · <a href="https://github.com/cloudflare/sandbox-sdk"><u>cloudflare/sandbox-sdk</u></a> · <a href="https://github.com/cloudflare/mcp-server-cloudflare"><u>cloudflare/mcp-server-cloudflare</u></a> · <a href="https://github.com/cloudflare/skills"><u>cloudflare/skills</u></a></p><p>For more on how we’re using AI at Cloudflare, read the post on <a href="http://blog.cloudflare.com/ai-code-review"><u>our process for AI Code Review</u></a>. And check out <a href="https://www.cloudflare.com/agents-week/updates/"><u>everything we shipped during Agents Week</u></a>.</p><p>We’d love to hear what you build. Find us on <a href="https://discord.cloudflare.com/"><u>Discord</u>,</a> <a href="https://x.com/CloudflareDev"><u>X</u>, and</a> <a href="https://bsky.app/profile/cloudflare.social"><u>Bluesky</u></a>.</p><p><sup><i>Ayush Thakur built the AGENTS.md system and the AI Gateway integration for the OpenCode infrastructure, Scott Roemeschke is the Engineering Manager of the Developer Productivity team at Cloudflare, Rajesh Bhatia leads the Productivity Platform function at Cloudflare. This post was a collaborative effort across the Devtools team, with help from volunteers across the company through the iMARS (Internal MCP Agent/Server Rollout Squad) tiger team.</i></sup></p> ]]></content:encoded>
            <category><![CDATA[Agents Week]]></category>
            <category><![CDATA[Agents]]></category>
            <category><![CDATA[AI]]></category>
            <category><![CDATA[Cloudflare Workers]]></category>
            <category><![CDATA[SASE]]></category>
            <category><![CDATA[MCP]]></category>
            <category><![CDATA[Developer Platform]]></category>
            <category><![CDATA[Developers]]></category>
            <category><![CDATA[Cloudflare Gateway]]></category>
            <category><![CDATA[Product News]]></category>
            <category><![CDATA[Workers AI]]></category>
            <guid isPermaLink="false">4z7ZJ5ZbY3e3YwJtkg6NiD</guid>
            <dc:creator>Ayush Thakur</dc:creator>
            <dc:creator>Scott Roe-Meschke</dc:creator>
            <dc:creator>Rajesh Bhatia</dc:creator>
        </item>
        <item>
            <title><![CDATA[From 0 to 20 billion - How We Built Crawler Hints]]></title>
            <link>https://blog.cloudflare.com/from-0-to-20-billion-how-we-built-crawler-hints/</link>
            <pubDate>Thu, 16 Dec 2021 13:58:29 GMT</pubDate>
            <description><![CDATA[ Cloudflare Is reducing the environmental impact of web searches with 20+ billions crawler hints delivered so far. This blog describes the technical solution of how we built the Crawler Hints system that makes all this possible.
 ]]></description>
            <content:encoded><![CDATA[ 
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/xs3odwiEbW2X4uv6wNNdA/a08cd0796a54029678fd143edc84e4d6/image2-57.png" />
            
            </figure><p>In July 2021, as part of <a href="/welcome-to-cloudflare-impact-week/">Impact Innovation Week</a>, we announced our intention to launch <a href="/crawler-hints-how-cloudflare-is-reducing-the-environmental-impact-of-web-searches/">Crawler Hints</a> as a means to reduce the environmental impact of web searches. We spent the weeks following the announcement hard at work, and in October 2021, we announced <a href="/cloudflare-now-supports-indexnow/">General Availability for the first iteration of the product</a>. This post explains how we built it, some of the interesting engineering problems we had to solve, and shares some metrics on how it's going so far.</p>
    <div>
      <h2>Before We Begin...</h2>
      <a href="#before-we-begin">
        
      </a>
    </div>
    <p>Search indexers crawl sites periodically to check for new content. Algorithms vary by search provider, but are often based on either a regular interval or cadence of past updates, and these crawls are often not aligned with real world content changes. This naive crawling approach may harm customer page rank and also works to the detriment of search engines with respect to their operational costs and environmental impact. To make the Internet greener and more energy efficient, the goal of Crawler Hints is to help search indexers make more informed decisions on when content has changed, saving valuable compute cycles/bandwidth and having a net positive environmental impact.</p><p>Cloudflare is in an advantageous position to help inform crawlers of content changes, as we are often the “front line” of the interface between site visitors and the origin server where the content updates take place. This grants us knowledge of some key data points like headers, content hashes, and site purges among others. For customers who have opted in to Crawler Hints, we leverage this data to generate a “content freshness score” using an ensemble of active and passive signals from our customer base and request flow. To help with efficiency, Crawler Hints helps to improve SEO for websites behind Cloudflare, improves relevance for search engine users, and improves origin responsiveness by reducing bot traffic to our customers’ origin servers.</p><p>A high level design of the system we built looks as follows:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4kSfCs22YboeTPDLdbffsG/b21c528beaa8579a0d6e2e3b874fccca/image3-42.png" />
            
            </figure><p>In this blog we will dig into each aspect of it in more detail.</p>
    <div>
      <h2>Keeping Things Fresh</h2>
      <a href="#keeping-things-fresh">
        
      </a>
    </div>
    <p><a href="https://www.cloudflare.com/network/">Cloudflare has a large global network spanning 250 cities</a>.  A popular use case for Cloudflare is to use our CDN product to cache your website's assets so that users accessing your site can benefit from lightning fast response times. You can read more about how Cloudflare manages our cache <a href="/why-we-started-putting-unpopular-assets-in-memory/">here</a>. The important thing to call out for the purpose of this post is that the cache is Data Center local. A cache hit in London might be a cache miss in San Francisco unless you have opted-in to <a href="/orpheus/">tiered-caching</a>, but that is beyond the scope of this post.</p><p>For Crawler Hints to work, we make use of a number of signals available at request time to make an informed decision on the “freshness” of content. For our first iteration of Crawler Hints, we used a cache miss from Cloudflare’s cache as a starting basis. Although a naive signal on its own, getting the data pipelines in place to forward cache miss data from our global network to our control plane meant we would have everything in place to iterate on and improve the signal processing quickly going forward. To do this, we leveraged some existing services from our data team that takes request data , marshalls it into <a href="https://capnproto.org/">Cap'n Proto format</a>, and forwards it to a message bus (we use apache Kafka). These messages include the URLs of the resources that have met the signal criteria, along with some additional metadata for analytics/future improvement.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1XeWU8Bx1SuIOajaVbu3Kd/76edad32d2eff51af6b2d9887ea2825e/image4-34.png" />
            
            </figure><p>The amount of traffic our global network receives is substantial. We serve over 28 million HTTP requests per second on average, with more than 35 million HTTP requests per second at peak. Typically, Cloudflare teams sample this data to enable products <a href="/get-notified-when-your-site-is-under-attack/">such as being alerted when you are under attack</a>. For Crawler Hints, every cache miss is important. Therefore, 100% of all cache misses for opted-in sites were sent for further processing, and we’ll discuss more on opt-in later.</p>
    <div>
      <h2>Redis as a Distributed Buffer</h2>
      <a href="#redis-as-a-distributed-buffer">
        
      </a>
    </div>
    <p>With messages buffered in Kafka, we can now begin the work of aggregation and deduplication. We wrote a consumer service that we call an ingestor. The ingestor reads the data from Kafka. The ingestor performs validation to ensure proper sanitization and data integrity and passes this data onto the next stage of the system. We run the ingestor as part of a Kafka consumer group, allowing us to scale our consumer count up to the partition size as throughput increases.</p><p>We ultimately want to deliver a set of “fresh” content to our search partners on a dynamic interval. For example, we might want to send a batch of 10,000 URLs every two minutes. There are, however, a couple of important things to call out though:</p><ul><li><p>There should be no duplicate resources in each batch.</p></li><li><p>We should strike a balance in our size and frequency such that overall request size isn’t too large, but big enough to remove some pressure on the receiving API by not sending too <i>many</i> requests at once.</p></li></ul><p>For the deduplication, the simplest thing to do would be to have an in-memory map in our service to track resources between a pre-specified interval. A naive implementation in Go might look something like this.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2vlmka7b85QzcVxziLLGdR/b3669b1bbd3fd4108d94ffa8052b2f8d/image5-22.png" />
            
            </figure><p>The problem with this approach is we have little resilience. If the service was to crash, we would lose all the data for our current batch. Furthermore, if we were to run multiple instances of our services, they would all have a different “view” of which resources they had seen before and therefore we would not be deduplicating.To mitigate this issue, we decided to use a specialist caching service. There are a number of distributed caches that would fit the bill, but we chose Redis given our team’s familiarity with operating it at scale.</p><p>Redis is well known as a Key Value(KV) store often used for caching things,optionally with a specified Time To Live(TTL). Perhaps slightly less obvious is its value as a distributed buffer, housing ephemeral data with periodic flush/tear-downs. For Crawler Hints, we leveraged both these traits via a multi-generational, multi-cluster setup to achieve a highly available rolling aggregation service.</p><p>Two standalone Redis clusters were spun up. For each generation of request data, one cluster would be designated as the active primary. The validated records would be inserted as keys on the primary, serving the dual purpose of buffering while also deduplicating since Redis keys are unique. Separately, a downstream service (more on this later!) would periodically issue the command for these inserters to switch from the active primary (cluster A) to the inactive cluster (cluster B). Cluster A could then be flushed with records being batch read in a size of our choosing.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4IYn9s1nmM2Qcci2c5A8cn/21069dec8e9b95ec87e17d8b2d31a767/image9-5.png" />
            
            </figure>
    <div>
      <h2>Buffering for Dispatch</h2>
      <a href="#buffering-for-dispatch">
        
      </a>
    </div>
    <p>At this point, we have clean, batched data. Things are looking good! However, there’s one small hiccup in the plan: we’re reading these batches from Redis at some set interval. What if it takes longer to dispatch than the interval itself? What if the search partner API is having issues?</p><p>We need a way to ensure the durability of the batch URLs and reduce the impact of any dispatch issues. To do this, we revisit an old friend from earlier: Kafka. The batches that get read from Redis are then fed into a Kafka topic. We wrote a Kafka consumer that we call the “dispatcher service” which runs within a consumer group to enable us to scale it if necessary just like the ingestor. The dispatcher reads from the Kafka topic and sends a batch of resources to each of our API partners.</p><p>Launching in tandem with Cloudflare, Crawler Hints was a joint venture between a few early adopters in the search engine space to provide a means for sites to inform indexers of content changes called IndexNow. <a href="/cloudflare-now-supports-indexnow/">You can read more about this launch here.</a> IndexNow is a large part of what makes Crawler Hints possible. As part of its manifest, it provides a common API spec to publish resources that should be re-indexed. The standardized API makes abstracting the communication layer quite simple for the partners that support it. “Pushing” these signals to our search engine partners is a big step away from the inefficient “Pull” based model that is used today (you can read more about that <a href="/crawler-hints-how-cloudflare-is-reducing-the-environmental-impact-of-web-searches/">here</a>). We launched with Yandex and Bing as Search Engine Partners.</p><p>To ensure we can add more partners in the future, we defined an interface which we call a “Hinter”.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7K0wQWVx2hciGxZVwFMxM6/a3b6f0272225bbddd393465592c98721/image8-12.png" />
            
            </figure><p>We then satisfy this interface for each partner that we work with. We return a custom error from the Hinter service that is of type *indexers.Error. The definition of which is:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7Aq6eqraSEg1TpQ2b2QJK9/e763eb8303e0d1fdef3807ae58503cda/image1-84.png" />
            
            </figure><p>This allows us to “bubble up” information about which indexer has failed and increment metrics and retry only those calls to indexers which have failed.</p><p>This all culminates together with the following in our service layer:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5fwN6ZGTRJ5NARBrJWLfOq/a69a7ef3147e17c02de3c99e0f92ee95/image6-21.png" />
            
            </figure><p>Simple, performant, maintainable, AND easy to add more partners in the future.</p>
    <div>
      <h2>Rolling out Crawler Hints</h2>
      <a href="#rolling-out-crawler-hints">
        
      </a>
    </div>
    <p>At Cloudflare, we often release things that haven’t been done before at scale. This project is a great example of that. Trying to gauge how many users would be interested in this product and what the uptake might be like on day one, day ten, and day one thousand is close to impossible. As engineers responsible for running this system, it is essential we build in checks and balances so that the system does not become overwhelmed and responds appropriately. For this particular project, there are three different types of “protection” we put in place. These are:</p><ul><li><p>Customer opt-in</p></li><li><p>Monitoring &amp; Alerts</p></li><li><p>System resilience via “self-healing”</p></li></ul>
    <div>
      <h3>Customer opt-in</h3>
      <a href="#customer-opt-in">
        
      </a>
    </div>
    <p>Cloudflare takes any changes that can impact customer traffic flow seriously. Considering Crawler Hints has the potential to change how sites are seen externally (even if in this instance the site’s viewers are robots!) and can impact things like SEO and bandwidth usage, asking customers to opt-in is a sensible default. By asking customers to opt-in to the service, we can start to get an understanding of our system’s capacity and look for bottle necks and how to remove them. To do this, we make extensive use of Prometheus, Grafana, and Kibana.</p>
    <div>
      <h3>Monitoring &amp; Alerting</h3>
      <a href="#monitoring-alerting">
        
      </a>
    </div>
    <p>We do our best to make our systems as “self-healing” and easy to run as possible, but as they say, “By failing to prepare, you are preparing to fail.” We therefore invest a lot of time creating ways to track the health and performance of our system and creating automated alerts when things fall outside of expected bounds.</p><p>Below is a small sample of the Grafana dashboard we created for this project. As you can see, we can track customer enablement and the rate of hint dispatch in real time. The bottom two panels show the throughput of our Kafka clusters by partition. Even just these four metrics give us a lot of insight into how things are going, but we also track (as well as other things):</p><ul><li><p>Lag on Kafka by partition (how far behind real time we are)</p></li><li><p>Bad messages received from Kafka</p></li><li><p>Amount of URLs processed per “run”</p></li><li><p>Response code per index partner over time</p></li><li><p>Response time of partner API over time</p></li><li><p>Health of the Redis clusters (how much memory is used, frequency of commands we are using received by the cluster)</p></li><li><p>Memory, CPU usage, and pods available against configured limits/requests</p></li></ul>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7bunGQ2Uvk8bZ5jdRz3t6G/08a155b3ec60b9bf44218a4d2e12b774/image7-12.png" />
            
            </figure><p>It seems a lot to track, but this information is invaluable to us, and we use it to generate alerts that notify the on-call engineer if a threshold is breached. For example, we have an alert that would escalate to an engineer if our Redis cluster approached 80% capacity. For some thresholds we specify, we may want the system to “self-heal.” In this instance, we would want an engineer to investigate as this is outside the bounds of “normal,” and it might be that something is not working as expected. An alternative reason that we might receive alerts is that our product has increased in popularity beyond our expectations, and we simply need to increase the memory limit. This requires context and is therefore best left to a human to make this decision.</p>
    <div>
      <h3>System Resilience via “self-healing”</h3>
      <a href="#system-resilience-via-self-healing">
        
      </a>
    </div>
    <p>We do everything we can to not disturb on-call engineers, and therefore, we try to make the system as “self-healing” as possible. We also don’t want to have too much extra resource running as it can be expensive and use limited capacity that another  Cloudflare service might need more - it's a trade off.  To do this, we make use of a few patterns and tools common in every distributed engineer’s toolbelt. Firstly, we deploy on Kubernetes. This enables us to make use of great features like <a href="https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/">Horizontal Pod Autoscaling</a>. When any of our pods reach ~80% memory usage, a new pod is created which will pick up some of the slack up to a predefined limit.</p><p>Secondly, by using a message bus, we get a lot of control over the amount of “work” our services have to do in a given time frame. In general, a message bus is “pull” based. If we want more work, we ask for it. If we want less work, we pull less. This holds for the most part, but with a system where being close to real time is important, it is essential that we monitor the “lag” of the topic, or how far we are behind real time. If we are too far behind, we may want to introduce more partitions or consumers.</p><p>Finally, networks fail. We therefore add retry policies to all HTTP calls we make before reporting them a failure. For example, if we were to receive a 500 (Internal Server Error) from one of our partner APIs, we would retry up to five times using an exponential backoff strategy before reporting a failure.</p>
    <div>
      <h2>Data from the first couple of months</h2>
      <a href="#data-from-the-first-couple-of-months">
        
      </a>
    </div>
    <p>Since the release of Crawler Hints on October 18, 2021 until December 15, 2021, Crawler Hints has processed over twenty five billion crawl signals, has been opted-in to by more than 81,000 customers, and has handled roughly 18,000 requests per second. It’s been an exciting project to be a part of, and we are just getting started.</p>
    <div>
      <h2>What’s Next?</h2>
      <a href="#whats-next">
        
      </a>
    </div>
    <p>We will continue to work with our partners to improve the standard even further and continue to improve the signaling on our side to ensure the most valuable information is being pushed on behalf of our customers in a timely manner.</p><p><b><i>If you're interested in building scalable services and solving interesting technical problems, we are hiring engineers on our team in</i></b> <a href="https://boards.greenhouse.io/cloudflare/jobs/3129759?gh_jid=3129759"><b><i>Austin</i></b></a><b><i>,</i></b> <a href="https://boards.greenhouse.io/cloudflare/jobs/3231716?gh_jid=3231716"><b><i>Lisbon</i></b></a><b><i>, and</i></b> <a href="https://boards.greenhouse.io/cloudflare/jobs/3231718?gh_jid=3231718"><b><i>London</i></b></a><b><i>.</i></b></p> ]]></content:encoded>
            <category><![CDATA[Crawler Hints]]></category>
            <category><![CDATA[Product News]]></category>
            <category><![CDATA[Speed & Reliability]]></category>
            <category><![CDATA[SEO]]></category>
            <guid isPermaLink="false">3WLRRaI7sl25i1KhmRq7YB</guid>
            <dc:creator>Matt Boyle</dc:creator>
            <dc:creator>Nathan Disidore</dc:creator>
            <dc:creator>Rajesh Bhatia</dc:creator>
        </item>
    </channel>
</rss>