C

Cloudflare changelogs | Developer platform

Cloudflare changelogs for Developer platform products

Durable Objects, Workers - View and edit Durable Object data in UI with Data Studio (Beta)

You can now view and write to each Durable Object's storage using a UI editor on the Cloudflare dashboard. Only Durable Objects using SQLite storage can use Data Studio. Go to Durable Objects Data Studio unlocks easier data access with Durable Objects for prototyping application data models to debugging production storage usage. Before, querying your Durable Objects data required deploying a Worker. To access a Durable Object, you can provide an object's unique name or ID generated by Cloudflare. Data Studio requires you to have at least the Workers Platform Admin role, and all queries are captured with audit logging for your security and compliance needs. Queries executed by Data Studio send requests to your remote, deployed objects and incur normal usage billing. To learn more, visit the Data Studio documentation. If you have feedback or suggestions for the new Data Studio, please share your experience on Discord

2025/10/16
articleCard.readMore

Workers - Worker startup time limit increased to 1 second

You can now upload a Worker that takes up 1 second to parse and execute its global scope. Previously, startup time was limited to 400 ms. This allows you to run Workers that import more complex packages and execute more code prior to requests being handled. For more information, see the documentation on Workers startup limits.

2025/10/10
articleCard.readMore

Workers - You can now deploy full-stack apps on Workers using Terraform

You can now upload Workers with static assets (like HTML, CSS, JavaScript, images) with the Cloudflare Terraform provider v5.11.0, making it even easier to deploy and manage full-stack apps with IaC. Previously, you couldn't use Terraform to upload static assets without writing custom scripts to handle generating an asset manifest, calling the Cloudflare API to upload assets in chunks, and handling change detection. Now, you simply define the directory where your assets are built, and we handle the rest. Check out the examples for what this looks like in Terraform configuration. You can get started today with the Cloudflare Terraform provider (v5.11.0), using either the existing cloudflare_workers_script resource, or the beta cloudflare_worker_version resource. Examples With cloudflare_workers_script Here's how you can use the existing cloudflare_workers_script resource to upload your Worker code and assets in one shot. resource "cloudflare_workers_script" "my_app" { account_id = var.account_id script_name = "my-app" content_file = "./dist/worker/index.js" content_sha256 = filesha256("./dist/worker/index.js") main_module = "index.js" # Just point to your assets directory - that's it! assets = { directory = "./dist/static" } } With cloudflare_worker, cloudflare_worker_version, and cloudflare_workers_deployment And here's an example using the beta cloudflare_worker_version resource, alongside the cloudflare_worker and cloudflare_workers_deployment resources: # This tracks the existence of your Worker, so that you # can upload code and assets separately from tracking Worker state. resource "cloudflare_worker" "my_app" { account_id = var.account_id name = "my-app" } resource "cloudflare_worker_version" "my_app_version" { account_id = var.account_id worker_id = cloudflare_worker.my_app.id # Just point to your assets directory - that's it! assets = { directory = "./dist/static" } modules = [{ name = "index.js" content_file = "./dist/worker/index.js" content_type = "application/javascript+module" }] } resource "cloudflare_workers_deployment" "my_app_deployment" { account_id = var.account_id script_name = cloudflare_worker.my_app.name strategy = "percentage" versions = [{ version_id = cloudflare_worker_version.my_app_version.id percentage = 100 }] } What's changed Under the hood, the Cloudflare Terraform provider now handles the same logic that Wrangler uses for static asset uploads. This includes scanning your assets directory, computing hashes for each file, generating a manifest with file metadata, and calling the Cloudflare API to upload any missing files in chunks. We support large directories with parallel uploads and chunking, and when the asset manifest hash changes, we detect what's changed and trigger an upload for only those changed files. Try it out Get started with the Cloudflare Terraform provider (v5.11.0) You can use either the existing cloudflare_workers_script resource to upload your Worker code and assets in one resource. Or you can use the new beta cloudflare_worker_version resource (along with the cloudflare_worker and cloudflare_workers_deployment) resources to more granularly control the lifecycle of each Worker resource.

2025/10/9
articleCard.readMore

Workers - You can now deploy and manage Workflows in Terraform

You can now create and manage Workflows using Terraform, now supported in the Cloudflare Terraform provider v5.11.0. Workflows allow you to build durable, multi-step applications -- without needing to worry about retrying failed tasks or managing infrastructure. Now, you can deploy and manage Workflows through Terraform using the new cloudflare_workflow resource: resource "cloudflare_workflow" "my_workflow" { account_id = var.account_id workflow_name = "my-workflow" class_name = "MyWorkflow" script_name = "my-worker" } Examples Here are full examples of how to configure cloudflare_workflow in Terraform, using the existing cloudflare_workers_script resource, and the beta cloudflare_worker_version resource. With cloudflare_workflow and cloudflare_workers_script resource "cloudflare_workers_script" "workflow_worker" { account_id = var.cloudflare_account_id script_name = "my-workflow-worker" content_file = "${path.module}/../dist/worker/index.js" content_sha256 = filesha256("${path.module}/../dist/worker/index.js") main_module = "index.js" } resource "cloudflare_workflow" "workflow" { account_id = var.cloudflare_account_id workflow_name = "my-workflow" class_name = "MyWorkflow" script_name = cloudflare_workers_script.workflow_worker.script_name } With cloudflare_workflow, and the new beta resources You can more granularly control the lifecycle of each Worker resource using the beta cloudflare_worker_version resource, alongside the cloudflare_worker and cloudflare_workers_deployment resources. resource "cloudflare_worker" "workflow_worker" { account_id = var.cloudflare_account_id name = "my-workflow-worker" } resource "cloudflare_worker_version" "workflow_worker_version" { account_id = var.cloudflare_account_id worker_id = cloudflare_worker.workflow_worker.id main_module = "index.js" modules = [{ name = "index.js" content_file = "${path.module}/../dist/worker/index.js" content_type = "application/javascript+module" }] } resource "cloudflare_workers_deployment" "workflow_deployment" { account_id = var.cloudflare_account_id script_name = cloudflare_worker.workflow_worker.name strategy = "percentage" versions = [{ version_id = cloudflare_worker_version.workflow_worker_version.id percentage = 100 }] } resource "cloudflare_workflow" "my_workflow" { account_id = var.cloudflare_account_id workflow_name = "my-workflow" class_name = "MyWorkflow" script_name = cloudflare_worker.workflow_worker.name } Try it out Get started with the Cloudflare Terraform provider (v5.11.0) and the new cloudflare_workflow resource.

2025/10/9
articleCard.readMore

Workers - New Overview Page for Cloudflare Workers

Each of your Workers now has a new overview page in the Cloudflare dashboard. The goal is to make it easier to understand your Worker without digging through multiple tabs. Think of it as a new home base, a place to get a high-level overview on what's going on. It's the first place you land when you open a Worker in the dashboard, and it gives you an immediate view of what’s going on. You can see requests, errors, and CPU time at a glance. You can view and add bindings, and see recent versions of your app, including who published them. Navigation is also simpler, with visually distinct tabs at the top of the page. At the bottom right you'll find guided steps for what to do next that are based on the state of your Worker, such as adding a binding or connecting a custom domain. We plan to add more here over time. Better insights, more controls, and ways to manage your Worker from one page. If you have feedback or suggestions for the new Overview page or your Cloudflare Workers experience in general, we'd love to hear from you. Join the Cloudflare developer community on Discord.

2025/10/7
articleCard.readMore

R2 - R2 Data Catalog table-level compaction

You can now enable compaction for individual Apache Iceberg tables in R2 Data Catalog, giving you fine-grained control over different workloads. # Enable compaction for a specific table (no token required) npx wrangler r2 bucket catalog compaction enable <BUCKET> <NAMESPACE> <TABLE> --target-size 256 This allows you to: Apply different target file sizes per table Disable compaction for specific tables Optimize based on table-specific access patterns Learn more at Manage catalogs.

2025/10/6
articleCard.readMore

Workers - One-click Cloudflare Access for Workers

You can now enable Cloudflare Access for your workers.dev and Preview URLs in a single click. Access allows you to limit access to your Workers to specific users or groups. You can limit access to yourself, your teammates, your organization, or anyone else you specify in your Access policy. To enable Cloudflare Access: In the Cloudflare dashboard, go to the Workers & Pages page. Go to Workers & Pages In Overview, select your Worker. Go to Settings > Domains & Routes. For workers.dev or Preview URLs, click Enable Cloudflare Access. Optionally, to configure the Access application, click Manage Cloudflare Access. There, you can change the email addresses you want to authorize. View Access policies to learn about configuring alternate rules. To fully secure your application, it is important that you validate the JWT that Cloudflare Access adds to the Cf-Access-Jwt-Assertion header on the incoming request. The following code will validate the JWT using the jose NPM package: import { jwtVerify, createRemoteJWKSet } from "jose"; export default { async fetch(request, env, ctx) { // Verify the POLICY_AUD environment variable is set if (!env.POLICY_AUD) { return new Response('Missing required audience', { status: 403, headers: { 'Content-Type': 'text/plain' } }); } // Get the JWT from the request headers const token = request.headers.get("cf-access-jwt-assertion"); // Check if token exists if (!token) { return new Response("Missing required CF Access JWT", { status: 403, headers: { "Content-Type": "text/plain" }, }); } try { // Create JWKS from your team domain const JWKS = createRemoteJWKSet( new URL(`${env.TEAM_DOMAIN}/cdn-cgi/access/certs`), ); // Verify the JWT const { payload } = await jwtVerify(token, JWKS, { issuer: env.TEAM_DOMAIN, audience: env.POLICY_AUD, }); // Token is valid, proceed with your application logic return new Response(`Hello ${payload.email || "authenticated user"}!`, { headers: { "Content-Type": "text/plain" }, }); } catch (error) { // Token verification failed return new Response(`Invalid token: ${error.message}`, { status: 403, headers: { "Content-Type": "text/plain" }, }); } }, }; Required environment variables Add these environment variables to your Worker: POLICY_AUD: Your application's AUD tag TEAM_DOMAIN: https://<your-team-name>.cloudflareaccess.com Both of these appear in the modal that appears when you enable Cloudflare Access. You can set these variables by adding them to your Worker's Wrangler configuration file, or via the Cloudflare dashboard under Workers & Pages > your-worker > Settings > Environment Variables.

2025/10/3
articleCard.readMore

Workers AI - New Deepgram Flux model available on Workers AI

Deepgram's newest Flux model @cf/deepgram/flux is now available on Workers AI, hosted directly on Cloudflare's infrastructure. We're excited to be a launch partner with Deepgram and offer their new Speech Recognition model built specifically for enabling voice agents. Check out Deepgram's blog for more details on the release. The Flux model can be used in conjunction with Deepgram's speech-to-text model @cf/deepgram/nova-3 and text-to-speech model @cf/deepgram/aura-1 to build end-to-end voice agents. Having Deepgram on Workers AI takes advantage of our edge GPU infrastructure, for ultra low latency voice AI applications. Promotional Pricing For the month of October 2025, Deepgram's Flux model will be free to use on Workers AI. Official pricing will be announced soon and charged after the promotional pricing period ends on October 31, 2025. Check out the model page for pricing details in the future. Example Usage The new Flux model is WebSocket only as it requires live bi-directional streaming in order to recognize speech activity. Create a worker that establishes a websocket connection with @cf/deepgram/flux export default { async fetch(request, env, ctx): Promise<Response> { const resp = await env.AI.run("@cf/deepgram/flux", { encoding: "linear16", sample_rate: "16000" }, { websocket: true }); return resp; }, } satisfies ExportedHandler<Env>; Deploy your worker npx wrangler deploy Write a client script to connect to your worker and start sending random audio bytes to it const ws = new WebSocket('wss://<your-worker-url.com>'); ws.onopen = () => { console.log('Connected to WebSocket'); // Generate and send random audio bytes // You can replace this part with a function // that reads from your mic or other audio source const audioData = generateRandomAudio(); ws.send(audioData); console.log('Audio data sent'); }; ws.onmessage = (event) => { // Transcription will be received here // Add your custom logic to parse the data console.log('Received:', event.data); }; ws.onerror = (error) => { console.error('WebSocket error:', error); }; ws.onclose = () => { console.log('WebSocket closed'); }; // Generate random audio data (1 second of noise at 44.1kHz, mono) function generateRandomAudio() { const sampleRate = 44100; const duration = 1; const numSamples = sampleRate * duration; const buffer = new ArrayBuffer(numSamples * 2); const view = new Int16Array(buffer); for (let i = 0; i < numSamples; i++) { view[i] = Math.floor(Math.random() * 65536 - 32768); } return buffer; }

2025/10/2
articleCard.readMore

Workers Analytics Engine, Workers - Workers Analytics Engine adds supports for new SQL functions

You can now perform more powerful queries directly in Workers Analytics Engine with a major expansion of our SQL function library. Workers Analytics Engine allows you to ingest and store high-cardinality data at scale (such as custom analytics) and query your data through a simple SQL API. Today, we've expanded Workers Analytics Engine's SQL capabilities with several new functions: New aggregate functions: argMin() - Returns the value associated with the minimum in a group argMax() - Returns the value associated with the maximum in a group topK() - Returns an array of the most frequent values in a group topKWeighted() - Returns an array of the most frequent values in a group using weights first_value() - Returns the first value in an ordered set of values within a partition last_value() - Returns the last value in an ordered set of values within a partition New bit functions: bitAnd() - Returns the bitwise AND of two expressions bitCount() - Returns the number of bits set to one in the binary representation of a number bitHammingDistance() - Returns the number of bits that differ between two numbers bitNot() - Returns a number with all bits flipped bitOr() - Returns the inclusive bitwise OR of two expressions bitRotateLeft() - Rotates all bits in a number left by specified positions bitRotateRight() - Rotates all bits in a number right by specified positions bitShiftLeft() - Shifts all bits in a number left by specified positions bitShiftRight() - Shifts all bits in a number right by specified positions bitTest() - Returns the value of a specific bit in a number bitXor() - Returns the bitwise exclusive-or of two expressions New mathematical functions: abs() - Returns the absolute value of a number log() - Computes the natural logarithm of a number round() - Rounds a number to a specified number of decimal places ceil() - Rounds a number up to the nearest integer floor() - Rounds a number down to the nearest integer pow() - Returns a number raised to the power of another number New string functions: lowerUTF8() - Converts a string to lowercase using UTF-8 encoding upperUTF8() - Converts a string to uppercase using UTF-8 encoding New encoding functions: hex() - Converts a number to its hexadecimal representation bin() - Converts a string to its binary representation New type conversion functions: toUInt8() - Converts any numeric expression, or expression resulting in a string representation of a decimal, into an unsigned 8 bit integer Ready to get started? Whether you're building usage-based billing systems, customer analytics dashboards, or other custom analytics, these functions let you get the most out of your data. Get started with Workers Analytics Engine and explore all available functions in our SQL reference documentation.

2025/10/2
articleCard.readMore

Containers - Larger Container instance types

New instance types provide up to 4 vCPU, 12 GiB of memory, and 20 GB of disk per container instance. Instance TypevCPUMemoryDisk lite1/16256 MiB2 GB basic1/41 GiB4 GB standard-11/24 GiB8 GB standard-216 GiB12 GB standard-328 GiB16 GB standard-4412 GiB20 GB The dev and standard instance types are preserved for backward compatibility and are aliases for lite and standard-1, respectively. The standard-1 instance type now provides up to 8 GB of disk instead of only 4 GB. See the getting started guide to deploy your first Container, and the limits documentation for more details on the available instance types and limits.

2025/10/1
articleCard.readMore

Workers - Automatic loopback bindings via ctx.exports

The ctx.exports API contains automatically-configured bindings corresponding to your Worker's top-level exports. For each top-level export extending WorkerEntrypoint, ctx.exports will contain a Service Binding by the same name, and for each export extending DurableObject (and for which storage has been configured via a migration), ctx.exports will contain a Durable Object namespace binding. This means you no longer have to configure these bindings explicitly in wrangler.jsonc/wrangler.toml. Example: import { WorkerEntrypoint } from "cloudflare:workers"; export class Greeter extends WorkerEntrypoint { greet(name) { return `Hello, ${name}!`; } } export default { async fetch(request, env, ctx) { let greeting = await ctx.exports.Greeter.greet("World") return new Response(greeting); } } At present, you must use the enable_ctx_exports compatibility flag to enable this API, though it will be on by default in the future. See the API reference for more information.

2025/9/26
articleCard.readMore

Pipelines - Pipelines now supports SQL transformations and Apache Iceberg

Today, we're launching the new Cloudflare Pipelines: a streaming data platform that ingests events, transforms them with SQL, and writes to R2 as Apache Iceberg tables or Parquet files. Pipelines can receive events via HTTP endpoints or Worker bindings, transform them with SQL, and deliver to R2 with exactly-once guarantees. This makes it easy to build analytics-ready warehouses for server logs, mobile application events, IoT telemetry, or clickstream data without managing streaming infrastructure. For example, here's a pipeline that ingests clickstream events and filters out bot traffic while extracting domain information: INSERT into events_table SELECT user_id, lower(event) AS event_type, to_timestamp_micros(ts_us) AS event_time, regexp_match(url, '^https?://([^/]+)')[1] AS domain, url, referrer, user_agent FROM events_json WHERE event = 'page_view' AND NOT regexp_like(user_agent, '(?i)bot|spider'); Get started by creating a pipeline in the dashboard or running a single command in Wrangler: npx wrangler pipelines setup Check out our getting started guide to learn how to create a pipeline that delivers events to an Iceberg table you can query with R2 SQL. Read more about today's announcement in our blog post.

2025/9/25
articleCard.readMore

R2 SQL - Announcing R2 SQL

Today, we're launching the open beta for R2 SQL: A serverless, distributed query engine that can efficiently analyze petabytes of data in Apache Iceberg tables managed by R2 Data Catalog. R2 SQL is ideal for exploring analytical and time-series data stored in R2, such as logs, events from Pipelines, or clickstream and user behavior data. If you already have a table in R2 Data Catalog, running queries is as simple as: npx wrangler r2 sql query YOUR_WAREHOUSE " SELECT user_id, event_type, value FROM events.user_events WHERE event_type = 'CHANGELOG' or event_type = 'BLOG' AND __ingest_ts > '2025-09-24T00:00:00Z' ORDER BY __ingest_ts DESC LIMIT 100" To get started with R2 SQL, check out our getting started guide or learn more about supported features in the SQL reference. For a technical deep dive into how we built R2 SQL, read our blog post.

2025/9/25
articleCard.readMore

R2 - R2 Data Catalog now supports compaction

You can now enable automatic compaction for Apache Iceberg tables in R2 Data Catalog to improve query performance. Compaction is the process of taking a group of small files and combining them into fewer larger files. This is an important maintenance operation as it helps ensure that query performance remains consistent by reducing the number of files that needs to be scanned. To enable automatic compaction in R2 Data Catalog, find it under R2 Data Catalog in your R2 bucket settings in the dashboard. Or with Wrangler, run: npx wrangler r2 bucket catalog compaction enable <BUCKET_NAME> --target-size 128 --token <API_TOKEN> To get started with compaction, check out manage catalogs. For best practices and limitations, refer to about compaction.

2025/9/25
articleCard.readMore

Browser Rendering - Browser Rendering Playwright GA, Stagehand support (Beta), and higher limits

We’re shipping three updates to Browser Rendering: Playwright support is now Generally Available and synced with Playwright v1.55, giving you a stable foundation for critical automation and AI-agent workflows. We’re also adding Stagehand support (Beta) so you can combine code with natural language instructions to build more resilient automations. Finally, we’ve tripled limits for paid plans across both the REST API and Workers Bindings to help you scale. To get started with Stagehand, refer to the Stagehand example that uses Stagehand and Workers AI to search for a movie on this example movie directory, extract its details using natural language (title, year, rating, duration, and genre), and return the information along with a screenshot of the webpage. const stagehand = new Stagehand({ env: "LOCAL", localBrowserLaunchOptions: { cdpUrl: endpointURLString(env.BROWSER) }, llmClient: new WorkersAIClient(env.AI), verbose: 1, }); await stagehand.init(); const page = stagehand.page; await page.goto('https://demo.playwright.dev/movies'); // if search is a multi-step action, stagehand will return an array of actions it needs to act on const actions = await page.observe('Search for "Furiosa"'); for (const action of actions) await page.act(action); await page.act('Click the search result'); // normal playwright functions work as expected await page.waitForSelector('.info-wrapper .cast'); let movieInfo = await page.extract({ instruction: 'Extract movie information', schema: z.object({ title: z.string(), year: z.number(), rating: z.number(), genres: z.array(z.string()), duration: z.number().describe("Duration in minutes"), }), }); await stagehand.close();

2025/9/25
articleCard.readMore

AI Search - AI Search (formerly AutoRAG) now with More Models To Choose From

AutoRAG is now AI Search! The new name marks a new and bigger mission: to make world-class search infrastructure available to every developer and business. With AI Search you can now use models from different providers like OpenAI and Anthropic. By attaching your provider keys to the AI Gateway linked to your AI Search instance, you can use many more models for both embedding and inference. To use AI Search with other model providers: Add provider keys to AI Gateway Go to AI > AI Gateway in the dashboard. Select or create an AI gateway. In Provider Keys, choose your provider, click Add, and enter the key. Connect a gateway to AI Search: When creating a new AI Search, select the AI Gateway with your provider keys. For an existing AI Search, go to Settings and switch to a gateway that has your keys under Resources. Select models: Embedding models are only available to be changed when creating a new AI Search. Generation model can be selected when creating a new AI Search and can be changed at any time in Settings. Once configured, your AI Search instance will be able to reference models available through your AI Gateway when making a /ai-search request: export default { async fetch(request, env) { // Query your AI Search instance with a natural language question to an OpenAI model const result = await env.AI.autorag("my-ai-search").aiSearch({ query: "What's new for Cloudflare Birthday Week?", model: "openai/gpt-5" }); // Return only the generated answer as plain text return new Response(result.response, { headers: { "Content-Type": "text/plain" }, }); }, }; In the coming weeks we will also roll out updates to align the APIs with the new name. The existing APIs will continue to be supported for the time being. Stay tuned to the AI Search Changelog and Discord for more updates!

2025/9/25
articleCard.readMore

Containers - Run more Containers with higher resource limits

You can now run more Containers concurrently with higher limits on CPU, memory, and disk. LimitNew LimitPrevious Limit Memory for concurrent live Container instances400GiB40GiB vCPU for concurrent live Container instances10020 Disk for concurrent live Container instances2TB100GB You can now run 1000 instances of the dev instance type, 400 instances of basic, or 100 instances of standard concurrently. This opens up new possibilities for running larger-scale workloads on Containers. See the getting started guide to deploy your first Container, and the limits documentation for more details on the available instance types and limits.

2025/9/25
articleCard.readMore

Workers - Improved support for running multiple Workers with `wrangler dev`

You can run multiple Workers in a single dev command by passing multiple config files to wrangler dev: wrangler dev --config ./web/wrangler.jsonc --config ./api/wrangler.jsonc Previously, if you ran the command above and then also ran wrangler dev for a different Worker, the Workers running in separate wrangler dev sessions could not communicate with each other. This prevented you from being able to use Service Bindings and Tail Workers in local development, when running separate wrangler dev sessions. Now, the following works as expected: # Terminal 1: Run your application that includes both Web and API workers wrangler dev --config ./web/wrangler.jsonc --config ./api/wrangler.jsonc # Terminal 2: Run your auth worker separately wrangler dev --config ./auth/wrangler.jsonc These Workers can now communicate with each other across separate dev commands, regardless of your development setup. export default { async fetch(request, env) { // This service binding call now works across dev commands const authorized = await env.AUTH.isAuthorized(request); if (!authorized) { return new Response('Unauthorized', { status: 401 }); } return new Response('Hello from API Worker!', { status: 200 }); }, }; Check out the Developing with multiple Workers guide to learn more about the different approaches and when to use each one.

2025/9/23
articleCard.readMore

AI Search - New Metrics View in AutoRAG

AutoRAG now includes a Metrics tab that shows how your data is indexed and searched. Get a clear view of the health of your indexing pipeline, compare usage between ai-search and search, and see which files are retrieved most often. You can find these metrics within each AutoRAG instance: Indexing: Track how files are ingested and see status changes over time. Search breakdown: Compare usage between ai-search and search endpoints. Top file retrievals: Identify which files are most frequently retrieved in a given period. Try it today in AutoRAG.

2025/9/19
articleCard.readMore

Workers - Rate Limiting in Workers is now GA

Rate Limiting within Cloudflare Workers is now Generally Available (GA). The ratelimit binding is now stable and recommended for all production workloads. Existing deployments using the unsafe binding will continue to function to allow for a smooth transition. For more details, refer to Workers Rate Limiting documentation.

2025/9/19
articleCard.readMore

Workers - Panic Recovery for Rust Workers

In workers-rs, Rust panics were previously non-recoverable. A panic would put the Worker into an invalid state, and further function calls could result in memory overflows or exceptions. Now, when a panic occurs, in-flight requests will throw 500 errors, but the Worker will automatically and instantly recover for future requests. This ensures more reliable deployments. Automatic panic recovery is enabled for all new workers-rs deployments as of version 0.6.5, with no configuration required. Fixing Rust Panics with Wasm Bindgen Rust Workers are built with Wasm Bindgen, which treats panics as non-recoverable. After a panic, the entire Wasm application is considered to be in an invalid state. We now attach a default panic handler in Rust: std::panic::set_hook(Box::new(move |panic_info| { hook_impl(panic_info); })); Which is registered by default in the JS initialization: import { setPanicHook } from "./index.js"; setPanicHook(function (err) { console.error("Panic handler!", err); }); When a panic occurs, we reset the Wasm state to revert the Wasm application to how it was when the application started. Resetting VM State in Wasm Bindgen We worked upstream on the Wasm Bindgen project to implement a new --experimental-reset-state-function compilation option which outputs a new __wbg_reset_state function. This function clears all internal state related to the Wasm VM, and updates all function bindings in place to reference the new WebAssembly instance. One other necessary change here was associating Wasm-created JS objects with an instance identity. If a JS object created by an earlier instance is then passed into a new instance later on, a new "stale object" error is specially thrown when using this feature. Layered Solution Building on this new Wasm Bindgen feature, layered with our new default panic handler, we also added a proxy wrapper to ensure all top-level exported class instantiations (such as for Rust Durable Objects) are tracked and fully reinitialized when resetting the Wasm instance. This was necessary because the workerd runtime will instantiate exported classes, which would then be associated with the Wasm instance. This approach now provides full panic recovery for Rust Workers on subsequent requests. Of course, we never want panics, but when they do happen they are isolated and can be investigated further from the error logs - avoiding broader service disruption. WebAssembly Exception Handling In the future, full support for recoverable panics could be implemented without needing reinitialization at all, utilizing the WebAssembly Exception Handling proposal, part of the newly announced WebAssembly 3.0 specification. This would allow unwinding panics as normal JS errors, and concurrent requests would no longer fail. We're making significant improvements to the reliability of Rust Workers. Join us in #rust-on-workers on the Cloudflare Developers Discord to stay updated.

2025/9/19
articleCard.readMore

Workers - Increased vCPU for Workers Builds on paid plans

We recently increased the available disk space from 8 GB to 20 GB for all plans. Building on that improvement, we’re now doubling the CPU power available for paid plans — from 2 vCPU to 4 vCPU. These changes continue our focus on making Workers Builds faster and more reliable. MetricFree PlanPaid Plans CPU2 vCPU4 vCPU Performance Improvements Fast build times: Even single-threaded workloads benefit from having more vCPUs 2x faster multi-threaded builds: Tools like esbuild and webpack can now utilize additional cores, delivering near-linear performance scaling All other build limits — including memory, build minutes, and timeout remain unchanged.

2025/9/18
articleCard.readMore

Workers - Preview URLs now default to opt-in

To prevent the accidental exposure of applications, we've updated how Worker preview URLs (<PREVIEW>-<WORKER_NAME>.<SUBDOMAIN>.workers.dev) are handled. We made this change to ensure preview URLs are only active when intentionally configured, improving the default security posture of your Workers. One-Time Update for Workers with workers.dev Disabled We performed a one-time update to disable preview URLs for existing Workers where the workers.dev subdomain was also disabled. Because preview URLs were historically enabled by default, users who had intentionally disabled their workers.dev route may not have realized their Worker was still accessible at a separate preview URL. This update was performed to ensure that using a preview URL is always an intentional, opt-in choice. If your Worker was affected, its preview URL (<PREVIEW>-<WORKER_NAME>.<SUBDOMAIN>.workers.dev) will now direct to an informational page explaining this change. How to Re-enable Your Preview URL If your preview URL was disabled, you can re-enable it via the Cloudflare dashboard by navigating to your Worker's Settings page and toggling on the Preview URL. Alternatively, you can use Wrangler by adding the preview_urls = true setting to your Wrangler file and redeploying the Worker. wrangler.jsonc { "preview_urls": true } wrangler.toml preview_urls = true Note: You can set preview_urls = true with any Wrangler version that supports the preview URL flag (v3.91.0+). However, we recommend updating to v4.34.0 or newer, as this version defaults preview_urls to false, ensuring preview URLs are always enabled by explicit choice.

2025/9/17
articleCard.readMore

Workers - Remote bindings GA - Connect to remote resources (D1, KV, R2, etc.) during local development

Three months ago we announced the public beta of remote bindings for local development. Now, we're excited to say that it's available for everyone in Wrangler, Vite, and Vitest without using an experimental flag! With remote bindings, you can now connect to deployed resources like R2 buckets and D1 databases while running Worker code on your local machine. This means you can test your local code changes against real data and services, without the overhead of deploying for each iteration. Example configuration To enable remote bindings, add "remote" : true to each binding that you want to rely on a remote resource running on Cloudflare: wrangler.jsonc { "name": "my-worker", "compatibility_date": "2025-10-16", "r2_buckets": [ { "bucket_name": "screenshots-bucket", "binding": "screenshots_bucket", "remote": true, }, ], } wrangler.toml name = "my-worker" compatibility_date = "2025-10-16" [[r2_buckets]] bucket_name = "screenshots-bucket" binding = "screenshots_bucket" remote = true When remote bindings are configured, your Worker still executes locally, but all binding calls are proxied to the deployed resource that runs on Cloudflare's network. You can try out remote bindings for local development today with: Wrangler v4.37.0 The Cloudflare Vite Plugin The Cloudflare Vitest Plugin

2025/9/16
articleCard.readMore

D1, Workers - D1 automatically retries read-only queries

D1 now detects read-only queries and automatically attempts up to two retries to execute those queries in the event of failures with retryable errors. You can access the number of execution attempts in the returned response metadata property total_attempts. At the moment, only read-only queries are retried, that is, queries containing only the following SQLite keywords: SELECT, EXPLAIN, WITH. Queries containing any SQLite keyword that leads to database writes are not retried. The retry success ratio among read-only retryable errors varies from 5% all the way up to 95%, depending on the underlying error and its duration (like network errors or other internal errors). The retry success ratio among all retryable errors is lower, indicating that there are write-queries that could be retried. Therefore, we recommend D1 users to continue applying retries in their own code for queries that are not read-only but are idempotent according to the business logic of the application. D1 ensures that any retry attempt does not cause database writes, making the automatic retries safe from side-effects, even if a query causing changes slips through the read-only detection. D1 achieves this by checking for modifications after every query execution, and if any write occurred due to a retry attempt, the query is rolled back. The read-only query detection heuristics are simple for now, and there is room for improvement to capture more cases of queries that can be retried, so this is just the beginning.

2025/9/11
articleCard.readMore

Workers - Worker version rollback limit increased from 10 to 100

The number of recent versions available for a Worker rollback has been increased from 10 to 100. This allows you to: Promote any of the 100 most recent versions to be the active deployment. Split traffic using gradual deployments between your latest code and any of the 100 most recent versions. You can do this through the Cloudflare dashboard or with Wrangler's rollback command Learn more about versioned deployments and rollbacks.

2025/9/11
articleCard.readMore

Agents, Workers - Agents SDK v0.1.0 and workers-ai-provider v2.0.0 with AI SDK v5 support

We've shipped a new release for the Agents SDK bringing full compatibility with AI SDK v5 and introducing automatic message migration that handles all legacy formats transparently. This release includes improved streaming and tool support, tool confirmation detection (for "human in the loop" systems), enhanced React hooks with automatic tool resolution, improved error handling for streaming responses, and seamless migration utilities that work behind the scenes. This makes it ideal for building production AI chat interfaces with Cloudflare Workers AI models, agent workflows, human-in-the-loop systems, or any application requiring reliable message handling across SDK versions — all while maintaining backward compatibility. Additionally, we've updated workers-ai-provider v2.0.0, the official provider for Cloudflare Workers AI models, to be compatible with AI SDK v5. useAgentChat(options) Creates a new chat interface with enhanced v5 capabilities. // Basic chat setup const { messages, sendMessage, addToolResult } = useAgentChat({ agent, experimental_automaticToolResolution: true, tools, }); // With custom tool confirmation const chat = useAgentChat({ agent, experimental_automaticToolResolution: true, toolsRequiringConfirmation: ["dangerousOperation"], }); Automatic Tool Resolution Tools are automatically categorized based on their configuration: const tools = { // Auto-executes (has execute function) getLocalTime: { description: "Get current local time", inputSchema: z.object({}), execute: async () => new Date().toLocaleString(), }, // Requires confirmation (no execute function) deleteFile: { description: "Delete a file from the system", inputSchema: z.object({ filename: z.string(), }), }, // Server-executed (no client confirmation) analyzeData: { description: "Analyze dataset on server", inputSchema: z.object({ data: z.array(z.number()) }), serverExecuted: true, }, } satisfies Record<string, AITool>; Message Handling Send messages using the new v5 format with parts array: // Text message sendMessage({ role: "user", parts: [{ type: "text", text: "Hello, assistant!" }], }); // Multi-part message with file sendMessage({ role: "user", parts: [ { type: "text", text: "Analyze this image:" }, { type: "image", image: imageData }, ], }); Tool Confirmation Detection Simplified logic for detecting pending tool confirmations: const pendingToolCallConfirmation = messages.some((m) => m.parts?.some( (part) => isToolUIPart(part) && part.state === "input-available", ), ); // Handle tool confirmation if (pendingToolCallConfirmation) { await addToolResult({ toolCallId: part.toolCallId, tool: getToolName(part), output: "User approved the action", }); } Automatic Message Migration Seamlessly handle legacy message formats without code changes. // All these formats are automatically converted: // Legacy v4 string content const legacyMessage = { role: "user", content: "Hello world", }; // Legacy v4 with tool calls const legacyWithTools = { role: "assistant", content: "", toolInvocations: [ { toolCallId: "123", toolName: "weather", args: { city: "SF" }, state: "result", result: "Sunny, 72°F", }, ], }; // Automatically becomes v5 format: // { // role: "assistant", // parts: [{ // type: "tool-call", // toolCallId: "123", // toolName: "weather", // args: { city: "SF" }, // state: "result", // result: "Sunny, 72°F" // }] // } Tool Definition Updates Migrate tool definitions to use the new inputSchema property. // Before (AI SDK v4) const tools = { weather: { description: "Get weather information", parameters: z.object({ city: z.string(), }), execute: async (args) => { return await getWeather(args.city); }, }, }; // After (AI SDK v5) const tools = { weather: { description: "Get weather information", inputSchema: z.object({ city: z.string(), }), execute: async (args) => { return await getWeather(args.city); }, }, }; Cloudflare Workers AI Integration Seamless integration with Cloudflare Workers AI models through the updated workers-ai-provider v2.0.0. Model Setup with Workers AI Use Cloudflare Workers AI models directly in your agent workflows: import { createWorkersAI } from "workers-ai-provider"; import { useAgentChat } from "agents/ai-react"; // Create Workers AI model (v2.0.0 - same API, enhanced v5 internals) const model = createWorkersAI({ binding: env.AI, })("@cf/meta/llama-3.2-3b-instruct"); Enhanced File and Image Support Workers AI models now support v5 file handling with automatic conversion: // Send images and files to Workers AI models sendMessage({ role: "user", parts: [ { type: "text", text: "Analyze this image:" }, { type: "file", data: imageBuffer, mediaType: "image/jpeg", }, ], }); // Workers AI provider automatically converts to proper format Streaming with Workers AI Enhanced streaming support with automatic warning detection: // Streaming with Workers AI models const result = await streamText({ model: createWorkersAI({ binding: env.AI })("@cf/meta/llama-3.2-3b-instruct"), messages, onChunk: (chunk) => { // Enhanced streaming with warning handling console.log(chunk); }, }); Import Updates Update your imports to use the new v5 types: // Before (AI SDK v4) import type { Message } from "ai"; import { useChat } from "ai/react"; // After (AI SDK v5) import type { UIMessage } from "ai"; // or alias for compatibility import type { UIMessage as Message } from "ai"; import { useChat } from "@ai-sdk/react"; Resources Migration Guide - Comprehensive migration documentation AI SDK v5 Documentation - Official AI SDK migration guide An Example PR showing the migration from AI SDK v4 to v5 GitHub Issues - Report bugs or request features Feedback Welcome We'd love your feedback! We're particularly interested in feedback on: Migration experience - How smooth was the upgrade process? Tool confirmation workflow - Does the new automatic detection work as expected? Message format handling - Any edge cases with legacy message conversion?

2025/9/10
articleCard.readMore

Workers - Built with Cloudflare button

We've updated our "Built with Cloudflare" button to make it easier to share that you're building on Cloudflare with the world. Embed it in your project's README, blog post, or wherever you want to let people know. Check out the documentation for usage information.

2025/9/10
articleCard.readMore

Workers - Deploy static sites to Workers without a configuration file

Deploying static site to Workers is now easier. When you run wrangler deploy [directory] or wrangler deploy --assets [directory] without an existing configuration file, Wrangler CLI now guides you through the deployment process with interactive prompts. Before and after Before: Required remembering multiple flags and parameters wrangler deploy --assets ./dist --compatibility-date 2025-09-09 --name my-project After: Simple directory deployment with guided setup wrangler deploy dist # Interactive prompts handle the rest as shown in the example flow below What's new Interactive prompts for missing configuration: Wrangler detects when you're trying to deploy a directory of static assets Prompts you to confirm the deployment type Asks for a project name (with smart defaults) Automatically sets the compatibility date to today Automatic configuration generation: Creates a wrangler.jsonc file with your deployment settings Stores your choices for future deployments Eliminates the need to remember complex command-line flags Example workflow # Deploy your built static site wrangler deploy dist # Wrangler will prompt: ✔ It looks like you are trying to deploy a directory of static assets only. Is this correct? … yes ✔ What do you want to name your project? … my-astro-site # Automatically generates a wrangler.jsonc file and adds it to your project: { "name": "my-astro-site", "compatibility_date": "2025-09-09", "assets": { "directory": "dist" } } # Next time you run wrangler deploy, this will use the configuration in your newly generated wrangler.jsonc file wrangler deploy Requirements You must use Wrangler version 4.24.4 or later in order to use this feature

2025/9/9
articleCard.readMore

Workers AI - Introducing EmbeddingGemma from Google on Workers AI

We're excited to be a launch partner alongside Google to bring their newest embedding model, EmbeddingGemma, to Workers AI that delivers best-in-class performance for its size, enabling RAG and semantic search use cases. @cf/google/embeddinggemma-300m is a 300M parameter embedding model from Google, built from Gemma 3 and the same research used to create Gemini models. This multilingual model supports 100+ languages, making it ideal for RAG systems, semantic search, content classification, and clustering tasks. Using EmbeddingGemma in AI Search: Now you can leverage EmbeddingGemma directly through AI Search for your RAG pipelines. EmbeddingGemma's multilingual capabilities make it perfect for global applications that need to understand and retrieve content across different languages with exceptional accuracy. To use EmbeddingGemma for your AI Search projects: Go to Create in the AI Search dashboard Follow the setup flow for your new RAG instance In the Generate Index step, open up More embedding models and select @cf/google/embeddinggemma-300m as your embedding model Complete the setup to create an AI Search Try it out and let us know what you think!

2025/9/5
articleCard.readMore

Workers, Workers for Platforms - Increased static asset limits for Workers

You can now upload up to 100,000 static assets per Worker version Paid and Workers for Platforms users can now upload up to 100,000 static assets per Worker version, a 5x increase from the previous limit of 20,000. Customers on the free plan still have the same limit as before — 20,000 static assets per version of your Worker The individual file size limit of 25 MiB remains unchanged for all customers. This increase allows you to build larger applications with more static assets without hitting limits. Wrangler To take advantage of the increased limits, you must use Wrangler version 4.34.0 or higher. Earlier versions of Wrangler will continue to enforce the previous 20,000 file limit. Learn more For more information about Workers static assets, see the Static Assets documentation and Platform Limits.

2025/9/4
articleCard.readMore

Workers - A new, simpler REST API for Cloudflare Workers (Beta)

You can now manage Workers, Versions, and Deployments as separate resources with a new, resource-oriented API (Beta). This new API is supported in the Cloudflare Terraform provider and the Cloudflare Typescript SDK, allowing platform teams to manage a Worker's infrastructure in Terraform, while development teams handle code deployments from a separate repository or workflow. We also designed this API with AI agents in mind, as a clear, predictable structure is essential for them to reliably build, test, and deploy applications. Try it out New beta API endpoints Cloudflare TypeScript SDK v5.0.0 Cloudflare Go SDK v6.0.0 Terraform provider v5.9.0: cloudflare_worker , cloudflare_worker_version, and cloudflare_workers_deployments resources. See full examples in our Infrastructure as Code (IaC) guide Before: Eight+ endpoints with mixed responsibilities The existing API was originally designed for simple, one-shot script uploads: curl -X PUT "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/workers/scripts/$SCRIPT_NAME" \ -H "X-Auth-Email: $CLOUDFLARE_EMAIL" \ -H "X-Auth-Key: $CLOUDFLARE_API_KEY" \ -H "Content-Type: multipart/form-data" \ -F 'metadata={ "main_module": "worker.js", "compatibility_date": "$today$" }' \ -F "worker.js=@worker.js;type=application/javascript+module" This API worked for creating a basic Worker, uploading all of its code, and deploying it immediately — but came with challenges: A Worker couldn't exist without code: To create a Worker, you had to upload its code in the same API request. This meant platform teams couldn't provision Workers with the proper settings, and then hand them off to development teams to deploy the actual code. Several endpoints implicitly created deployments: Simple updates like adding a secret or changing a script's content would implicitly create a new version and immediately deploy it. Updating a setting was confusing: Configuration was scattered across eight endpoints with overlapping responsibilities. This ambiguity made it difficult for human developers (and even more so for AI agents) to reliably update a Worker via API. Scripts used names as primary identifiers: This meant simple renames could turn into a risky migration, requiring you to create a brand new Worker and update every reference. If you were using Terraform, this could inadvertently destroy your Worker altogether. After: Three resources with clear boundaries All endpoints now use simple JSON payloads, with script content embedded as base64-encoded strings -- a more consistent and reliable approach than the previous multipart/form-data format. Worker: The parent resource representing your application. It has a stable UUID and holds persistent settings like name, tags, and logpush. You can now create a Worker to establish its identity and settings before any code is uploaded. Version: An immutable snapshot of your code and its specific configuration, like bindings and compatibility_date. Creating a new version is a safe action that doesn't affect live traffic. Deployment: An explicit action that directs traffic to a specific version. Note Workers and Versions use the new /workers/ beta endpoints, while Deployments remain on the existing /scripts/ endpoint. Pair the new endpoints with the existing Deployment API for a complete workflow. Why this matters You can now create Workers before uploading code Workers are now standalone resources that can be created and configured without any code. Platform teams can provision Workers with the right settings, then hand them off to development teams for implementation. Example: Typescript SDK // Step 1: Platform team creates the Worker resource (no code needed) const worker = await client.workers.beta.workers.create({ name: "payment-service", account_id: "...", observability: { enabled: true, }, }); // Step 2: Development team adds code and creates a version later const version = await client.workers.beta.workers.versions.create(worker.id, { account_id: "...", main_module: "worker.js", compatibility_date: "$today", bindings: [ /*...*/ ], modules: [ { name: "worker.js", content_type: "application/javascript+module", content_base64: Buffer.from(scriptContent).toString("base64"), }, ], }); // Step 3: Deploy explicitly when ready const deployment = await client.workers.scripts.deployments.create(worker.name, { account_id: "...", strategy: "percentage", versions: [ { percentage: 100, version_id: version.id, }, ], }); Example: Terraform If you use Terraform, you can now declare the Worker in your Terraform configuration and manage configuration outside of Terraform in your Worker's wrangler.jsonc file and deploy code changes using Wrangler. resource "cloudflare_worker" "my_worker" { account_id = "..." name = "my-important-service" } # Manage Versions and Deployments here or outside of Terraform # resource "cloudflare_worker_version" "my_worker_version" {} # resource "cloudflare_workers_deployment" "my_worker_deployment" {} Deployments are always explicit, never implicit Creating a version and deploying it are now always explicit, separate actions - never implicit side effects. To update version-specific settings (like bindings), you create a new version with those changes. The existing deployed version remains unchanged until you explicitly deploy the new one. # Step 1: Create a new version with updated settings (doesn't affect live traffic) POST /workers/workers/{id}/versions { "compatibility_date": "$today", "bindings": [ { "name": "MY_NEW_ENV_VAR", "text": "new_value", "type": "plain_text" } ], "modules": [...] } # Step 2: Explicitly deploy when ready (now affects live traffic) POST /workers/scripts/{script_name}/deployments { "strategy": "percentage", "versions": [ { "percentage": 100, "version_id": "new_version_id" } ] } Settings are clearly organized by scope Configuration is now logically divided: Worker settings (like name and tags) persist across all versions, while Version settings (like bindings and compatibility_date) are specific to each code snapshot. # Worker settings (the parent resource) PUT /workers/workers/{id} { "name": "payment-service", "tags": ["production"], "logpush": true, } # Version settings (the "code") POST /workers/workers/{id}/versions { "compatibility_date": "$today", "bindings": [...], "modules": [...] } /workers API endpoints now support UUIDs (in addition to names) The /workers/workers/ path now supports addressing a Worker by both its immutable UUID and its mutable name. # Both work for the same Worker GET /workers/workers/29494978e03748669e8effb243cf2515 # UUID (stable for automation) GET /workers/workers/payment-service # Name (convenient for humans) This dual approach means: Developers can use readable names for debugging. Automation can rely on stable UUIDs to prevent errors when Workers are renamed. Terraform can rename Workers without destroying and recreating them. Learn more Infrastructure as Code (IaC) guide API documentation Versions and Deployments overview Technical notes The pre-existing Workers REST API remains fully supported. Once the new API exits beta, we'll provide a migration timeline with ample notice and comprehensive migration guides. Existing Terraform resources and SDK methods will continue to be fully supported through the current major version. While the Deployments API currently remains on the /scripts/ endpoint, we plan to introduce a new Deployments endpoint under /workers/ to match the new API structure.

2025/9/4
articleCard.readMore

Workers AI - Deepgram and Leonardo partner models now available on Workers AI

New state-of-the-art models have landed on Workers AI! This time, we're introducing new partner models trained by our friends at Deepgram and Leonardo, hosted on Workers AI infrastructure. As well, we're introuding a new turn detection model that enables you to detect when someone is done speaking — useful for building voice agents! Read the blog for more details and check out some of the new models on our platform: @cf/deepgram/aura-1 is a text-to-speech model that allows you to input text and have it come to life in a customizable voice @cf/deepgram/nova-3 is speech-to-text model that transcribes multilingual audio at a blazingly fast speed @cf/pipecat-ai/smart-turn-v2 helps you detect when someone is done speaking @cf/leonardo/lucid-origin is a text-to-image model that generates images with sharp graphic design, stunning full-HD renders, or highly specific creative direction @cf/leonardo/phoenix-1.0 is a text-to-image model with exceptional prompt adherence and coherent text You can filter out new partner models with the Partner capability on our Models page. As well, we're introducing WebSocket support for some of our audio models, which you can filter though the Realtime capability on our Models page. WebSockets allows you to create a bi-directional connection to our inference server with low latency — perfect for those that are building voice agents. An example python snippet on how to use WebSockets with our new Aura model: import json import os import asyncio import websockets uri = f"wss://api.cloudflare.com/client/v4/accounts/{ACCOUNT_ID}/ai/run/@cf/deepgram/aura-1" input = [ "Line one, out of three lines that will be provided to the aura model.", "Line two, out of three lines that will be provided to the aura model.", "Line three, out of three lines that will be provided to the aura model. This is a last line.", ] async def text_to_speech(): async with websockets.connect(uri, additional_headers={"Authorization": os.getenv("CF_TOKEN")}) as websocket: print("connection established") for line in input: print(f"sending `{line}`") await websocket.send(json.dumps({"type": "Speak", "text": line})) print("line was sent, flushing") await websocket.send(json.dumps({"type": "Flush"})) print("flushed, recving") resp = await websocket.recv() print(f"response received {resp}") if __name__ == "__main__": asyncio.run(text_to_speech())

2025/8/27
articleCard.readMore

Vectorize - List all vectors in a Vectorize index with the new list-vectors operation

You can now list all vector identifiers in a Vectorize index using the new list-vectors operation. This enables bulk operations, auditing, and data migration workflows through paginated requests that maintain snapshot consistency. The operation is available via Wrangler CLI and REST API. Refer to the list-vectors best practices guide for detailed usage guidance.

2025/8/26
articleCard.readMore

Secrets Store, AI Gateway, SSL/TLS - Manage and deploy your AI provider keys through Bring Your Own Key (BYOK) with AI Gateway, now powered by Cloudflare Secrets Store

Cloudflare Secrets Store is now integrated with AI Gateway, allowing you to store, manage, and deploy your AI provider keys in a secure and seamless configuration through Bring Your Own Key. Instead of passing your AI provider keys directly in every request header, you can centrally manage each key with Secrets Store and deploy in your gateway configuration using only a reference, rather than passing the value in plain text. You can now create a secret directly from your AI Gateway in the dashboard by navigating into your gateway -> Provider Keys -> Add. You can also create your secret with the newly available ai_gateway scope via wrangler, the Secrets Store dashboard, or the API. Then, pass the key in the request header using its Secrets Store reference: curl -X POST https://gateway.ai.cloudflare.com/v1/<ACCOUNT_ID>/my-gateway/anthropic/v1/messages \ --header 'cf-aig-authorization: ANTHROPIC_KEY_1 \ --header 'anthropic-version: 2023-06-01' \ --header 'Content-Type: application/json' \ --data '{"model": "claude-3-opus-20240229", "messages": [{"role": "user", "content": "What is Cloudflare?"}]}' Or, using Javascript: import Anthropic from '@anthropic-ai/sdk'; const anthropic = new Anthropic({ apiKey: "ANTHROPIC_KEY_1", baseURL: "https://gateway.ai.cloudflare.com/v1/<ACCOUNT_ID>/my-gateway/anthropic", }); const message = await anthropic.messages.create({ model: 'claude-3-opus-20240229', messages: [{role: "user", content: "What is Cloudflare?"}], max_tokens: 1024 }); For more information, check out the blog!

2025/8/25
articleCard.readMore

Workers - Content type returned in Workers Assets for Javascript files is now `text/javascript`

JavaScript asset responses have been updated to use the text/javascript Content-Type header instead of application/javascript. While both MIME types are widely supported by browsers, the HTML Living Standard explicitly recommends text/javascript as the preferred type going forward. This change improves: Standards alignment: Ensures consistency with the HTML spec and modern web platform guidance. Interoperability: Some developer tools, validators, and proxies expect text/javascript and may warn or behave inconsistently with application/javascript. Future-proofing: By following the spec-preferred MIME type, we reduce the risk of deprecation warnings or unexpected behavior in evolving browser environments. Consistency: Most frameworks, CDNs, and hosting providers now default to text/javascript, so this change matches common ecosystem practice. Because all major browsers accept both MIME types, this update is backwards compatible and should not cause breakage. Users will see this change on the next deployment of their assets.

2025/8/25
articleCard.readMore

KV - Workers KV completes hybrid storage provider rollout for improved performance, fault-tolerance

Workers KV has completed rolling out performance improvements across all KV namespaces, providing a significant latency reduction on read operations for all KV users. This is due to architectural changes to KV's underlying storage infrastructure, which introduces a new metadata later and substantially improves redundancy. Performance improvements The new hybrid architecture delivers substantial latency reductions throughout Europe, Asia, Middle East, Africa regions. Over the past 2 weeks, we have observed the following: p95 latency: Reduced from ~150ms to ~50ms (67% decrease) p99 latency: Reduced from ~350ms to ~250ms (29% decrease)

2025/8/22
articleCard.readMore

Workflows, Workers - Build durable multi-step applications in Python with Workflows (now in beta)

You can now build Workflows using Python. With Python Workflows, you get automatic retries, state persistence, and the ability to run multi-step operations that can span minutes, hours, or weeks using Python’s familiar syntax and the Python Workers runtime. Python Workflows use the same step-based execution model as JavaScript Workflows, but with Python syntax and access to Python’s ecosystem. Python Workflows also enable DAG (Directed Acyclic Graph) workflows, where you can define complex dependencies between steps using the depends parameter. Here’s a simple example: from workers import Response, WorkflowEntrypoint class PythonWorkflowStarter(WorkflowEntrypoint): async def run(self, event, step): @step.do("my first step") async def my_first_step(): # do some work return "Hello Python!" await my_first_step() await step.sleep("my-sleep-step", "10 seconds") @step.do("my second step") async def my_second_step(): # do some more work return "Hello again!" await my_second_step() async def on_fetch(request, env): await env.MY_WORKFLOW.create() return Response("Hello Workflow creation!") Note Python Workflows requires a compatibility_date = "2025-08-01", or lower, in your wrangler toml file. Python Workflows support the same core capabilities as JavaScript Workflows, including sleep scheduling, event-driven workflows, and built-in error handling with configurable retry policies. To learn more and get started, refer to Python Workflows documentation.

2025/8/22
articleCard.readMore

Durable Objects, Workers - New getByName() API to access Durable Objects

You can now create a client (a Durable Object stub) to a Durable Object with the new getByName method, removing the need to convert Durable Object names to IDs and then create a stub. // Before: (1) translate name to ID then (2) get a client const objectId = env.MY_DURABLE_OBJECT.idFromName("foo"); // or .newUniqueId() const stub = env.MY_DURABLE_OBJECT.get(objectId); // Now: retrieve client to Durable Object directly via its name const stub = env.MY_DURABLE_OBJECT.getByName("foo"); // Use client to send request to the remote Durable Object const rpcResponse = await stub.sayHello(); Each Durable Object has a globally-unique name, which allows you to send requests to a specific object from anywhere in the world. Thus, a Durable Object can be used to coordinate between multiple clients who need to work together. You can have billions of Durable Objects, providing isolation between application tenants. To learn more, visit the Durable Objects API Documentation or the getting started guide.

2025/8/21
articleCard.readMore

Queues - Subscribe to events from Cloudflare services with Queues

You can now subscribe to events from other Cloudflare services (for example, Workers KV, Workers AI, Workers) and consume those events via Queues, allowing you to build custom workflows, integrations, and logic in response to account activity. Event subscriptions allow you to receive messages when events occur across your Cloudflare account. Cloudflare products can publish structured events to a queue, which you can then consume with Workers or pull via HTTP from anywhere. To create a subscription, use the dashboard or Wrangler: npx wrangler queues subscription create my-queue --source r2 --events bucket.created An event is a structured record of something happening in your Cloudflare account – like a Workers AI batch request being queued, a Worker build completing, or an R2 bucket being created. Events follow a consistent structure: { "type": "cf.r2.bucket.created", "source": { "type": "r2" }, "payload": { "name": "my-bucket", "location": "WNAM" }, "metadata": { "accountId": "f9f79265f388666de8122cfb508d7776", "eventTimestamp": "2025-07-28T10:30:00Z" } } Current event sources include R2, Workers KV, Workers AI, Workers Builds, Vectorize, Super Slurper, and Workflows. More sources and events are on the way. For more information on event subscriptions, available events, and how to get started, refer to our documentation.

2025/8/19
articleCard.readMore

Workers - Easier debugging in Workers with improved Wrangler error screen

Wrangler's error screen has received several improvements to enhance your debugging experience! The error screen now features a refreshed design thanks to youch, with support for both light and dark themes, improved source map resolution logic that handles missing source files more reliably, and better error cause display. BeforeAfter (Light)After (Dark) Try it out now with npx wrangler@latest dev in your Workers project.

2025/8/19
articleCard.readMore

Workers - The Node.js and Web File System APIs in Workers

Implementations of the node:fs module and the Web File System API are now available in Workers. Using the node:fs module The node:fs module provides access to a virtual file system in Workers. You can use it to read and write files, create directories, and perform other file system operations. The virtual file system is ephemeral with each individual request havig its own isolated temporary file space. Files written to the file system will not persist across requests and will not be shared across requests or across different Workers. Workers running with the nodejs_compat compatibility flag will have access to the node:fs module by default when the compatibility date is set to 2025-09-01 or later. Support for the API can also be enabled using the enable_nodejs_fs_module compatibility flag together with the nodejs_compat flag. The node:fs module can be disabled using the disable_nodejs_fs_module compatibility flag. import fs from "node:fs"; const config = JSON.parse(fs.readFileSync("/bundle/config.json", "utf-8")); export default { async fetch(request) { return new Response(`Config value: ${config.value}`); }, }; There are a number of initial limitations to the node:fs implementation: The glob APIs (e.g. fs.globSync(...)) are not implemented. The file watching APIs (e.g. fs.watch(...)) are not implemented. The file timestamps (modified time, access time, etc) are only partially supported. For now, these will always return the Unix epoch. Refer to the Node.js documentation for more information on the node:fs module and its APIs. The Web File System API The Web File System API provides access to the same virtual file system as the node:fs module, but with a different API surface. The Web File System API is only available in Workers running with the enable_web_file_system compatibility flag. The nodejs_compat compatibility flag is not required to use the Web File System API. const root = navigator.storage.getDirectory(); export default { async fetch(request) { const tmp = await root.getDirectoryHandle("/tmp"); const file = await tmp.getFileHandle("data.txt", { create: true }); const writable = await file.createWritable(); const writer = writable.getWriter(); await writer.write("Hello, World!"); await writer.close(); return new Response("File written successfully!"); }, }; As there are still some parts of the Web File System API tht are not fully standardized, there may be some differences between the Workers implementation and the implementations in browsers.

2025/8/15
articleCard.readMore

Workers - Workers Static Assets: Corrected handling of double slashes in redirect rule paths

Static Assets: Fixed a bug in how redirect rules defined in your Worker's _redirects file are processed. If you're serving Static Assets with a _redirects file containing a rule like /ja/* /:splat, paths with double slashes were previously misinterpreted as external URLs. For example, visiting /ja//example.com would incorrectly redirect to https://example.com instead of /example.com on your domain. This has been fixed and double slashes now correctly resolve as local paths. Note: Cloudflare Pages was not affected by this issue.

2025/8/15
articleCard.readMore

Workers - Workers per-branch preview URLs now support long branch names

We've updated preview URLs for Cloudflare Workers to support long branch names. Previously, branch and Worker names exceeding the 63-character DNS limit would cause alias generation to fail, leaving pull requests without aliased preview URLs. This particularly impacted teams relying on descriptive branch naming. Now, Cloudflare automatically truncates long branch names and appends a unique hash, ensuring every pull request gets a working preview link. How it works 63 characters or less: <branch-name>-<worker-name> → Uses actual branch name as is 64 characters or more: <truncated-branch-name>--<hash>-<worker-name> → Uses truncated name with 4-character hash Hash generation: The hash is derived from the full branch name to ensure uniqueness Stable URLs: The same branch always generates the same hash across all commits Requirements and compatibility Wrangler 4.30.0 or later: This feature requires updating to wrangler@4.30.0+ No configuration needed: Works automatically with existing preview URL setups

2025/8/14
articleCard.readMore

Workers - Terraform provider improvements — Python Workers support, smaller plan diffs, and API SDK fixes

The recent Cloudflare Terraform Provider and SDK releases (such as cloudflare-typescript) bring significant improvements to the Workers developer experience. These updates focus on reliability, performance, and adding Python Workers support. Terraform Improvements Fixed Unwarranted Plan Diffs Resolved several issues with the cloudflare_workers_script resource that resulted in unwarranted plan diffs, including: Using Durable Objects migrations Using some bindings such as secret_text Using smart placement A resource should never show a plan diff if there isn't an actual change. This fix reduces unnecessary noise in your Terraform plan and is available in Cloudflare Terraform Provider 5.8.0. Improved File Management You can now specify content_file and content_sha256 instead of content. This prevents the Workers script content from being stored in the state file which greatly reduces plan diff size and noise. If your workflow synced plans remotely, this should now happen much faster since there is less data to sync. This is available in Cloudflare Terraform Provider 5.7.0. resource "cloudflare_workers_script" "my_worker" { account_id = "123456789" script_name = "my_worker" main_module = "worker.mjs" content_file = "worker.mjs" content_sha256 = filesha256("worker.mjs") } Assets Headers and Redirects Support Fixed the cloudflare_workers_script resource to properly support headers and redirects for Assets: resource "cloudflare_workers_script" "my_worker" { account_id = "123456789" script_name = "my_worker" main_module = "worker.mjs" content_file = "worker.mjs" content_sha256 = filesha256("worker.mjs") assets = { config = { headers = file("_headers") redirects = file("_redirects") } # Completion jwt from: # https://developers.cloudflare.com/api/resources/workers/subresources/assets/subresources/upload/ jwt = "jwt" } } Available in Cloudflare Terraform Provider 5.8.0. Python Workers Support Added support for uploading Python Workers (beta) in Terraform. You can now deploy Python Workers with: resource "cloudflare_workers_script" "my_worker" { account_id = "123456789" script_name = "my_worker" content_file = "worker.py" content_sha256 = filesha256("worker.py") content_type = "text/x-python" } Available in Cloudflare Terraform Provider 5.8.0. SDK Enhancements Improved File Upload API Fixed an issue where Workers script versions in the SDK did not allow uploading files. This now works, and also has an improved files upload interface: const scriptContent = ` export default { async fetch(request, env, ctx) { return new Response('Hello World!', { status: 200 }); } }; `; client.workers.scripts.versions.create('my-worker', { account_id: '123456789', metadata: { main_module: 'my-worker.mjs', }, files: [ await toFile( Buffer.from(scriptContent), 'my-worker.mjs', { type: "application/javascript+module", } ) ] }); Will be available in cloudflare-typescript 4.6.0. A similar change will be available in cloudflare-python 4.4.0. Fixed updating KV values Previously when creating a KV value like this: await cf.kv.namespaces.values.update("my-kv-namespace", "key1", { account_id: "123456789", metadata: "my metadata", value: JSON.stringify({ hello: "world" }) }); ...and recalling it in your Worker like this: const value = await c.env.KV.get<{hello: string}>("key1", "json"); You'd get back this: {metadata:'my metadata', value:"{'hello':'world'}"} instead of the correct value of {hello: 'world'} This is fixed in cloudflare-typescript 4.5.0 and will be fixed in cloudflare-python 4.4.0.

2025/8/14
articleCard.readMore

Workers - Python Workers handlers now live in an entrypoint class

We are changing how Python Workers are structured by default. Previously, handlers were defined at the top-level of a module as on_fetch, on_scheduled, etc. methods, but now they live in an entrypoint class. Here's an example of how to now define a Worker with a fetch handler: from workers import Response, WorkerEntrypoint class Default(WorkerEntrypoint): async def fetch(self, request): return Response("Hello World!") To keep using the old-style handlers, you can specify the disable_python_no_global_handlers compatibility flag in your wrangler file: wrangler.jsonc { "compatibility_flags": [ "disable_python_no_global_handlers" ] } wrangler.toml compatibility_flags = [ "disable_python_no_global_handlers" ] Consult the Python Workers documentation for more details.

2025/8/14
articleCard.readMore

Workers - MessageChannel and MessagePort

A minimal implementation of the MessageChannel API is now available in Workers. This means that you can use MessageChannel to send messages between different parts of your Worker, but not across different Workers. The MessageChannel and MessagePort APIs will be available by default at the global scope with any worker using a compatibility date of 2025-08-15 or later. It is also available using the expose_global_message_channel compatibility flag, or can be explicitly disabled using the no_expose_global_message_channel compatibility flag. const { port1, port2 } = new MessageChannel(); port2.onmessage = (event) => { console.log('Received message:', event.data); }; port2.postMessage('Hello from port2!'); Any value that can be used with the structuredClone(...) API can be sent over the port. Differences There are a number of key limitations to the MessageChannel API in Workers: Transfer lists are currently not supported. This means that you will not be able to transfer ownership of objects like ArrayBuffer or MessagePort between ports. The MessagePort is not yet serializable. This means that you cannot send a MessagePort object through the postMessage method or via JSRPC calls. The 'messageerror' event is only partially supported. If the 'onmessage' handler throws an error, the 'messageerror' event will be triggered, however, it will not be triggered when there are errors serializing or deserializing the message data. Instead, the error will be thrown when the postMessage method is called on the sending port. The 'close' event will be emitted on both ports when one of the ports is closed, however it will not be emitted when the Worker is terminated or when one of the ports is garbage collected.

2025/8/11
articleCard.readMore

Workers - Wrangler and the Cloudflare Vite plugin support `.env` files in local development

Now, you can use .env files to provide secrets and override environment variables on the env object during local development with Wrangler and the Cloudflare Vite plugin. Previously in local development, if you wanted to provide secrets or environment variables during local development, you had to use .dev.vars files. This is still supported, but you can now also use .env files, which are more familiar to many developers. Using .env files in local development You can create a .env file in your project root to define environment variables that will be used when running wrangler dev or vite dev. The .env file should be formatted like a dotenv file, such as KEY="VALUE": TITLE="My Worker" API_TOKEN="dev-token" When you run wrangler dev or vite dev, the environment variables defined in the .env file will be available in your Worker code via the env object: export default { async fetch(request, env) { const title = env.TITLE; // "My Worker" const apiToken = env.API_TOKEN; // "dev-token" const response = await fetch( `https://api.example.com/data?token=${apiToken}`, ); return new Response(`Title: ${title} - ` + (await response.text())); }, }; Multiple environments with .env files If your Worker defines multiple environments, you can set different variables for each environment (ex: production or staging) by creating files named .env.<environment-name>. When you use wrangler <command> --env <environment-name> or CLOUDFLARE_ENV=<environment-name> vite dev, the corresponding environment-specific file will also be loaded and merged with the .env file. For example, if you want to set different environment variables for the staging environment, you can create a file named .env.staging: API_TOKEN="staging-token" When you run wrangler dev --env staging or CLOUDFLARE_ENV=staging vite dev, the environment variables from .env.staging will be merged onto those from .env. export default { async fetch(request, env) { const title = env.TITLE; // "My Worker" (from `.env`) const apiToken = env.API_TOKEN; // "staging-token" (from `.env.staging`, overriding the value from `.env`) const response = await fetch( `https://api.example.com/data?token=${apiToken}`, ); return new Response(`Title: ${title} - ` + (await response.text())); }, }; Find out more For more information on how to use .env files with Wrangler and the Cloudflare Vite plugin, see the following documentation: Environment variables and secrets Wrangler Documentation Cloudflare Vite Plugin Documentation

2025/8/8
articleCard.readMore

Stream - Introducing observability and metrics for Stream Live Inputs

New information about broadcast metrics and events is now available in Cloudflare Stream in the Live Input details of the Dashboard. You can now easily understand broadcast-side health and performance with new observability, which can help when troubleshooting common issues, particularly for new customers who are just getting started, and platform customers who may have limited visibility into how their end-users configure their encoders. To get started, start a live stream (just getting started?), then visit the Live Input details page in Dash. See our new live Troubleshooting guide to learn what these metrics mean and how to use them to address common broadcast issues.

2025/8/8
articleCard.readMore

Workers - Directly import `waitUntil` in Workers for easily spawning background tasks

You can now import waitUntil from cloudflare:workers to extend your Worker's execution beyond the request lifecycle from anywhere in your code. Previously, waitUntil could only be accessed through the execution context (ctx) parameter passed to your Worker's handler functions. This meant that if you needed to schedule background tasks from deeply nested functions or utility modules, you had to pass the ctx object through multiple function calls to access waitUntil. Now, you can import waitUntil directly and use it anywhere in your Worker without needing to pass ctx as a parameter: import { waitUntil } from "cloudflare:workers"; export function trackAnalytics(eventData) { const analyticsPromise = fetch("https://analytics.example.com/track", { method: "POST", body: JSON.stringify(eventData), }); // Extend execution to ensure analytics tracking completes waitUntil(analyticsPromise); } This is particularly useful when you want to: Schedule background tasks from utility functions or modules Extend execution for analytics, logging, or cleanup operations Avoid passing the execution context through multiple layers of function calls import { waitUntil } from "cloudflare:workers"; export default { async fetch(request, env, ctx) { // Background task that should complete even after response is sent cleanupTempData(env.KV_NAMESPACE); return new Response("Hello, World!"); } }; function cleanupTempData(kvNamespace) { // This function can now use waitUntil without needing ctx const deletePromise = kvNamespace.delete("temp-key"); waitUntil(deletePromise); } Note The imported waitUntil function works the same way as ctx.waitUntil(). It extends your Worker's execution to wait for the provided promise to settle, but does not block the response from being sent to the client. For more information, see the waitUntil documentation.

2025/8/8
articleCard.readMore

Workers - Requests made from Cloudflare Workers can now force a revalidation of their cache with the origin

By setting the value of the cache property to no-cache, you can force Cloudflare's cache to revalidate its contents with the origin when making subrequests from Cloudflare Workers. JavaScript export default { async fetch(req, env, ctx) { const request = new Request("https://cloudflare.com", { cache: "no-cache", }); const response = await fetch(request); return response; }, }; TypeScript export default { async fetch(req, env, ctx): Promise<Response> { const request = new Request("https://cloudflare.com", { cache: 'no-cache'}); const response = await fetch(request); return response; } } satisfies ExportedHandler<Environment> When no-cache is set, the Worker request will first look for a match in Cloudflare's cache, then: If there is a match, a conditional request is sent to the origin, regardless of whether or not the match is fresh or stale. If the resource has not changed, the cached version is returned. If the resource has changed, it will be downloaded from the origin, updated in the cache, and returned. If there is no match, Workers will make a standard request to the origin and cache the response. This increases compatibility with NPM packages and JavaScript frameworks that rely on setting the cache property, which is a cross-platform standard part of the Request interface. Previously, if you set the cache property on Request to 'no-cache', the Workers runtime threw an exception. Learn how the Cache works with Cloudflare Workers Enable Node.js compatibility for your Cloudflare Worker Explore Runtime APIs and Bindings available in Cloudflare Workers

2025/8/7
articleCard.readMore

Agents, Workers - Agents SDK adds MCP Elicitation support, http-streamable suppport, task queues, email integration and more

The latest releases of @cloudflare/agents brings major improvements to MCP transport protocols support and agents connectivity. Key updates include: MCP elicitation support MCP servers can now request user input during tool execution, enabling interactive workflows like confirmations, forms, and multi-step processes. This feature uses durable storage to preserve elicitation state even during agent hibernation, ensuring seamless user interactions across agent lifecycle events. // Request user confirmation via elicitation const confirmation = await this.elicitInput({ message: `Are you sure you want to increment the counter by ${amount}?`, requestedSchema: { type: "object", properties: { confirmed: { type: "boolean", title: "Confirm increment", description: "Check to confirm the increment", }, }, required: ["confirmed"], }, }); Check out our demo to see elicitation in action. HTTP streamable transport for MCP MCP now supports HTTP streamable transport which is recommended over SSE. This transport type offers: Better performance: More efficient data streaming and reduced overhead Improved reliability: Enhanced connection stability and error recover- Automatic fallback: If streamable transport is not available, it gracefully falls back to SSE export default MyMCP.serve("/mcp", { binding: "MyMCP", }); The SDK automatically selects the best available transport method, gracefully falling back from streamable-http to SSE when needed. Enhanced MCP connectivity Significant improvements to MCP server connections and transport reliability: Auto transport selection: Automatically determines the best transport method, falling back from streamable-http to SSE as needed Improved error handling: Better connection state management and error reporting for MCP servers Reliable prop updates: Centralized agent property updates ensure consistency across different contexts Lightweight .queue for fast task deferral You can use .queue() to enqueue background work — ideal for tasks like processing user messages, sending notifications etc. class MyAgent extends Agent { doSomethingExpensive(payload) { // a long running process that you want to run in the background } queueSomething() { await this.queue("doSomethingExpensive", somePayload); // this will NOT block further execution, and runs in the background await this.queue("doSomethingExpensive", someOtherPayload); // the callback will NOT run until the previous callback is complete // ... call as many times as you want } } Want to try it yourself? Just define a method like processMessage in your agent, and you’re ready to scale. New email adapter Want to build an AI agent that can receive and respond to emails automatically? With the new email adapter and onEmail lifecycle method, now you can. export class EmailAgent extends Agent { async onEmail(email: AgentEmail) { const raw = await email.getRaw(); const parsed = await PostalMime.parse(raw); // create a response based on the email contents // and then send a reply await this.replyToEmail(email, { fromName: "Email Agent", body: `Thanks for your email! You've sent us "${parsed.subject}". We'll process it shortly.`, }); } } You route incoming mail like this: export default { async email(email, env) { await routeAgentEmail(email, env, { resolver: createAddressBasedEmailResolver("EmailAgent"), }); }, }; You can find a full example here. Automatic context wrapping for custom methods Custom methods are now automatically wrapped with the agent's context, so calling getCurrentAgent() should work regardless of where in an agent's lifecycle it's called. Previously this would not work on RPC calls, but now just works out of the box. export class MyAgent extends Agent { async suggestReply(message) { // getCurrentAgent() now correctly works, even when called inside an RPC method const { agent } = getCurrentAgent()!; return generateText({ prompt: `Suggest a reply to: "${message}" from "${agent.name}"`, tools: [replyWithEmoji], }); } } Try it out and tell us what you build!

2025/8/5
articleCard.readMore

Agents, Workers - Cloudflare Sandbox SDK adds streaming, code interpreter, Git support, process control and more

We’ve shipped a major release for the @cloudflare/sandbox SDK, turning it into a full-featured, container-based execution platform that runs securely on Cloudflare Workers. This update adds live streaming of output, persistent Python and JavaScript code interpreters with rich output support (charts, tables, HTML, JSON), file system access, Git operations, full background process control, and the ability to expose running services via public URLs. This makes it ideal for building AI agents, CI runners, cloud REPLs, data analysis pipelines, or full developer tools — all without managing infrastructure. Code interpreter (Python, JS, TS) Create persistent code contexts with support for rich visual + structured outputs. createCodeContext(options) Creates a new code execution context with persistent state. // Create a Python context const pythonCtx = await sandbox.createCodeContext({ language: "python" }); // Create a JavaScript context const jsCtx = await sandbox.createCodeContext({ language: "javascript" }); Options: language: Programming language ('python' | 'javascript' | 'typescript') cwd: Working directory (default: /workspace) envVars: Environment variables for the context runCode(code, options) Executes code with optional streaming callbacks. // Simple execution const execution = await sandbox.runCode('print("Hello World")', { context: pythonCtx, }); // With streaming callbacks await sandbox.runCode( ` for i in range(5): print(f"Step {i}") time.sleep(1) `, { context: pythonCtx, onStdout: (output) => console.log("Real-time:", output.text), onResult: (result) => console.log("Result:", result), }, ); Options: language: Programming language ('python' | 'javascript' | 'typescript') cwd: Working directory (default: /workspace) envVars: Environment variables for the context Real-time streaming output Returns a streaming response for real-time processing. const stream = await sandbox.runCodeStream( "import time; [print(i) for i in range(10)]", ); // Process the stream as needed Rich output handling Interpreter outputs are auto-formatted and returned in multiple formats: text html (e.g., Pandas tables) png, svg (e.g., Matplotlib charts) json (structured data) chart (parsed visualizations) const result = await sandbox.runCode( ` import seaborn as sns import matplotlib.pyplot as plt data = sns.load_dataset("flights") pivot = data.pivot("month", "year", "passengers") sns.heatmap(pivot, annot=True, fmt="d") plt.title("Flight Passengers") plt.show() pivot.to_dict() `, { context: pythonCtx }, ); if (result.png) { console.log("Chart output:", result.png); } Preview URLs from Exposed Ports Start background processes and expose them with live URLs. await sandbox.startProcess("python -m http.server 8000"); const preview = await sandbox.exposePort(8000); console.log("Live preview at:", preview.url); Full process lifecycle control Start, inspect, and terminate long-running background processes. const process = await sandbox.startProcess("node server.js"); console.log(`Started process ${process.id} with PID ${process.pid}`); // Monitor the process const logStream = await sandbox.streamProcessLogs(process.id); for await (const log of parseSSEStream<LogEvent>(logStream)) { console.log(`Server: ${log.data}`); } listProcesses() - List all running processes getProcess(id) - Get detailed process status killProcess(id, signal) - Terminate specific processes killAllProcesses() - Kill all processes streamProcessLogs(id, options) - Stream logs from running processes getProcessLogs(id) - Get accumulated process output Git integration Clone Git repositories directly into the sandbox. await sandbox.gitCheckout("https://github.com/user/repo", { branch: "main", targetDir: "my-project", }); Sandboxes are still experimental. We're using them to explore how isolated, container-like workloads might scale on Cloudflare — and to help define the developer experience around them.

2025/8/5
articleCard.readMore

Agents, Workers AI - OpenAI open models now available on Workers AI

We're thrilled to be a Day 0 partner with OpenAI to bring their latest open models to Workers AI, including support for Responses API, Code Interpreter, and Web Search (coming soon). Get started with the new models at @cf/openai/gpt-oss-120b and @cf/openai/gpt-oss-20b. Check out the blog for more details about the new models, and the gpt-oss-120b and gpt-oss-20b model pages for more information about pricing and context windows. Responses API If you call the model through: Workers Binding, it will accept/return Responses API – env.AI.run(“@cf/openai/gpt-oss-120b”) REST API on /run endpoint, it will accept/return Responses API – https://api.cloudflare.com/client/v4/accounts/<account_id>/ai/run/@cf/openai/gpt-oss-120b REST API on new /responses endpoint, it will accept/return Responses API – https://api.cloudflare.com/client/v4/accounts/<account_id>/ai/v1/responses REST API for OpenAI Compatible endpoint, it will return Chat Completions (coming soon) – https://api.cloudflare.com/client/v4/accounts/<account_id>/ai/v1/chat/completions curl https://api.cloudflare.com/client/v4/accounts/<account_id>/ai/v1/responses \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $CLOUDFLARE_API_KEY" \ -d '{ "model": "@cf/openai/gpt-oss-120b", "reasoning": {"effort": "medium"}, "input": [ { "role": "user", "content": "What are the benefits of open-source models?" } ] }' Code Interpreter The model is natively trained to support stateful code execution, and we've implemented support for this feature using our Sandbox SDK and Containers. Cloudflare's Developer Platform is uniquely positioned to support this feature, so we're very excited to bring our products together to support this new use case. Web Search (coming soon) We are working to implement Web Search for the model, where users can bring their own Exa API Key so the model can browse the Internet.

2025/8/5
articleCard.readMore

Workers - Increased disk space for Workers Builds

As part of the ongoing open beta for Workers Builds, we’ve increased the available disk space for builds from 8 GB to 20 GB for both Free and Paid plans. This provides more space for larger projects, dependencies, and build artifacts while improving overall build reliability. MetricFree PlanPaid Plans Disk Space20 GB20 GB All other build limits — including CPU, memory, build minutes, and timeout remain unchanged.

2025/8/4
articleCard.readMore

Workers - Develop locally with Containers and the Cloudflare Vite plugin

You can now configure and run Containers alongside your Worker during local development when using the Cloudflare Vite plugin. Previously, you could only develop locally when using Wrangler as your local development server. Configuration You can simply configure your Worker and your Container(s) in your Wrangler configuration file: wrangler.jsonc { "name": "container-starter", "main": "src/index.js", "containers": [ { "class_name": "MyContainer", "image": "./Dockerfile", "instances": 5 } ], "durable_objects": { "bindings": [ { "class_name": "MyContainer", "name": "MY_CONTAINER" } ] }, "migrations": [ { "new_sqlite_classes": [ "MyContainer" ], "tag": "v1" } ], } wrangler.toml name = "container-starter" main = "src/index.js" [[containers]] class_name = "MyContainer" image = "./Dockerfile" instances = 5 [[durable_objects.bindings]] class_name = "MyContainer" name = "MY_CONTAINER" [[migrations]] new_sqlite_classes = [ "MyContainer" ] tag = "v1" Worker Code Once your Worker and Containers are configured, you can access the Container instances from your Worker code: import { Container, getContainer } from "@cloudflare/containers"; export class MyContainer extends Container { defaultPort = 4000; // Port the container is listening on sleepAfter = "10m"; // Stop the instance if requests not sent for 10 minutes } async fetch(request, env) { const { "session-id": sessionId } = await request.json(); // Get the container instance for the given session ID const containerInstance = getContainer(env.MY_CONTAINER, sessionId) // Pass the request to the container instance on its default port return containerInstance.fetch(request); } Local development To develop your Worker locally, start a local dev server by running vite dev in your terminal. Resources Learn more about Cloudflare Containers or the Cloudflare Vite plugin in our developer docs.

2025/8/1
articleCard.readMore

Workers, Secrets Store - Deploy to Cloudflare buttons now support Worker environment variables, secrets, and Secrets Store secrets

Any template which uses Worker environment variables, secrets, or Secrets Store secrets can now be deployed using a Deploy to Cloudflare button. Define environment variables and secrets store bindings in your Wrangler configuration file as normal: wrangler.jsonc { "name": "my-worker", "main": "./src/index.ts", "compatibility_date": "2025-10-16", "vars": { "API_HOST": "https://example.com", }, "secrets_store_secrets": [ { "binding": "API_KEY", "store_id": "demo", "secret_name": "api-key" } ] } wrangler.toml name = "my-worker" main = "./src/index.ts" compatibility_date = "2025-10-16" [vars] API_HOST = "https://example.com" [[secrets_store_secrets]] binding = "API_KEY" store_id = "demo" secret_name = "api-key" Add secrets to a .dev.vars.example or .env.example file: COOKIE_SIGNING_KEY=my-secret # comment And optionally, you can add a description for these bindings in your template's package.json to help users understand how to configure each value: { "name": "my-worker", "private": true, "cloudflare": { "bindings": { "API_KEY": { "description": "Select your company's API key for connecting to the example service." }, "COOKIE_SIGNING_KEY": { "description": "Generate a random string using `openssl rand -hex 32`." } } } } These secrets and environment variables will be presented to users in the dashboard as they deploy this template, allowing them to configure each value. Additional information about creating templates and Deploy to Cloudflare buttons can be found in our documentation.

2025/7/29
articleCard.readMore

Browser Rendering - Introducing pricing for the Browser Rendering API — $0.09 per browser hour

We’ve launched pricing for Browser Rendering, including a free tier and a pay-as-you-go model that scales with your needs. Starting August 20, 2025, Cloudflare will begin billing for Browser Rendering. There are two ways to use Browser Rendering. Depending on the method you use, here’s how billing will work: REST API: Charged for Duration only ($/browser hour) Workers Bindings: Charged for both Duration and Concurrency ($/browser hour and # of concurrent browsers) Included usage and pricing by plan PlanIncluded durationIncluded concurrencyPrice (beyond included) Workers Free10 minutes per day3 concurrent browsersN/A Workers Paid10 hours per month10 concurrent browsers (averaged monthly)1. REST API: $0.09 per additional browser hour 2. Workers Bindings: $0.09 per additional browser hour $2.00 per additional concurrent browser What you need to know: Workers Free Plan: 10 minutes of browser usage per day with 3 concurrent browsers at no charge. Workers Paid Plan: 10 hours of browser usage per month with 10 concurrent browsers (averaged monthly) at no charge. Additional usage is charged as shown above. You can monitor usage via the Cloudflare dashboard. Go to Compute (Workers) > Browser Rendering. If you've been using Browser Rendering and do not wish to incur charges, ensure your usage stays within your plan's included usage. To estimate costs, take a look at these example pricing scenarios.

2025/7/28
articleCard.readMore

Browser Rendering - Browser Rendering now supports local development

You can now run your Browser Rendering locally using npx wrangler dev, which spins up a browser directly on your machine before deploying to Cloudflare's global network. By running tests locally, you can quickly develop, debug, and test changes without needing to deploy or worry about usage costs. Get started with this example guide that shows how to use Cloudflare's fork of Puppeteer (you can also use Playwright) to take screenshots of webpages and store the results in Workers KV.

2025/7/22
articleCard.readMore

Workers - Test out code changes before shipping with per-branch preview deployments for Cloudflare Workers

Now, when you connect your Cloudflare Worker to a git repository on GitHub or GitLab, each branch of your repository has its own stable preview URL, that you can use to preview code changes before merging the pull request and deploying to production. This works the same way that Cloudflare Pages does — every time you create a pull request, you'll automatically get a shareable preview link where you can see your changes running, without affecting production. The link stays the same, even as you add commits to the same branch. These preview URLs are named after your branch and are posted as a comment to each pull request. The URL stays the same with every commit and always points to the latest version of that branch. Preview URL types Each comment includes two preview URLs as shown above: Commit Preview URL: Unique to the specific version/commit (e.g., <version-prefix>-<worker-name>.<subdomain>.workers.dev) Branch Preview URL: A stable alias based on the branch name (e.g., <branch-name>-<worker-name>.<subdomain>.workers.dev) How it works When you create a pull request: A preview alias is automatically created based on the Git branch name (e.g., <branch-name> becomes <branch-name>-<worker-name>.<subdomain>.workers.dev) No configuration is needed, the alias is generated for you The link stays the same even as you add commits to the same branch Preview URLs are posted directly to your pull request as comments (just like they are in Cloudflare Pages) Custom alias name You can also assign a custom preview alias using the Wrangler CLI, by passing the --preview-alias flag when uploading a version of your Worker: wrangler versions upload --preview-alias staging Limitations while in beta Only available on the workers.dev subdomain (custom domains not yet supported) Requires Wrangler v4.21.0+ Preview URLs are not generated for Workers that use Durable Objects Not yet supported for Workers for Platforms

2025/7/22
articleCard.readMore

Stream - Audio mode for Media Transformations

We now support audio mode! Use this feature to extract audio from a source video, outputting an M4A file to use in downstream workflows like AI inference, content moderation, or transcription. For example, https://example.com/cdn-cgi/media/<OPTIONS>/<SOURCE-VIDEO> https://example.com/cdn-cgi/media/mode=audio,time=3s,duration=60s/<input video with diction> For more information, learn about Transforming Videos.

2025/7/22
articleCard.readMore

Email Routing - Subaddressing support in Email Routing

Subaddressing, as defined in RFC 5233, also known as plus addressing, is now supported in Email Routing. This enables using the "+" separator to augment your custom addresses with arbitrary detail information. Now you can send an email to user+detail@example.com and it will be captured by the user@example.com custom address. The +detail part is ignored by Email Routing, but it can be captured next in the processing chain in the logs, an Email Worker or an Agent application. Customers can use this feature to dynamically add context to their emails, such as tracking the source of an email or categorizing emails without needing to create multiple custom addresses. Check our Developer Docs to learn on to enable subaddressing in Email Routing.

2025/7/21
articleCard.readMore

Workers - The Cloudflare Vite plugin now supports Vite 7

Vite 7 is now supported in the Cloudflare Vite plugin. See the Vite changelog for a list of changes. Note that the minimum Node.js versions supported by Vite 7 are 20.19 and 22.12. We continue to support Vite 6 so you do not need to immediately upgrade.

2025/7/17
articleCard.readMore

AI Search - Faster indexing and new Jobs view in AutoRAG

You can now expect 3-5× faster indexing in AutoRAG, and with it, a brand new Jobs view to help you monitor indexing progress. With each AutoRAG, indexing jobs are automatically triggered to sync your data source (i.e. R2 bucket) with your Vectorize index, ensuring new or updated files are reflected in your query results. You can also trigger jobs manually via the Sync API or by clicking “Sync index” in the dashboard. With the new jobs observability, you can now: View the status, job ID, source, start time, duration and last sync time for each indexing job Inspect real-time logs of job events (e.g. Starting indexing data source...) See a history of past indexing jobs under the Jobs tab of your AutoRAG This makes it easier to understand what’s happening behind the scenes. Coming soon: We’re adding APIs to programmatically check indexing status, making it even easier to integrate AutoRAG into your workflows. Try it out today on the Cloudflare dashboard.

2025/7/8
articleCard.readMore

Cloudflare Images - HEIC support in Cloudflare Images

You can use Images to ingest HEIC images and serve them in supported output formats like AVIF, WebP, JPEG, and PNG. When inputting a HEIC image, dimension and sizing limits may still apply. Refer to our documentation to see limits for uploading to Images or transforming a remote image.

2025/7/8
articleCard.readMore

Workers - Workers now supports JavaScript debug terminals in VSCode, Cursor and Windsurf IDEs

Workers now support breakpoint debugging using VSCode's built-in JavaScript Debug Terminals. All you have to do is open a JS debug terminal (Cmd + Shift + P and then type javascript debug) and run wrangler dev (or vite dev) from within the debug terminal. VSCode will automatically connect to your running Worker (even if you're running multiple Workers at once!) and start a debugging session. In 2023 we announced breakpoint debugging support for Workers, which meant that you could easily debug your Worker code in Wrangler's built-in devtools (accessible via the [d] hotkey) as well as multiple other devtools clients, including VSCode. For most developers, breakpoint debugging via VSCode is the most natural flow, but until now it's required manually configuring a launch.json file, running wrangler dev, and connecting via VSCode's built-in debugger. Now it's much more seamless!

2025/7/4
articleCard.readMore

Hyperdrive - Hyperdrive now supports configuring the amount of database connections

You can now specify the number of connections your Hyperdrive configuration uses to connect to your origin database. All configurations have a minimum of 5 connections. The maximum connection count for a Hyperdrive configuration depends on the Hyperdrive limits of your Workers plan. This feature allows you to right-size your connection pool based on your database capacity and application requirements. You can configure connection counts through the Cloudflare dashboard or API. Refer to the Hyperdrive configuration documentation for more information.

2025/7/3
articleCard.readMore

Workers - Enhanced support for static assets with the Cloudflare Vite plugin

You can now use any of Vite's static asset handling features in your Worker as well as in your frontend. These include importing assets as URLs, importing as strings and importing from the public directory as well as inlining assets. Additionally, assets imported as URLs in your Worker are now automatically moved to the client build output. Here is an example that fetches an imported asset using the assets binding and modifies the response. // Import the asset URL // This returns the resolved path in development and production import myImage from "./my-image.png"; export default { async fetch(request, env) { // Fetch the asset using the binding const response = await env.ASSETS.fetch(new URL(myImage, request.url)); // Create a new `Response` object that can be modified const modifiedResponse = new Response(response.body, response); // Add an additional header modifiedResponse.headers.append("my-header", "imported-asset"); // Return the modfied response return modifiedResponse; }, }; Refer to Static Assets in the Cloudflare Vite plugin docs for more info.

2025/7/1
articleCard.readMore

Email Routing - Mail authentication requirements for Email Routing

The Email Routing platform supports SPF records and DKIM (DomainKeys Identified Mail) signatures and honors these protocols when the sending domain has them configured. However, if the sending domain doesn't implement them, we still forward the emails to upstream mailbox providers. Starting on July 3, 2025, we will require all emails to be authenticated using at least one of the protocols, SPF or DKIM, to forward them. We also strongly recommend that all senders implement the DMARC protocol. If you are using a Worker with an Email trigger to receive email messages and forward them upstream, you will need to handle the case where the forward action may fail due to missing authentication on the incoming email. SPAM has been a long-standing issue with email. By enforcing mail authentication, we will increase the efficiency of identifying abusive senders and blocking bad emails. If you're an email server delivering emails to large mailbox providers, it's likely you already use these protocols; otherwise, please ensure you have them properly configured.

2025/6/30
articleCard.readMore

Workers - Remote bindings (beta) now works with Next.js — connect to remote resources (D1, KV, R2, etc.) during local development

We recently announced our public beta for remote bindings, which allow you to connect to deployed resources running on your Cloudflare account (like R2 buckets or D1 databases) while running a local development session. Now, you can use remote bindings with your Next.js applications through the @opennextjs/cloudflare adaptor by enabling the experimental feature in your next.config.ts: initOpenNextCloudflareForDev(); initOpenNextCloudflareForDev({ experimental: { remoteBindings: true } }); Then, all you have to do is specify which bindings you want connected to the deployed resource on your Cloudflare account via the experimental_remote flag in your binding definition: wrangler.jsonc { "r2_buckets": [ { "bucket_name": "testing-bucket", "binding": "MY_BUCKET", "experimental_remote": true, }, ], } wrangler.toml [[r2_buckets]] bucket_name = "testing-bucket" binding = "MY_BUCKET" experimental_remote = true You can then run next dev to start a local development session (or start a preview with opennextjs-cloudflare preview), and all requests to env.MY_BUCKET will be proxied to the remote testing-bucket — rather than the default local binding simulations. Remote bindings & ISR Remote bindings are also used during the build process, which comes with significant benefits for pages using Incremental Static Regeneration (ISR). During the build step for an ISR page, your server executes the page's code just as it would for normal user requests. If a page needs data to display (like fetching user info from KV), those requests are actually made. The server then uses this fetched data to render the final HTML. Data fetching is a critical part of this process, as the finished HTML is only as good as the data it was built with. If the build process can't fetch real data, you end up with a pre-rendered page that's empty or incomplete. With remote bindings support in OpenNext, your pre-rendered pages are built with real data from the start. The build process uses any configured remote bindings, and any data fetching occurs against the deployed resources on your Cloudflare account. Want to learn more? Get started with remote bindings and OpenNext. Have feedback? Join the discussion in our beta announcement to share feedback or report any issues.

2025/6/30
articleCard.readMore

Workers - Run and connect Workers in separate dev commands with the Cloudflare Vite plugin

Workers can now talk to each other across separate dev commands using service bindings and tail consumers, whether started with vite dev or wrangler dev. Simply start each Worker in its own terminal: # Terminal 1 vite dev # Terminal 2 wrangler dev This is useful when different teams maintain different Workers, or when each Worker has its own build setup or tooling. Check out the Developing with multiple Workers guide to learn more about the different approaches and when to use each one.

2025/6/26
articleCard.readMore

Agents, Workers, Workflows - Run AI-generated code on-demand with Code Sandboxes (new)

AI is supercharging app development for everyone, but we need a safe way to run untrusted, LLM-written code. We’re introducing Sandboxes, which let your Worker run actual processes in a secure, container-based environment. import { getSandbox } from "@cloudflare/sandbox"; export { Sandbox } from "@cloudflare/sandbox"; export default { async fetch(request: Request, env: Env) { const sandbox = getSandbox(env.Sandbox, "my-sandbox"); return sandbox.exec("ls", ["-la"]); }, }; Methods exec(command: string, args: string[], options?: { stream?: boolean }):Execute a command in the sandbox. gitCheckout(repoUrl: string, options: { branch?: string; targetDir?: string; stream?: boolean }): Checkout a git repository in the sandbox. mkdir(path: string, options: { recursive?: boolean; stream?: boolean }): Create a directory in the sandbox. writeFile(path: string, content: string, options: { encoding?: string; stream?: boolean }): Write content to a file in the sandbox. readFile(path: string, options: { encoding?: string; stream?: boolean }): Read content from a file in the sandbox. deleteFile(path: string, options?: { stream?: boolean }): Delete a file from the sandbox. renameFile(oldPath: string, newPath: string, options?: { stream?: boolean }): Rename a file in the sandbox. moveFile(sourcePath: string, destinationPath: string, options?: { stream?: boolean }): Move a file from one location to another in the sandbox. ping(): Ping the sandbox. Sandboxes are still experimental. We're using them to explore how isolated, container-like workloads might scale on Cloudflare — and to help define the developer experience around them. You can try it today from your Worker, with just a few lines of code. Let us know what you build.

2025/6/25
articleCard.readMore

Durable Objects, Workers - @cloudflare/actors library - SDK for Durable Objects in beta

The new @cloudflare/actors library is now in beta! The @cloudflare/actors library is a new SDK for Durable Objects and provides a powerful set of abstractions for building real-time, interactive, and multiplayer applications on top of Durable Objects. With beta usage and feedback, @cloudflare/actors will become the recommended way to build on Durable Objects and draws upon Cloudflare's experience building products/features on Durable Objects. The name "actors" originates from the actor programming model, which closely ties to how Durable Objects are modelled. The @cloudflare/actors library includes: Storage helpers for querying embeddeded, per-object SQLite storage Storage helpers for managing SQL schema migrations Alarm helpers for scheduling multiple alarms provided a date, delay in seconds, or cron expression Actor class for using Durable Objects with a defined pattern Durable Objects Workers API is always available for your application as needed Storage and alarm helper methods can be combined with any Javascript class that defines your Durable Object, i.e, ones that extend DurableObject including the Actor class. import { Storage } from "@cloudflare/actors/storage"; export class ChatRoom extends DurableObject<Env> { storage: Storage; constructor(ctx: DurableObjectState, env: Env) { super(ctx, env) this.storage = new Storage(ctx.storage); this.storage.migrations = [{ idMonotonicInc: 1, description: "Create users table", sql: "CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY)" }] } async fetch(request: Request): Promise<Response> { // Run migrations before executing SQL query await this.storage.runMigrations(); // Query with SQL template let userId = new URL(request.url).searchParams.get("userId"); const query = this.storage.sql`SELECT * FROM users WHERE id = ${userId};` return new Response(`${JSON.stringify(query)}`); } } @cloudflare/actors library introduces the Actor class pattern. Actor lets you access Durable Objects without writing the Worker that communicates with your Durable Object (the Worker is created for you). By default, requests are routed to a Durable Object named "default". export class MyActor extends Actor<Env> { async fetch(request: Request): Promise<Response> { return new Response('Hello, World!') } } export default handler(MyActor); You can route to different Durable Objects by name within your Actor class using nameFromRequest. export class MyActor extends Actor<Env> { static nameFromRequest(request: Request): string { let url = new URL(request.url); return url.searchParams.get("userId") ?? "foo"; } async fetch(request: Request): Promise<Response> { return new Response(`Actor identifier (Durable Object name): ${this.identifier}`); } } export default handler(MyActor); For more examples, check out the library README. @cloudflare/actors library is a place for more helpers and built-in patterns, like retry handling and Websocket-based applications, to reduce development overhead for common Durable Objects functionality. Please share feedback and what more you would like to see on our Discord channel.

2025/6/25
articleCard.readMore

Workers - Increased blob size limits in Workers Analytics Engine

We’ve increased the total allowed size of blob fields on data points written to Workers Analytics Engine from 5 KB to 16 KB. This change gives you more flexibility when logging rich observability data — such as base64-encoded payloads, AI inference traces, or custom metadata — without hitting request size limits. You can find full details on limits for queries, filters, payloads, and more here in the Workers Analytics Engine limits documentation. JavaScript export default { async fetch(request, env) { env.analyticsDataset.writeDataPoint({ // The sum of all of the blob's sizes can now be 16 KB blobs: [ // The URL of the request to the Worker request.url, // Some metadata about your application you'd like to store JSON.stringify(metadata), // The version of your Worker this datapoint was collected from env.versionMetadata.tag, ], indexes: ["sample-index"], }); }, }; TypeScript export default { async fetch(request, env) { env.analyticsDataset.writeDataPoint({ // The sum of all of the blob's sizes can now be 16 KB blobs: [ // The URL of the request to the Worker request.url, // Some metadata about your application you'd like to store JSON.stringify(metadata), // The version of your Worker this datapoint was collected from env.versionMetadata.tag, ], indexes: ["sample-index"], }); } };

2025/6/20
articleCard.readMore

AI Search - View custom metadata in responses and guide AI-search with context in AutoRAG

In AutoRAG, you can now view your object's custom metadata in the response from /search and /ai-search, and optionally add a context field in the custom metadata of an object to provide additional guidance for AI-generated answers. You can add custom metadata to an object when uploading it to your R2 bucket. Object's custom metadata in search responses When you run a search, AutoRAG now returns any custom metadata associated with the object. This metadata appears in the response inside attributes then file , and can be used for downstream processing. For example, the attributes section of your search response may look like: { "attributes": { "timestamp": 1750001460000, "folder": "docs/", "filename": "launch-checklist.md", "file": { "url": "https://wiki.company.com/docs/launch-checklist", "context": "A checklist for internal launch readiness, including legal, engineering, and marketing steps." } } } Add a context field to guide LLM answers When you include a custom metadata field named context, AutoRAG attaches that value to each chunk of the file. When you run an /ai-search query, this context is passed to the LLM and can be used as additional input when generating an answer. We recommend using the context field to describe supplemental information you want the LLM to consider, such as a summary of the document or a source URL. If you have several different metadata attributes, you can join them together however you choose within the context string. For example: { "context": "summary: 'Checklist for internal product launch readiness, including legal, engineering, and marketing steps.'; url: 'https://wiki.company.com/docs/launch-checklist'" } This gives you more control over how your content is interpreted, without requiring you to modify the original contents of the file. Learn more in AutoRAG's metadata filtering documentation.

2025/6/19
articleCard.readMore

AI Search - Filter your AutoRAG search by file name

In AutoRAG, you can now filter by an object's file name using the filename attribute, giving you more control over which files are searched for a given query. This is useful when your application has already determined which files should be searched. For example, you might query a PostgreSQL database to get a list of files a user has access to based on their permissions, and then use that list to limit what AutoRAG retrieves. For example, your search query may look like: const response = await env.AI.autorag("my-autorag").search({ query: "what is the project deadline?", filters: { type: "eq", key: "filename", value: "project-alpha-roadmap.md", }, }); This allows you to connect your application logic with AutoRAG's retrieval process, making it easy to control what gets searched without needing to reindex or modify your data. Learn more in AutoRAG's metadata filtering documentation.

2025/6/19
articleCard.readMore

D1, Workers, Workers for Platforms - Automate Worker deployments with a simplified SDK and more reliable Terraform provider

Simplified Worker Deployments with our SDKs We've simplified the programmatic deployment of Workers via our Cloudflare SDKs. This update abstracts away the low-level complexities of the multipart/form-data upload process, allowing you to focus on your code while we handle the deployment mechanics. This new interface is available in: cloudflare-typescript (4.4.1) cloudflare-python (4.3.1) For complete examples, see our guide on programmatic Worker deployments. The Old way: Manual API calls Previously, deploying a Worker programmatically required manually constructing a multipart/form-data HTTP request, packaging your code and a separate metadata.json file. This was more complicated and verbose, and prone to formatting errors. For example, here's how you would upload a Worker script previously with cURL: curl https://api.cloudflare.com/client/v4/accounts/<account_id>/workers/scripts/my-hello-world-script \ -X PUT \ -H 'Authorization: Bearer <api_token>' \ -F 'metadata={ "main_module": "my-hello-world-script.mjs", "bindings": [ { "type": "plain_text", "name": "MESSAGE", "text": "Hello World!" } ], "compatibility_date": "$today" };type=application/json' \ -F 'my-hello-world-script.mjs=@-;filename=my-hello-world-script.mjs;type=application/javascript+module' <<EOF export default { async fetch(request, env, ctx) { return new Response(env.MESSAGE, { status: 200 }); } }; EOF After: SDK interface With the new SDK interface, you can now define your entire Worker configuration using a single, structured object. This approach allows you to specify metadata like main_module, bindings, and compatibility_date as clearer properties directly alongside your script content. Our SDK takes this logical object and automatically constructs the complex multipart/form-data API request behind the scenes. Here's how you can now programmatically deploy a Worker via the cloudflare-typescript SDK JavaScript import Cloudflare from "cloudflare"; import { toFile } from "cloudflare/index"; // ... client setup, script content, etc. const script = await client.workers.scripts.update(scriptName, { account_id: accountID, metadata: { main_module: scriptFileName, bindings: [], }, files: { [scriptFileName]: await toFile(Buffer.from(scriptContent), scriptFileName, { type: "application/javascript+module", }), }, }); TypeScript import Cloudflare from 'cloudflare'; import { toFile } from 'cloudflare/index'; // ... client setup, script content, etc. const script = await client.workers.scripts.update(scriptName, { account_id: accountID, metadata: { main_module: scriptFileName, bindings: [], }, files: { [scriptFileName]: await toFile(Buffer.from(scriptContent), scriptFileName, { type: 'application/javascript+module', }), }, }); View the complete example here: https://github.com/cloudflare/cloudflare-typescript/blob/main/examples/workers/script-upload.ts Terraform provider improvements We've also made several fixes and enhancements to the Cloudflare Terraform provider: Fixed the cloudflare_workers_script resource in Terraform, which previously was producing a diff even when there were no changes. Now, your terraform plan outputs will be cleaner and more reliable. Fixed the cloudflare_workers_for_platforms_dispatch_namespace, where the provider would attempt to recreate the namespace on a terraform apply. The resource now correctly reads its remote state, ensuring stability for production environments and CI/CD workflows. The cloudflare_workers_route resource now allows for the script property to be empty, null, or omitted to indicate that pattern should be negated for all scripts (see routes docs). You can now reserve a pattern or temporarily disable a Worker on a route without deleting the route definition itself. Using primary_location_hint in the cloudflare_d1_database resource will no longer always try to recreate. You can now safely change the location hint for a D1 database without causing a destructive operation. API improvements We've also properly documented the Workers Script And Version Settings in our public OpenAPI spec and SDKs.

2025/6/19
articleCard.readMore

Workers - Remote bindings public beta - Connect to remote resources (D1, KV, R2, etc.) during local development

Today we announced the public beta of remote bindings for local development. With remote bindings, you can now connect to deployed resources like R2 buckets and D1 databases while running Worker code on your local machine. This means you can test your local code changes against real data and services, without the overhead of deploying for each iteration. Example configuration To enable remote mode, add "experimental_remote" : true to each binding that you want to rely on a remote resource running on Cloudflare: wrangler.jsonc { "name": "my-worker", "compatibility_date": "2025-10-16", "r2_buckets": [ { "bucket_name": "screenshots-bucket", "binding": "screenshots_bucket", "experimental_remote": true, }, ], } wrangler.toml name = "my-worker" compatibility_date = "2025-10-16" [[r2_buckets]] bucket_name = "screenshots-bucket" binding = "screenshots_bucket" experimental_remote = true When remote bindings are configured, your Worker still executes locally, but all binding calls are proxied to the deployed resource that runs on Cloudflare's network. You can try out remote bindings for local development today with: Wrangler v4.20.3: Use the wrangler dev --x-remote-bindings command. The Cloudflare Vite Plugin: Refer to the documentation for how to enable in your Vite config. The Cloudflare Vitest Plugin: Refer to the documentation for how to enable in your Vitest config. Have feedback? Join the discussion in our beta announcement to share feedback or report any issues.

2025/6/18
articleCard.readMore

Workers - Control which routes invoke your Worker script for Single Page Applications

For those building Single Page Applications (SPAs) on Workers, you can now explicitly define which routes invoke your Worker script in Wrangler configuration. The run_worker_first config option has now been expanded to accept an array of route patterns, allowing you to more granularly specify when your Worker script runs. Configuration example: wrangler.jsonc { "name": "my-spa-worker", "compatibility_date": "2025-10-16", "main": "./src/index.ts", "assets": { "directory": "./dist/", "not_found_handling": "single-page-application", "binding": "ASSETS", "run_worker_first": ["/api/*", "!/api/docs/*"] } } wrangler.toml name = "my-spa-worker" compatibility_date = "2025-10-16" main = "./src/index.ts" [assets] directory = "./dist/" not_found_handling = "single-page-application" binding = "ASSETS" run_worker_first = [ "/api/*", "!/api/docs/*" ] This new routing control was done in partnership with our community and customers who provided great feedback on our public proposal. Thank you to everyone who brought forward use-cases and feedback on the design! Prerequisites To use advanced routing control with run_worker_first, you'll need: Wrangler v4.20.0 and above Cloudflare Vite plugin v1.7.0 and above

2025/6/17
articleCard.readMore

Workers - SSRF vulnerability in @opennextjs/cloudflare proactively mitigated for all Cloudflare customers

Mitigations have been put in place for all existing and future deployments of sites with the Cloudflare adapter for Open Next in response to an identified Server-Side Request Forgery (SSRF) vulnerability in the @opennextjs/cloudflare package. The vulnerability stemmed from an unimplemented feature in the Cloudflare adapter for Open Next, which allowed users to proxy arbitrary remote content via the /_next/image endpoint. This issue allowed attackers to load remote resources from arbitrary hosts under the victim site's domain for any site deployed using the Cloudflare adapter for Open Next. For example: https://victim-site.com/_next/image?url=https://attacker.com. In this example, attacker-controlled content from attacker.com is served through the victim site's domain (victim-site.com), violating the same-origin policy and potentially misleading users or other services. References: https://www.cve.org/cverecord?id=CVE-2025-6087, https://github.com/opennextjs/opennextjs-cloudflare/security/advisories/GHSA-rvpw-p7vw-wj3m Impact SSRF via unrestricted remote URL loading Arbitrary remote content loading Potential internal service exposure or phishing risks through domain abuse Mitigation The following mitigations have been put in place: Server side updates to Cloudflare's platform to restrict the content loaded via the /_next/image endpoint to images. The update automatically mitigates the issue for all existing and any future sites deployed to Cloudflare using the affected version of the Cloudflare adapter for Open Next Root cause fix: Pull request #727 to the Cloudflare adapter for Open Next. The patched version of the adapter has been released as @opennextjs/cloudflare@1.3.0 Package dependency update: Pull request cloudflare/workers-sdk#9608 to create-cloudflare (c3) to use the fixed version of the Cloudflare adapter for Open Next. The patched version of create-cloudflare has been published as create-cloudflare@2.49.3. In addition to the automatic mitigation deployed on Cloudflare's platform, we encourage affected users to upgrade to @opennext/cloudflare v1.3.0 and use the remotePatterns filter in Next config if they need to allow-list external urls with images assets.

2025/6/17
articleCard.readMore

Workers - Grant account members read-only access to the Workers Platform

You can now grant members of your Cloudflare account read-only access to the Workers Platform. The new "Workers Platform (Read-only)" role grants read-only access to all products typically used as part of Cloudflare's Developer Platform, including Workers, Pages, Durable Objects, KV, R2, Zones, Zone Analytics and Page Rules. When Cloudflare introduces new products to the Workers platform, we will add additional read-only permissions to this role. Additionally, the role previously named "Workers Admin" has been renamed to "Workers Platform Admin". This change ensures that the name more accurately reflects the permissions granted — this role has always granted access to more than just Workers — it grants read and write access to the products mentioned above, and similarly, as new products are added to the Workers platform, we will add additional read and write permissions to this role. You can review the updated roles in the developer docs.

2025/6/16
articleCard.readMore

Stream - Increased limits for Media Transformations

We have increased the limits for Media Transformations: Input file size limit is now 100MB (was 40MB) Output video duration limit is now 1 minute (was 30 seconds) Additionally, we have improved caching of the input asset, resulting in fewer requests to origin storage even when transformation options may differ. For more information, learn about Transforming Videos.

2025/6/10
articleCard.readMore

Workers - Access git commit sha and branch name as environment variables in Workers Builds

Workers Builds connects your Worker to a Git repository, and automates building and deploying your code on each pushed change. To make CI/CD pipelines even more flexible, Workers Builds now automatically injects default environment variables into your build process (much like the defaults in Cloudflare Pages projects). You can use these variables to customize your build process based on the deployment context, such as the branch or commit. The following environment variables are injected by default: Environment VariableInjected valueExample use-case CItrueChanging build behavior when run on CI versus locally WORKERS_CI1Changing build behavior when run on Workers Builds versus locally WORKERS_CI_BUILD_UUID<build-uuid-of-current-build>Passing the Build UUID along to custom workflows WORKERS_CI_COMMIT_SHA<sha1-hash-of-current-commit>Passing current commit ID to error reporting, for example, Sentry WORKERS_CI_BRANCH<branch-name-from-push-eventCustomizing build based on branch, for example, disabling debug logging on production You can override these default values and add your own custom environment variables by navigating to your Worker > Settings > Environment variables. Learn more in the Build configuration documentation.

2025/6/10
articleCard.readMore

Workers - Workers native integrations were removed from the Cloudflare dashboard

Workers native integrations were originally launched in May 2023 to connect to popular database and observability providers with your Worker in just a few clicks. We are changing how developers connect Workers to these external services. The Integrations tab in the dashboard has been removed in favor of a more direct, command-line-based approach using Wrangler secrets. What's changed Integrations tab removed: The integrations setup flow is no longer available in the Workers dashboard. Manual secret configuration: New connections should be configured by adding credentials as secrets to your Workers using npx wrangler secret put commands. Impact on existing integrations Existing integrations will continue to work without any changes required. If you have integrations that were previously created through the dashboard, they will remain functional. Updating existing integrations If you'd like to modify your existing integration, you can update the secrets, environment variables, or Tail Workers that were created from the original integration setup. Update secrets: Use npx wrangler secret put <SECRET_NAME> to update credential values. Modify environment variables: Update variables through the dashboard or Wrangler configuration. Dashboard management: Access your Worker's settings in the Cloudflare dashboard to modify connections created by our removed native integrations feature. If you have previously set up an observability integration with Sentry, the following environment variables were set and are still modifiable: BLOCKED_HEADERS: headers to exclude sending to Sentry EXCEPTION_SAMPLING_RATE: number from 0 - 100, where 0 = no events go through to Sentry, and 100 = all events go through to Sentry STATUS_CODES_TO_SAMPLING_RATES: a map of status codes -- like 400 or with wildcards like 4xx -- to sampling rates described above Setting up new database and observability connections For new connections, refer to our step-by-step guides on connecting to popular database and observability providers including: Sentry, Turso, Neon, Supabase, PlanetScale, Upstash, Xata.

2025/6/9
articleCard.readMore

Workers - Performance and size optimization for the Cloudflare adapter for Open Next

With the release of the Cloudflare adapter for Open Next v1.0.0 in May 2025, we already had followups plans to improve performance and size. @opennextjs/cloudflare v1.2 released on June 5, 2025 delivers on these enhancements. By removing babel from the app code and dropping a dependency on @ampproject/toolbox-optimizer, we were able to reduce generated bundle sizes. Additionally, by stopping preloading of all app routes, we were able to improve the cold start time. This means that users will now see a decrease from 14 to 8MiB (2.3 to 1.6MiB gzipped) in generated bundle size for a Next app created via create-next-app, and typically 100ms faster startup times for their medium-sized apps. Users only need to update to the latest version of @opennextjs/cloudflare to automatically benefit from these improvements. Note that we published CVE-2005-6087 for a SSRF vulnerability in the @opennextjs/cloudflare package. The vulnerability has been fixed from @opennextjs/cloudflare v1.3.0 onwards. Please update to any version after this one.

2025/6/6
articleCard.readMore

AI Gateway - AI Gateway adds OpenAI compatible endpoint

Users can now use an OpenAI Compatible endpoint in AI Gateway to easily switch between providers, while keeping the exact same request and response formats. We're launching now with the chat completions endpoint, with the embeddings endpoint coming up next. To get started, use the OpenAI compatible chat completions endpoint URL with your own account id and gateway id and switch between providers by changing the model and apiKey parameters. import OpenAI from "openai"; const client = new OpenAI({ apiKey: "YOUR_PROVIDER_API_KEY", // Provider API key baseURL: "https://gateway.ai.cloudflare.com/v1/{account_id}/{gateway_id}/compat", }); const response = await client.chat.completions.create({ model: "google-ai-studio/gemini-2.0-flash", messages: [{ role: "user", content: "What is Cloudflare?" }], }); console.log(response.choices[0].message.content); Additionally, the OpenAI Compatible endpoint can be combined with our Universal Endpoint to add fallbacks across multiple providers. That means AI Gateway will return every response in the same standardized format, no extra parsing logic required! Learn more in the OpenAI Compatibility documentation.

2025/6/3
articleCard.readMore

Workers - View an architecture diagram of your Worker directly in the Cloudflare dashboard

You can now visualize, explore and modify your Worker’s architecture directly in the Cloudflare dashboard, making it easier to understand how your application connects to Cloudflare resources like D1 databases, Durable Objects, KV namespaces, and more. With this new view, you can easily: Explore existing bindings in a visual, architecture-style diagram Add and manage bindings directly from the same interface Discover the full range of compute, storage, AI, and media resources you can attach to your Workers application. To get started, head to the Cloudflare dashboard and open the Bindings tab of any Workers application.

2025/6/3
articleCard.readMore

Pages - Cloudflare Pages builds now provide Node.js v22 by default

When you use the built-in build system that is part of Cloudflare Pages, the Build Image now includes Node.js v22. Previously, Node.js v18 was provided by default, and Node.js v18 is now end-of-life (EOL). If you are creating a new Pages project, the new V3 build image that includes Node.js v22 will be used by default. If you have an existing Pages project, you can update to the latest build image by navigating to Settings > Build & deployments > Build system version in the Cloudflare dashboard for a specific Pages project. Note that you can always specify a particular version of Node.js or other built-in dependencies by setting an environment variable. For more, refer to the developer docs for Cloudflare Pages builds

2025/5/30
articleCard.readMore

Workers - Debug, profile, and view logs for your Worker in Chrome Devtools — now supported in the Cloudflare Vite plugin

You can now debug, profile, view logs, and analyze memory usage for your Worker using Chrome Devtools when your Worker runs locally using the Cloudflare Vite plugin. Previously, this was only possible if your Worker ran locally using the Wrangler CLI, and now you can do all the same things if your Worker uses Vite. When you run vite, you'll now see a debug URL in your console: VITE v6.3.5 ready in 461 ms ➜ Local: http://localhost:5173/ ➜ Network: use --host to expose ➜ Debug: http://localhost:5173/__debug ➜ press h + enter to show help Open the URL in Chrome, and an instance of Chrome Devtools will open and connect to your Worker running locally. You can then use Chrome Devtools to debug and introspect performance issues. For example, you can navigate to the Performance tab to understand where CPU time is spent in your Worker: For more information on how to get the most out of Chrome Devtools, refer to the following docs: Debug code by setting breakpoints Profile CPU usage Observe memory usage and debug memory leaks

2025/5/30
articleCard.readMore

D1, Workers - 50-500ms Faster D1 REST API Requests

Users using Cloudflare's REST API to query their D1 database can see lower end-to-end request latency now that D1 authentication is performed at the closest Cloudflare network data center that received the request. Previously, authentication required D1 REST API requests to proxy to Cloudflare's core, centralized data centers, which added network round trips and latency. Latency improvements range from 50-500 ms depending on request location and database location and only apply to the REST API. REST API requests and databases outside the United States see a bigger benefit since Cloudflare's primary core data centers reside in the United States. D1 query endpoints like /query and /raw have the most noticeable improvements since they no longer access Cloudflare's core data centers. D1 control plane endpoints such as those to create and delete databases see smaller improvements, since they still require access to Cloudflare's core data centers for other control plane metadata.

2025/5/29
articleCard.readMore

Browser Rendering - Playwright MCP server is now compatible with Browser Rendering

We're excited to share that you can now use the Playwright MCP server with Browser Rendering. Once you deploy the server, you can use any MCP client with it to interact with Browser Rendering. This allows you to run AI models that can automate browser tasks, such as taking screenshots, filling out forms, or scraping data. Playwright MCP is available as an npm package at @cloudflare/playwright-mcp. To install it, type: npm npm i -D @cloudflare/playwright-mcp yarn yarn add -D @cloudflare/playwright-mcp pnpm pnpm add -D @cloudflare/playwright-mcp Deploying the server is then as easy as: import { env } from "cloudflare:workers"; import { createMcpAgent } from "@cloudflare/playwright-mcp"; export const PlaywrightMCP = createMcpAgent(env.BROWSER); export default PlaywrightMCP.mount("/sse"); Check out the full code at GitHub. Learn more about Playwright MCP in our documentation.

2025/5/28
articleCard.readMore

Workers - Handle incoming request cancellation in Workers with Request.signal

In Cloudflare Workers, you can now attach an event listener to Request objects, using the signal property. This allows you to perform tasks when the request to your Worker is canceled by the client. To use this feature, you must set the enable_request_signal compatibility flag. You can use a listener to perform cleanup tasks or write to logs before your Worker's invocation ends. For example, if you run the Worker below, and then abort the request from the client, a log will be written: JavaScript export default { async fetch(request, env, ctx) { // This sets up an event listener that will be called if the client disconnects from your // worker. request.signal.addEventListener("abort", () => { console.log("The request was aborted!"); }); const { readable, writable } = new IdentityTransformStream(); sendPing(writable); return new Response(readable, { headers: { "Content-Type": "text/plain" }, }); }, }; async function sendPing(writable) { const writer = writable.getWriter(); const enc = new TextEncoder(); for (;;) { // Send 'ping' every second to keep the connection alive await writer.write(enc.encode("ping\r\n")); await scheduler.wait(1000); } } TypeScript export default { async fetch(request, env, ctx): Promise<Response> { // This sets up an event listener that will be called if the client disconnects from your // worker. request.signal.addEventListener('abort', () => { console.log('The request was aborted!'); }); const { readable, writable } = new IdentityTransformStream(); sendPing(writable); return new Response(readable, { headers: { 'Content-Type': 'text/plain' } }); }, } satisfies ExportedHandler<Env>; async function sendPing(writable: WritableStream): Promise<void> { const writer = writable.getWriter(); const enc = new TextEncoder(); for (;;) { // Send 'ping' every second to keep the connection alive await writer.write(enc.encode('ping\r\n')); await scheduler.wait(1000); } } For more information see the Request documentation.

2025/5/22
articleCard.readMore

Workers, Durable Objects - Durable Objects are now supported in Python Workers

You can now create Durable Objects using Python Workers. A Durable Object is a special kind of Cloudflare Worker which uniquely combines compute with storage, enabling stateful long-running applications which run close to your users. For more info see here. You can define a Durable Object in Python in a similar way to JavaScript: from workers import DurableObject, Response, WorkerEntrypoint from urllib.parse import urlparse class MyDurableObject(DurableObject): def __init__(self, ctx, env): self.ctx = ctx self.env = env def fetch(self, request): result = self.ctx.storage.sql.exec("SELECT 'Hello, World!' as greeting").one() return Response(result.greeting) class Default(WorkerEntrypoint): async def fetch(self, request): url = urlparse(request.url) id = env.MY_DURABLE_OBJECT.idFromName(url.path) stub = env.MY_DURABLE_OBJECT.get(id) greeting = await stub.fetch(request.url) return greeting Define the Durable Object in your Wrangler configuration file: wrangler.jsonc { "durable_objects": { "bindings": [ { "name": "MY_DURABLE_OBJECT", "class_name": "MyDurableObject" } ] } } wrangler.toml [[durable_objects.bindings]] name = "MY_DURABLE_OBJECT" class_name = "MyDurableObject" Then define the storage backend for your Durable Object: wrangler.jsonc { "migrations": [ { "tag": "v1", "new_sqlite_classes": [ "MyDurableObject" ] } ] } wrangler.toml [[migrations]] tag = "v1" # Should be unique for each entry new_sqlite_classes = ["MyDurableObject"] # Array of new classes Then test your new Durable Object locally by running wrangler dev: npx wrangler dev Consult the Durable Objects documentation for more details.

2025/5/16
articleCard.readMore

Hyperdrive - Hyperdrive achieves FedRAMP Moderate-Impact Authorization

Hyperdrive has been approved for FedRAMP Authorization and is now available in the FedRAMP Marketplace. FedRAMP is a U.S. government program that provides standardized assessment and authorization for cloud products and services. As a result of this product update, Hyperdrive has been approved as an authorized service to be used by U.S. federal agencies at the Moderate Impact level. For detailed information regarding FedRAMP and its implications, please refer to the official FedRAMP documentation for Cloudflare.

2025/5/14
articleCard.readMore

Stream - Introducing Origin Restrictions for Media Transformations

We are adding source origin restrictions to the Media Transformations beta. This allows customers to restrict what sources can be used to fetch images and video for transformations. This feature is the same as --- and uses the same settings as --- Image Transformations sources. When transformations is first enabled, the default setting only allows transformations on images and media from the same website or domain being used to make the transformation request. In other words, by default, requests to example.com/cdn-cgi/media can only reference originals on example.com. Adding access to other sources, or allowing any source, is easy to do in the Transformations tab under Stream. Click each domain enabled for Transformations and set its sources list to match the needs of your content. The user making this change will need permission to edit zone settings. For more information, learn about Transforming Videos.

2025/5/14
articleCard.readMore

Queues - Publish messages to Queues directly via HTTP

You can now publish messages to Cloudflare Queues directly via HTTP from any service or programming language that supports sending HTTP requests. Previously, publishing to queues was only possible from within Cloudflare Workers. You can already consume from queues via Workers or HTTP pull consumers, and now publishing is just as flexible. Publishing via HTTP requires a Cloudflare API token with Queues Edit permissions for authentication. Here's a simple example: curl "https://api.cloudflare.com/client/v4/accounts/<account_id>/queues/<queue_id>/messages" \ -X POST \ -H 'Authorization: Bearer <api_token>' \ --data '{ "body": { "greeting": "hello", "timestamp": "2025-07-24T12:00:00Z"} }' You can also use our SDKs for TypeScript, Python, and Go. To get started with HTTP publishing, check out our step-by-step example and the full API documentation in our API reference.

2025/5/9
articleCard.readMore

Workers - Improved memory efficiency for WebAssembly Workers

FinalizationRegistry is now available in Workers. You can opt-in using the enable_weak_ref compatibility flag. This can reduce memory leaks when using WebAssembly-based Workers, which includes Python Workers and Rust Workers. The FinalizationRegistry works by enabling toolchains such as Emscripten and wasm-bindgen to automatically free WebAssembly heap allocations. If you are using WASM and seeing Exceeded Memory errors and cannot determine a cause using memory profiling, you may want to enable the FinalizationRegistry. For more information refer to the enable_weak_ref compatibility flag documentation.

2025/5/8
articleCard.readMore

R2 - R2 Dashboard experience gets new updates

We're excited to announce several improvements to the Cloudflare R2 dashboard experience that make managing your object storage easier and more intuitive: All-new settings page We've redesigned the bucket settings page, giving you a centralized location to manage all your bucket configurations in one place. Improved navigation and sharing Deeplink support for prefix directories: Navigate through your bucket hierarchy without losing your state. Your browser's back button now works as expected, and you can share direct links to specific prefix directories with teammates. Objects as clickable links: Objects are now proper links that you can copy or CMD + Click to open in a new tab. Clearer public access controls Renamed "r2.dev domain" to "Public Development URL" for better clarity when exposing bucket contents for non-production workloads. Public Access status now clearly displays "Enabled" when your bucket is exposed to the internet (via Public Development URL or Custom Domains). We've also made numerous other usability improvements across the board to make your R2 experience smoother and more productive.

2025/5/1
articleCard.readMore

Workers - Cron triggers are now supported in Python Workers

You can now create Python Workers which are executed via a cron trigger. This is similar to how it's done in JavaScript Workers, simply define a scheduled event listener in your Worker: from workers import handler @handler async def on_scheduled(event, env, ctx): print("cron processed") Define a cron trigger configuration in your Wrangler configuration file: wrangler.jsonc { "triggers": { "crons": [ "*/3 * * * *", "0 15 1 * *", "59 23 LW * *" ] } } wrangler.toml [triggers] # Schedule cron triggers: # - At every 3rd minute # - At 15:00 (UTC) on first day of the month # - At 23:59 (UTC) on the last weekday of the month crons = [ "*/3 * * * *", "0 15 1 * *", "59 23 LW * *" ] Then test your new handler by using Wrangler with the --test-scheduled flag and making a request to /cdn-cgi/handler/scheduled?cron=*+*+*+*+*: npx wrangler dev --test-scheduled curl "http://localhost:8787/cdn-cgi/handler/scheduled?cron=*+*+*+*+*" Consult the Workers Cron Triggers page for full details on cron triggers in Workers.

2025/4/24
articleCard.readMore

AI Search - Metadata filtering and multitenancy support in AutoRAG

You can now filter AutoRAG search results by folder and timestamp using metadata filtering to narrow down the scope of your query. This makes it easy to build multitenant experiences where each user can only access their own data. By organizing your content into per-tenant folders and applying a folder filter at query time, you ensure that each tenant retrieves only their own documents. Example folder structure: customer-a/logs/ customer-a/contracts/ customer-b/contracts/ Example query: const response = await env.AI.autorag("my-autorag").search({ query: "When did I sign my agreement contract?", filters: { type: "eq", key: "folder", value: "customer-a/contracts/", }, }); You can use metadata filtering by creating a new AutoRAG or reindexing existing data. To reindex all content in an existing AutoRAG, update any chunking setting and select Sync index. Metadata filtering is available for all data indexed on or after April 21, 2025. If you are new to AutoRAG, get started with the Get started AutoRAG guide.

2025/4/23
articleCard.readMore

Queues - Increased limits for Queues pull consumers

Queues pull consumers can now pull and acknowledge up to 5,000 messages / second per queue. Previously, pull consumers were rate limited to 1,200 requests / 5 minutes, aggregated across all queues. Pull consumers allow you to consume messages over HTTP from any environment—including outside of Cloudflare Workers. They’re also useful when you need fine-grained control over how quickly messages are consumed. To setup a new queue with a pull based consumer using Wrangler, run: npx wrangler queues create my-queue npx wrangler queues consumer http add my-queue You can also configure a pull consumer using the REST API or the Queues dashboard. Once configured, you can pull messages from the queue using any HTTP client. You'll need a Cloudflare API Token with queues_read and queues_write permissions. For example: curl "https://api.cloudflare.com/client/v4/accounts/${CF_ACCOUNT_ID}/queues/${QUEUE_ID}/messages/pull" \ --header "Authorization: Bearer ${API_TOKEN}" \ --header "Content-Type: application/json" \ --data '{ "visibility_timeout": 10000, "batch_size": 2 }' To learn more about how to acknowledge messages, pull batches at once, and setup multiple consumers, refer to the pull consumer documentation. As always, Queues doesn't charge for data egress. Pull operations continue to be billed at the existing rate, of $0.40 / million operations. The increased limits are available now, on all new and existing queues. If you're new to Queues, get started with the Cloudflare Queues guide.

2025/4/17
articleCard.readMore

KV - Read multiple keys from Workers KV with bulk reads

You can now retrieve up to 100 keys in a single bulk read request made to Workers KV using the binding. This makes it easier to request multiple KV pairs within a single Worker invocation. Retrieving many key-value pairs using the bulk read operation is more performant than making individual requests since bulk read operations are not affected by Workers simultaneous connection limits. // Read single key const key = "key-a"; const value = await env.NAMESPACE.get(key); // Read multiple keys const keys = ["key-a", "key-b", "key-c", ...] // up to 100 keys const values : Map<string, string?> = await env.NAMESPACE.get(keys); // Print the value of "key-a" to the console. console.log(`The first key is ${values.get("key-a")}.`) Consult the Workers KV Read key-value pairs API for full details on Workers KV's new bulk reads support.

2025/4/17
articleCard.readMore

Workers, Workers for Platforms - Fixed and documented Workers Routes and Secrets API

Workers Routes API Previously, a request to the Workers Create Route API always returned null for "script" and an empty string for "pattern" even if the request was successful. curl https://api.cloudflare.com/client/v4/zones/$CF_ACCOUNT_ID/workers/routes \ -X PUT \ -H "Authorization: Bearer $CF_API_TOKEN" \ -H 'Content-Type: application/json' \ --data '{ "pattern": "example.com/*", "script": "hello-world-script" }' { "result": { "id": "bf153a27ba2b464bb9f04dcf75de1ef9", "pattern": "", "script": null, "request_limit_fail_open": false }, "success": true, "errors": [], "messages": [] } Now, it properly returns all values! { "result": { "id": "bf153a27ba2b464bb9f04dcf75de1ef9", "pattern": "example.com/*", "script": "hello-world-script", "request_limit_fail_open": false }, "success": true, "errors": [], "messages": [] } Workers Secrets API The Workers and Workers for Platforms secrets APIs are now properly documented in the Cloudflare OpenAPI docs. Previously, these endpoints were not publicly documented, leaving users confused on how to directly manage their secrets via the API. Now, you can find the proper endpoints in our public documentation, as well as in our API Library SDKs such as cloudflare-typescript (>4.2.0) and cloudflare-python (>4.1.0). Note the cloudflare_workers_secret and cloudflare_workers_for_platforms_script_secret Terraform resources are being removed in a future release. This resource is not recommended for managing secrets. Users should instead use the: Secrets Store with the "Secrets Store Secret" binding on Workers and Workers for Platforms Script Upload "Secret Text" Binding on Workers Script Upload and Workers for Platforms Script Upload Workers (and WFP) Secrets API

2025/4/15
articleCard.readMore

Stream - Signed URLs and Infrastructure Improvements on Stream Live WebRTC Beta

Cloudflare Stream has completed an infrastructure upgrade for our Live WebRTC beta support which brings increased scalability and improved playback performance to all customers. WebRTC allows broadcasting directly from a browser (or supported WHIP client) with ultra-low latency to tens of thousands of concurrent viewers across the globe. Additionally, as part of this upgrade, the WebRTC beta now supports Signed URLs to protect playback, just like our standard live stream options (HLS/DASH). For more information, learn about the Stream Live WebRTC beta.

2025/4/11
articleCard.readMore

Workers AI - Workers AI for Developer Week - faster inference, new models, async batch API, expanded LoRA support

Happy Developer Week 2025! Workers AI is excited to announce a couple of new features and improvements available today. Check out our blog for all the announcement details. Faster inference + New models We’re rolling out some in-place improvements to our models that can help speed up inference by 2-4x! Users of the models below will enjoy an automatic speed boost starting today: @cf/meta/llama-3.3-70b-instruct-fp8-fast gets a speed boost of 2-4x, leveraging techniques like speculative decoding, prefix caching, and an updated inference backend. @cf/baai/bge-small-en-v1.5, @cf/baai/bge-base-en-v1.5, @cf/baai/bge-large-en-v1.5 get an updated back end, which should improve inference times by 2x. With the bge models, we’re also announcing a new parameter called pooling which can take cls or mean as options. We highly recommend using pooling: cls which will help generate more accurate embeddings. However, embeddings generated with cls pooling are not backwards compatible with mean pooling. For this to not be a breaking change, the default remains as mean pooling. Please specify pooling: cls to enjoy more accurate embeddings going forward. We’re also excited to launch a few new models in our catalog to help round out your experience with Workers AI. We’ll be deprecating some older models in the future, so stay tuned for a deprecation announcement. Today’s new models include: @cf/mistralai/mistral-small-3.1-24b-instruct: a 24B parameter model achieving state-of-the-art capabilities comparable to larger models, with support for vision and tool calling. @cf/google/gemma-3-12b-it: well-suited for a variety of text generation and image understanding tasks, including question answering, summarization and reasoning, with a 128K context window, and multilingual support in over 140 languages. @cf/qwen/qwq-32b: a medium-sized reasoning model, which is capable of achieving competitive performance against state-of-the-art reasoning models, e.g., DeepSeek-R1, o1-mini. @cf/qwen/qwen2.5-coder-32b-instruct: the current state-of-the-art open-source code LLM, with its coding abilities matching those of GPT-4o. Batch Inference Introducing a new batch inference feature that allows you to send us an array of requests, which we will fulfill as fast as possible and send them back as an array. This is really helpful for large workloads such as summarization, embeddings, etc. where you don’t have a human-in-the-loop. Using the batch API will guarantee that your requests are fulfilled eventually, rather than erroring out if we don’t have enough capacity at a given time. Check out the tutorial to get started! Models that support batch inference today include: @cf/meta/llama-3.3-70b-instruct-fp8-fast @cf/baai/bge-small-en-v1.5 @cf/baai/bge-base-en-v1.5 @cf/baai/bge-large-en-v1.5 @cf/baai/bge-m3 @cf/meta/m2m100-1.2b Expanded LoRA support We’ve upgraded our LoRA experience to include 8 newer models, and can support ranks of up to 32 with a 300MB safetensors file limit (previously limited to rank of 8 and 100MB safetensors) Check out our LoRAs page to get started. Models that support LoRAs now include: @cf/meta/llama-3.2-11b-vision-instruct @cf/meta/llama-3.3-70b-instruct-fp8-fast @cf/meta/llama-guard-3-8b @cf/meta/llama-3.1-8b-instruct-fast (coming soon) @cf/deepseek-ai/deepseek-r1-distill-qwen-32b (coming soon) @cf/qwen/qwen2.5-coder-32b-instruct @cf/qwen/qwq-32b @cf/mistralai/mistral-small-3.1-24b-instruct @cf/google/gemma-3-12b-it

2025/4/11
articleCard.readMore

D1, Workers - D1 Read Replication Public Beta

D1 read replication is available in public beta to help lower average latency and increase overall throughput for read-heavy applications like e-commerce websites or content management tools. Workers can leverage read-only database copies, called read replicas, by using D1 Sessions API. A session encapsulates all the queries from one logical session for your application. For example, a session may correspond to all queries coming from a particular web browser session. With Sessions API, D1 queries in a session are guaranteed to be sequentially consistent to avoid data consistency pitfalls. D1 bookmarks can be used from a previous session to ensure logical consistency between sessions. // retrieve bookmark from previous session stored in HTTP header const bookmark = request.headers.get("x-d1-bookmark") ?? "first-unconstrained"; const session = env.DB.withSession(bookmark); const result = await session .prepare(`SELECT * FROM Customers WHERE CompanyName = 'Bs Beverages'`) .run(); // store bookmark for a future session response.headers.set("x-d1-bookmark", session.getBookmark() ?? ""); Read replicas are automatically created by Cloudflare (currently one in each supported D1 region), are active/inactive based on query traffic, and are transparently routed to by Cloudflare at no additional cost. To checkout D1 read replication, deploy the following Worker code using Sessions API, which will prompt you to create a D1 database and enable read replication on said database. To learn more about how read replication was implemented, go to our blog post.

2025/4/10
articleCard.readMore

Pipelines, R2, Workers - Cloudflare Pipelines now available in beta

Cloudflare Pipelines is now available in beta, to all users with a Workers Paid plan. Pipelines let you ingest high volumes of real time data, without managing the underlying infrastructure. A single pipeline can ingest up to 100 MB of data per second, via HTTP or from a Worker. Ingested data is automatically batched, written to output files, and delivered to an R2 bucket in your account. You can use Pipelines to build a data lake of clickstream data, or to store events from a Worker. Create your first pipeline with a single command: $ npx wrangler@latest pipelines create my-clickstream-pipeline --r2-bucket my-bucket 🌀 Authorizing R2 bucket "my-bucket" 🌀 Creating pipeline named "my-clickstream-pipeline" ✅ Successfully created pipeline my-clickstream-pipeline Id: 0e00c5ff09b34d018152af98d06f5a1xvc Name: my-clickstream-pipeline Sources: HTTP: Endpoint: https://0e00c5ff09b34d018152af98d06f5a1xvc.pipelines.cloudflare.com/ Authentication: off Format: JSON Worker: Format: JSON Destination: Type: R2 Bucket: my-bucket Format: newline-delimited JSON Compression: GZIP Batch hints: Max bytes: 100 MB Max duration: 300 seconds Max records: 100,000 🎉 You can now send data to your pipeline! Send data to your pipeline's HTTP endpoint: curl "https://0e00c5ff09b34d018152af98d06f5a1xvc.pipelines.cloudflare.com/" -d '[{ ...JSON_DATA... }]' To send data to your pipeline from a Worker, add the following configuration to your config file: { "pipelines": [ { "pipeline": "my-clickstream-pipeline", "binding": "PIPELINE" } ] } Head over to our getting started guide for an in-depth tutorial to building with Pipelines.

2025/4/10
articleCard.readMore

R2 - R2 Data Catalog is a managed Apache Iceberg data catalog built directly into R2 buckets

Today, we're launching R2 Data Catalog in open beta, a managed Apache Iceberg catalog built directly into your Cloudflare R2 bucket. If you're not already familiar with it, Apache Iceberg is an open table format designed to handle large-scale analytics datasets stored in object storage, offering ACID transactions and schema evolution. R2 Data Catalog exposes a standard Iceberg REST catalog interface, so you can connect engines like Spark, Snowflake, and PyIceberg to start querying your tables using the tools you already know. To enable a data catalog on your R2 bucket, find R2 Data Catalog in your buckets settings in the dashboard, or run: npx wrangler r2 bucket catalog enable my-bucket And that's it. You'll get a catalog URI and warehouse you can plug into your favorite Iceberg engines. Visit our getting started guide for step-by-step instructions on enabling R2 Data Catalog, creating tables, and running your first queries.

2025/4/10
articleCard.readMore

Hyperdrive - Hyperdrive now supports custom TLS/SSL certificates

Hyperdrive now supports more SSL/TLS security options for your database connections: Configure Hyperdrive to verify server certificates with verify-ca or verify-full SSL modes and protect against man-in-the-middle attacks Configure Hyperdrive to provide client certificates to the database server to authenticate itself (mTLS) for stronger security beyond username and password Use the new wrangler cert commands to create certificate authority (CA) certificate bundles or client certificate pairs: # Create CA certificate bundle npx wrangler cert upload certificate-authority --ca-cert your-ca-cert.pem --name your-custom-ca-name # Create client certificate pair npx wrangler cert upload mtls-certificate --cert client-cert.pem --key client-key.pem --name your-client-cert-name Then create a Hyperdrive configuration with the certificates and desired SSL mode: npx wrangler hyperdrive create your-hyperdrive-config \ --connection-string="postgres://user:password@hostname:port/database" \ --ca-certificate-id <CA_CERT_ID> \ --mtls-certificate-id <CLIENT_CERT_ID> --sslmode verify-full Learn more about configuring SSL/TLS certificates for Hyperdrive to enhance your database security posture.

2025/4/9
articleCard.readMore

Workers - CPU time and Wall time now published for Workers Invocations

You can now observe and investigate the CPU time and Wall time for every Workers Invocations. For Workers Logs, CPU time and Wall time are surfaced in the Invocation Log.. For Tail Workers, CPU time and Wall time are surfaced at the top level of the Workers Trace Events object. For Workers Logpush, CPU and Wall time are surfaced at the top level of the Workers Trace Events object. All new jobs will have these new fields included by default. Existing jobs need to be updated to include CPU time and Wall time. You can use a Workers Logs filter to search for logs where Wall time exceeds 100ms. You can also use the Workers Observability Query Builder to find the median CPU time and median Wall time for all of your Workers.

2025/4/9
articleCard.readMore

Workers - Investigate your Workers with the Query Builder in the new Observability dashboard

The Workers Observability dashboard offers a single place to investigate and explore your Workers Logs. The Overview tab shows logs from all your Workers in one place. The Invocations view groups logs together by invocation, which refers to the specific trigger that started the execution of the Worker (i.e. fetch). The Events view shows logs in the order they were produced, based on timestamp. Previously, you could only view logs for a single Worker. The Investigate tab presents a Query Builder, which helps you write structured queries to investigate and visualize your logs. The Query Builder can help answer questions such as: Which paths are experiencing the most 5XX errors? What is the wall time distribution by status code for my Worker? What are the slowest requests, and where are they coming from? Who are my top N users? The Query Builder can use any field that you store in your logs as a key to visualize, filter, and group by. Use the Query Builder to quickly access your data, build visualizations, save queries, and share them with your team. Workers Logs is now Generally Available Workers Logs is now Generally Available. With a small change to your Wrangler configuration, Workers Logs ingests, indexes, and stores all logs emitted from your Workers for up to 7 days. We've introduced a number of changes during our beta period, including: Dashboard enhancements with customizable fields as columns in the Logs view and support for invocation-based grouping Performance improvements to ensure no adverse impact Public API endpoints for broader consumption The API documents three endpoints: list the keys in the telemetry dataset, run a query, and list the unique values for a key. For more, visit our REST API documentation. Visit the docs to learn more about the capabilities and methods exposed by the Query Builder. Start using Workers Logs and the Query Builder today by enabling observability for your Workers: wrangler.jsonc { "observability": { "enabled": true, "logs": { "invocation_logs": true, "head_sampling_rate": 1 } } } wrangler.toml [observability] enabled = true [observability.logs] invocation_logs = true head_sampling_rate = 1 # optional. default = 1.

2025/4/9
articleCard.readMore

Email Routing - Local development support for Email Workers

Email Workers enables developers to programmatically take action on anything that hits their email inbox. If you're building with Email Workers, you can now test the behavior of an Email Worker script, receiving, replying and sending emails in your local environment using wrangler dev. Below is an example that shows you how you can receive messages using the email() handler and parse them using postal-mime: import * as PostalMime from "postal-mime"; export default { async email(message, env, ctx) { const parser = new PostalMime.default(); const rawEmail = new Response(message.raw); const email = await parser.parse(await rawEmail.arrayBuffer()); console.log(email); }, }; Now when you run npx wrangler dev, wrangler will expose a local /cdn-cgi/handler/email endpoint that you can POST email messages to and trigger your Worker's email() handler: curl -X POST 'http://localhost:8787/cdn-cgi/handler/email' \ --url-query 'from=sender@example.com' \ --url-query 'to=recipient@example.com' \ --header 'Content-Type: application/json' \ --data-raw 'Received: from smtp.example.com (127.0.0.1) by cloudflare-email.com (unknown) id 4fwwffRXOpyR for <recipient@example.com>; Tue, 27 Aug 2024 15:50:20 +0000 From: "John" <sender@example.com> Reply-To: sender@example.com To: recipient@example.com Subject: Testing Email Workers Local Dev Content-Type: text/html; charset="windows-1252" X-Mailer: Curl Date: Tue, 27 Aug 2024 08:49:44 -0700 Message-ID: <6114391943504294873000@ZSH-GHOSTTY> Hi there' This is what you get in the console: { "headers": [ { "key": "received", "value": "from smtp.example.com (127.0.0.1) by cloudflare-email.com (unknown) id 4fwwffRXOpyR for <recipient@example.com>; Tue, 27 Aug 2024 15:50:20 +0000" }, { "key": "from", "value": "\"John\" <sender@example.com>" }, { "key": "reply-to", "value": "sender@example.com" }, { "key": "to", "value": "recipient@example.com" }, { "key": "subject", "value": "Testing Email Workers Local Dev" }, { "key": "content-type", "value": "text/html; charset=\"windows-1252\"" }, { "key": "x-mailer", "value": "Curl" }, { "key": "date", "value": "Tue, 27 Aug 2024 08:49:44 -0700" }, { "key": "message-id", "value": "<6114391943504294873000@ZSH-GHOSTTY>" } ], "from": { "address": "sender@example.com", "name": "John" }, "to": [{ "address": "recipient@example.com", "name": "" }], "replyTo": [{ "address": "sender@example.com", "name": "" }], "subject": "Testing Email Workers Local Dev", "messageId": "<6114391943504294873000@ZSH-GHOSTTY>", "date": "2024-08-27T15:49:44.000Z", "html": "Hi there\n", "attachments": [] } Local development is a critical part of the development flow, and also works for sending, replying and forwarding emails. See our documentation for more information.

2025/4/8
articleCard.readMore

Hyperdrive - Hyperdrive introduces support for MySQL and MySQL-compatible databases

Hyperdrive now supports connecting to MySQL and MySQL-compatible databases, including Amazon RDS and Aurora MySQL, Google Cloud SQL for MySQL, Azure Database for MySQL, PlanetScale and MariaDB. Hyperdrive makes your regional, MySQL databases fast when connecting from Cloudflare Workers. It eliminates unnecessary network roundtrips during connection setup, pools database connections globally, and can cache query results to provide the fastest possible response times. Best of all, you can connect using your existing drivers, ORMs, and query builders with Hyperdrive's secure credentials, no code changes required. import { createConnection } from "mysql2/promise"; export interface Env { HYPERDRIVE: Hyperdrive; } export default { async fetch(request, env, ctx): Promise<Response> { const connection = await createConnection({ host: env.HYPERDRIVE.host, user: env.HYPERDRIVE.user, password: env.HYPERDRIVE.password, database: env.HYPERDRIVE.database, port: env.HYPERDRIVE.port, disableEval: true, // Required for Workers compatibility }); const [results, fields] = await connection.query("SHOW tables;"); ctx.waitUntil(connection.end()); return new Response(JSON.stringify({ results, fields }), { headers: { "Content-Type": "application/json", "Access-Control-Allow-Origin": "*", }, }); }, } satisfies ExportedHandler<Env>; Learn more about how Hyperdrive works and get started building Workers that connect to MySQL with Hyperdrive.

2025/4/8
articleCard.readMore

Hyperdrive - Hyperdrive Free plan makes fast, global database access available to all

Hyperdrive is now available on the Free plan of Cloudflare Workers, enabling you to build Workers that connect to PostgreSQL or MySQL databases without compromise. Low-latency access to SQL databases is critical to building full-stack Workers applications. We want you to be able to build on fast, global apps on Workers, regardless of the tools you use. So we made Hyperdrive available for all, to make it easier to build Workers that connect to PostgreSQL and MySQL. If you want to learn more about how Hyperdrive works, read the deep dive on how Hyperdrive can make your database queries up to 4x faster. Visit the docs to get started with Hyperdrive for PostgreSQL or MySQL.

2025/4/8
articleCard.readMore

Workers - Deploy a Workers application in seconds with one-click

You can now add a Deploy to Cloudflare button to the README of your Git repository containing a Workers application — making it simple for other developers to quickly set up and deploy your project! The Deploy to Cloudflare button: Creates a new Git repository on your GitHub/ GitLab account: Cloudflare will automatically clone and create a new repository on your account, so you can continue developing. Automatically provisions resources the app needs: If your repository requires Cloudflare primitives like a Workers KV namespace, a D1 database, or an R2 bucket, Cloudflare will automatically provision them on your account and bind them to your Worker upon deployment. Configures Workers Builds (CI/CD): Every new push to your production branch on your newly created repository will automatically build and deploy courtesy of Workers Builds. Adds preview URLs to each pull request: If you'd like to test your changes before deploying, you can push changes to a non-production branch and preview URLs will be generated and posted back to GitHub as a comment. To create a Deploy to Cloudflare button in your README, you can add the following snippet, including your Git repository URL: [![Deploy to Cloudflare](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=<YOUR_GIT_REPO_URL>) Check out our documentation for more information on how to set up a deploy button for your application and best practices to ensure a successful deployment for other developers.

2025/4/8
articleCard.readMore

Workers, Workers for Platforms - Full-stack frameworks are now Generally Available on Cloudflare Workers

The following full-stack frameworks now have Generally Available ("GA") adapters for Cloudflare Workers, and are ready for you to use in production: React Router v7 (Remix) Astro Hono Vue.js Nuxt Svelte (SvelteKit) And more. The following frameworks are now in beta, with GA support coming very soon: Next.js, supported through @opennextjs/cloudflare is now v1.0-beta. Angular SolidJS (SolidStart) You can also build complete full-stack apps on Workers without a framework: You can “just use Vite" and React together, and build a back-end API in the same Worker. Follow our React SPA with an API tutorial to learn how. Get started building today with our framework guides, or read our Developer Week 2025 blog post about all the updates to building full-stack applications on Workers.

2025/4/8
articleCard.readMore

Workers - Improved support for Node.js Crypto and TLS APIs in Workers

When using a Worker with the nodejs_compat compatibility flag enabled, the following Node.js APIs are now available: node:crypto node:tls This make it easier to reuse existing Node.js code in Workers or use npm packages that depend on these APIs. node:crypto The full node:crypto API is now available in Workers. You can use it to verify and sign data: import { sign, verify } from "node:crypto"; const signature = sign("sha256", "-data to sign-", env.PRIVATE_KEY); const verified = verify("sha256", "-data to sign-", env.PUBLIC_KEY, signature); Or, to encrypt and decrypt data: import { publicEncrypt, privateDecrypt } from "node:crypto"; const encrypted = publicEncrypt(env.PUBLIC_KEY, "some data"); const plaintext = privateDecrypt(env.PRIVATE_KEY, encrypted); See the node:crypto documentation for more information. node:tls The following APIs from node:tls are now available: connect TLSSocket checkServerIdentity createSecureContext This enables secure connections over TLS (Transport Layer Security) to external services. import { connect } from "node:tls"; // ... in a request handler ... const connectionOptions = { key: env.KEY, cert: env.CERT }; const socket = connect(url, connectionOptions, () => { if (socket.authorized) { console.log("Connection authorized"); } }); socket.on("data", (data) => { console.log(data); }); socket.on("end", () => { console.log("server ends connection"); }); See the node:tls documentation for more information.

2025/4/8
articleCard.readMore

Workers - The Cloudflare Vite plugin is now Generally Available

The Cloudflare Vite plugin has reached v1.0 and is now Generally Available ("GA"). When you use @cloudflare/vite-plugin, you can use Vite's local development server and build tooling, while ensuring that while developing, your code runs in workerd, the open-source Workers runtime. This lets you get the best of both worlds for a full-stack app — you can use Hot Module Replacement from Vite right alongside Durable Objects and other runtime APIs and bindings that are unique to Cloudflare Workers. @cloudflare/vite-plugin is made possible by the new environment API in Vite, and was built in partnership with the Vite team. Framework support You can build any type of application with @cloudflare/vite-plugin, using any rendering mode, from single page applications (SPA) and static sites to server-side rendered (SSR) pages and API routes. React Router v7 (Remix) is the first full-stack framework to provide full support for Cloudflare Vite plugin, allowing you to use all parts of Cloudflare's developer platform, without additional build steps. You can also build complete full-stack apps on Workers without a framework — "just use Vite" and React together, and build a back-end API in the same Worker. Follow our React SPA with an API tutorial to learn how. Configuration If you're already using Vite in your build and development toolchain, you can start using our plugin with minimal changes to your vite.config.ts: import { defineConfig } from "vite"; import { cloudflare } from "@cloudflare/vite-plugin"; export default defineConfig({ plugins: [cloudflare()], }); Take a look at the documentation for our Cloudflare Vite plugin for more information!

2025/4/8
articleCard.readMore

Agents, Workers - Build MCP servers with the Agents SDK

The Agents SDK now includes built-in support for building remote MCP (Model Context Protocol) servers directly as part of your Agent. This allows you to easily create and manage MCP servers, without the need for additional infrastructure or configuration. The SDK includes a new MCPAgent class that extends the Agent class and allows you to expose resources and tools over the MCP protocol, as well as authorization and authentication to enable remote MCP servers. JavaScript export class MyMCP extends McpAgent { server = new McpServer({ name: "Demo", version: "1.0.0", }); async init() { this.server.resource(`counter`, `mcp://resource/counter`, (uri) => { // ... }); this.server.tool( "add", "Add two numbers together", { a: z.number(), b: z.number() }, async ({ a, b }) => { // ... }, ); } } TypeScript export class MyMCP extends McpAgent<Env> { server = new McpServer({ name: "Demo", version: "1.0.0", }); async init() { this.server.resource(`counter`, `mcp://resource/counter`, (uri) => { // ... }); this.server.tool( "add", "Add two numbers together", { a: z.number(), b: z.number() }, async ({ a, b }) => { // ... }, ); } } See the example for the full code and as the basis for building your own MCP servers, and the client example for how to build an Agent that acts as an MCP client. To learn more, review the announcement blog as part of Developer Week 2025. Agents SDK updates We've made a number of improvements to the Agents SDK, including: Support for building MCP servers with the new MCPAgent class. The ability to export the current agent, request and WebSocket connection context using import { context } from "agents", allowing you to minimize or avoid direct dependency injection when calling tools. Fixed a bug that prevented query parameters from being sent to the Agent server from the useAgent React hook. Automatically converting the agent name in useAgent or useAgentChat to kebab-case to ensure it matches the naming convention expected by routeAgentRequest. To install or update the Agents SDK, run npm i agents@latest in an existing project, or explore the agents-starter project: npm create cloudflare@latest -- --template cloudflare/agents-starter See the full release notes and changelog on the Agents SDK repository and

2025/4/7
articleCard.readMore

AI Search, Vectorize - Create fully-managed RAG pipelines for your AI applications with AutoRAG

AutoRAG is now in open beta, making it easy for you to build fully-managed retrieval-augmented generation (RAG) pipelines without managing infrastructure. Just upload your docs to R2, and AutoRAG handles the rest: embeddings, indexing, retrieval, and response generation via API. With AutoRAG, you can: Customize your pipeline: Choose from Workers AI models, configure chunking strategies, edit system prompts, and more. Instant setup: AutoRAG provisions everything you need from Vectorize, AI gateway, to pipeline logic for you, so you can go from zero to a working RAG pipeline in seconds. Keep your index fresh: AutoRAG continuously syncs your index with your data source to ensure responses stay accurate and up to date. Ask questions: Query your data and receive grounded responses via a Workers binding or API. Whether you're building internal tools, AI-powered search, or a support assistant, AutoRAG gets you from idea to deployment in minutes. Get started in the Cloudflare dashboard or check out the guide for instructions on how to build your RAG pipeline today.

2025/4/7
articleCard.readMore

Browser Rendering - Browser Rendering REST API is Generally Available, with new endpoints and a free tier

We’re excited to announce Browser Rendering is now available on the Workers Free plan, making it even easier to prototype and experiment with web search and headless browser use-cases when building applications on Workers. The Browser Rendering REST API is now Generally Available, allowing you to control browser instances from outside of Workers applications. We've added three new endpoints to help automate more browser tasks: Extract structured data – Use /json to retrieve structured data from a webpage. Retrieve links – Use /links to pull all links from a webpage. Convert to Markdown – Use /markdown to convert webpage content into Markdown format. For example, to fetch the Markdown representation of a webpage: curl -X 'POST' 'https://api.cloudflare.com/client/v4/accounts/<accountId>/browser-rendering/markdown' \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer <apiToken>' \ -d '{ "url": "https://example.com" }' For the full list of endpoints, check out our REST API documentation. You can also interact with Browser Rendering via the Cloudflare TypeScript SDK. We also recently landed support for Playwright in Browser Rendering for browser automation from Cloudflare Workers, in addition to Puppeteer, giving you more flexibility to test across different browser environments. Visit the Browser Rendering docs to learn more about how to use headless browsers in your applications.

2025/4/7
articleCard.readMore

Durable Objects, Workers - Durable Objects on Workers Free plan

Durable Objects can now be used with zero commitment on the Workers Free plan allowing you to build AI agents with Agents SDK, collaboration tools, and real-time applications like chat or multiplayer games. Durable Objects let you build stateful, serverless applications with millions of tiny coordination instances that run your application code alongside (in the same thread!) your durable storage. Each Durable Object can access its own SQLite database through a Storage API. A Durable Object class is defined in a Worker script encapsulating the Durable Object's behavior when accessed from a Worker. To try the code below, click the button: import { DurableObject } from "cloudflare:workers"; // Durable Object export class MyDurableObject extends DurableObject { ... async sayHello(name) { return `Hello, ${name}!`; } } // Worker export default { async fetch(request, env) { // Every unique ID refers to an individual instance of the Durable Object class const id = env.MY_DURABLE_OBJECT.idFromName("foo"); // A stub is a client used to invoke methods on the Durable Object const stub = env.MY_DURABLE_OBJECT.get(id); // Methods on the Durable Object are invoked via the stub const response = await stub.sayHello("world"); return response; }, }; Free plan limits apply to Durable Objects compute and storage usage. Limits allow developers to build real-world applications, with every Worker request able to call a Durable Object on the free plan. For more information, checkout: Documentation Zero-latency SQLite storage in every Durable Object blog

2025/4/7
articleCard.readMore

Durable Objects, Workers - SQLite in Durable Objects GA with 10GB storage per object

SQLite in Durable Objects is now generally available (GA) with 10GB SQLite database per Durable Object. Since the public beta in September 2024, we've added feature parity and robustness for the SQLite storage backend compared to the preexisting key-value (KV) storage backend for Durable Objects. SQLite-backed Durable Objects are recommended for all new Durable Object classes, using new_sqlite_classes Wrangler configuration. Only SQLite-backed Durable Objects have access to Storage API's SQL and point-in-time recovery methods, which provide relational data modeling, SQL querying, and better data management. export class MyDurableObject extends DurableObject { sql: SqlStorage constructor(ctx: DurableObjectState, env: Env) { super(ctx, env); this.sql = ctx.storage.sql; } async sayHello() { let result = this.sql .exec("SELECT 'Hello, World!' AS greeting") .one(); return result.greeting; } } KV-backed Durable Objects remain for backwards compatibility, and a migration path from key-value storage to SQL storage for existing Durable Object classes will be offered in the future. For more details on SQLite storage, checkout Zero-latency SQLite storage in every Durable Object blog.

2025/4/7
articleCard.readMore

Workers - Capture up to 256 KB of log events in each Workers Invocation

You can now capture a maximum of 256 KB of log events per Workers invocation, helping you gain better visibility into application behavior. All console.log() statements, exceptions, request metadata, and headers are automatically captured during the Worker invocation and emitted as JSON object. Workers Logs deserializes this object before indexing the fields and storing them. You can also capture, transform, and export the JSON object in a Tail Worker. 256 KB is a 2x increase from the previous 128 KB limit. After you exceed this limit, further context associated with the request will not be recorded in your logs. This limit is automatically applied to all Workers.

2025/4/7
articleCard.readMore

Workflows, Workers - Workflows is now Generally Available

Workflows is now Generally Available (or "GA"): in short, it's ready for production workloads. Alongside marking Workflows as GA, we've introduced a number of changes during the beta period, including: A new waitForEvent API that allows a Workflow to wait for an event to occur before continuing execution. Increased concurrency: you can run up to 4,500 Workflow instances concurrently — and this will continue to grow. Improved observability, including new CPU time metrics that allow you to better understand which Workflow instances are consuming the most resources and/or contributing to your bill. Support for vitest for testing Workflows locally and in CI/CD pipelines. Workflows also supports the new increased CPU limits that apply to Workers, allowing you to run more CPU-intensive tasks (up to 5 minutes of CPU time per instance), not including the time spent waiting on network calls, AI models, or other I/O bound tasks. Human-in-the-loop The new step.waitForEvent API allows a Workflow instance to wait on events and data, enabling human-in-the-the-loop interactions, such as approving or rejecting a request, directly handling webhooks from other systems, or pushing event data to a Workflow while it's running. Because Workflows are just code, you can conditionally execute code based on the result of a waitForEvent call, and/or call waitForEvent multiple times in a single Workflow based on what the Workflow needs. For example, if you wanted to implement a human-in-the-loop approval process, you could use waitForEvent to wait for a user to approve or reject a request, and then conditionally execute code based on the result. JavaScript import { Workflow, WorkflowEvent } from "cloudflare:workflows"; export class MyWorkflow extends WorkflowEntrypoint { async run(event, step) { // Other steps in your Workflow let event = await step.waitForEvent( "receive invoice paid webhook from Stripe", { type: "stripe-webhook", timeout: "1 hour" }, ); // Rest of your Workflow } } TypeScript import { Workflow, WorkflowEvent } from "cloudflare:workflows"; export class MyWorkflow extends WorkflowEntrypoint<Env, Params> { async run(event: WorkflowEvent<Params>, step: WorkflowStep) { // Other steps in your Workflow let event = await step.waitForEvent<IncomingStripeWebhook>("receive invoice paid webhook from Stripe", { type: "stripe-webhook", timeout: "1 hour" }) // Rest of your Workflow } } You can then send a Workflow an event from an external service via HTTP or from within a Worker using the Workers API for Workflows: JavaScript export default { async fetch(req, env) { const instanceId = new URL(req.url).searchParams.get("instanceId"); const webhookPayload = await req.json(); let instance = await env.MY_WORKFLOW.get(instanceId); // Send our event, with `type` matching the event type defined in // our step.waitForEvent call await instance.sendEvent({ type: "stripe-webhook", payload: webhookPayload, }); return Response.json({ status: await instance.status(), }); }, }; TypeScript export default { async fetch(req: Request, env: Env) { const instanceId = new URL(req.url).searchParams.get("instanceId") const webhookPayload = await req.json<Payload>() let instance = await env.MY_WORKFLOW.get(instanceId); // Send our event, with `type` matching the event type defined in // our step.waitForEvent call await instance.sendEvent({type: "stripe-webhook", payload: webhookPayload}) return Response.json({ status: await instance.status(), }); }, }; Read the GA announcement blog to learn more about what landed as part of the Workflows GA.

2025/4/7
articleCard.readMore

Browser Rendering - Playwright for Browser Rendering now available

We're excited to share that you can now use Playwright's browser automation capabilities from Cloudflare Workers. Playwright is an open-source package developed by Microsoft that can do browser automation tasks; it's commonly used to write software tests, debug applications, create screenshots, and crawl pages. Like Puppeteer, we forked Playwright and modified it to be compatible with Cloudflare Workers and Browser Rendering. Below is an example of how to use Playwright with Browser Rendering to test a TODO application using assertions: import { launch, type BrowserWorker } from "@cloudflare/playwright"; import { expect } from "@cloudflare/playwright/test"; interface Env { MYBROWSER: BrowserWorker; } export default { async fetch(request: Request, env: Env) { const browser = await launch(env.MYBROWSER); const page = await browser.newPage(); await page.goto("https://demo.playwright.dev/todomvc"); const TODO_ITEMS = [ "buy some cheese", "feed the cat", "book a doctors appointment", ]; const newTodo = page.getByPlaceholder("What needs to be done?"); for (const item of TODO_ITEMS) { await newTodo.fill(item); await newTodo.press("Enter"); } await expect(page.getByTestId("todo-title")).toHaveCount(TODO_ITEMS.length); await Promise.all( TODO_ITEMS.map((value, index) => expect(page.getByTestId("todo-title").nth(index)).toHaveText(value), ), ); }, }; Playwright is available as an npm package at @cloudflare/playwright and the code is at GitHub. Learn more in our documentation.

2025/4/4
articleCard.readMore

Queues - New Pause & Purge APIs for Queues

Queues now supports the ability to pause message delivery and/or purge (delete) messages on a queue. These operations can be useful when: Your consumer has a bug or downtime, and you want to temporarily stop messages from being processed while you fix the bug You have pushed invalid messages to a queue due to a code change during development, and you want to clean up the backlog Your queue has a backlog that is stale and you want to clean it up to allow new messages to be consumed To pause a queue using Wrangler, run the pause-delivery command. Paused queues continue to receive messages. And you can easily unpause a queue using the resume-delivery command. $ wrangler queues pause-delivery my-queue Pausing message delivery for queue my-queue. Paused message delivery for queue my-queue. $ wrangler queues resume-delivery my-queue Resuming message delivery for queue my-queue. Resumed message delivery for queue my-queue. Purging a queue permanently deletes all messages in the queue. Unlike pausing, purging is an irreversible operation: $ wrangler queues purge my-queue ✔ This operation will permanently delete all the messages in queue my-queue. Type my-queue to proceed. … my-queue Purged queue 'my-queue' You can also do these operations using the Queues REST API, or the dashboard page for a queue. This feature is available on all new and existing queues. Head over to the pause and purge documentation to learn more. And if you haven't used Cloudflare Queues before, get started with the Cloudflare Queues guide.

2025/3/27
articleCard.readMore

Workers - Run Workers for up to 5 minutes of CPU-time

You can now run a Worker for up to 5 minutes of CPU time for each request. Previously, each Workers request ran for a maximum of 30 seconds of CPU time — that is the time that a Worker is actually performing a task (we still allowed unlimited wall-clock time, in case you were waiting on slow resources). This meant that some compute-intensive tasks were impossible to do with a Worker. For instance, you might want to take the cryptographic hash of a large file from R2. If this computation ran for over 30 seconds, the Worker request would have timed out. By default, Workers are still limited to 30 seconds of CPU time. This protects developers from incurring accidental cost due to buggy code. By changing the cpu_ms value in your Wrangler configuration, you can opt in to any value up to 300,000 (5 minutes). wrangler.jsonc { // ...rest of your configuration... "limits": { "cpu_ms": 300000, }, // ...rest of your configuration... } wrangler.toml [limits] cpu_ms = 300_000 Note CPU time is the amount of time the CPU actually spends doing work during a given request. If a Worker's request makes a sub-request and waits for that request to come back before doing additional work, this time spent waiting is not counted towards CPU time. Worker requests could run for more than 30 seconds of total time prior to this change — only CPU time was limited. For more information on the updates limits, see the documentation on Wrangler configuration for cpu_ms and on Workers CPU time limits. For building long-running tasks on Cloudflare, we also recommend checking out Workflows and Queues.

2025/3/26
articleCard.readMore

Workers - Source Maps are Generally Available

Source maps are now Generally Available (GA). You can now be uploaded with a maximum gzipped size of 15 MB. Previously, the maximum size limit was 15 MB uncompressed. Source maps help map between the original source code and the transformed/minified code that gets deployed to production. By uploading your source map, you allow Cloudflare to map the stack trace from exceptions onto the original source code making it easier to debug. With no source maps uploaded: notice how all the Javascript has been minified to one file, so the stack trace is missing information on file name, shows incorrect line numbers, and incorrectly references js instead of ts. With source maps uploaded: all methods reference the correct files and line numbers. Uploading source maps and stack trace remapping happens out of band from the Worker execution, so source maps do not affect upload speed, bundle size, or cold starts. The remapped stack traces are accessible through Tail Workers, Workers Logs, and Workers Logpush. To enable source maps, add the following to your Pages Function's or Worker's wrangler configuration: wrangler.jsonc { "upload_source_maps": true } wrangler.toml upload_source_maps = true

2025/3/25
articleCard.readMore

Workers, Pages, WAF - New Managed WAF rule for Next.js CVE-2025-29927.

Update: Mon Mar 24th, 11PM UTC: Next.js has made further changes to address a smaller vulnerability introduced in the patches made to its middleware handling. Users should upgrade to Next.js versions 15.2.4, 14.2.26, 13.5.10 or 12.3.6. If you are unable to immediately upgrade or are running an older version of Next.js, you can enable the WAF rule described in this changelog as a mitigation. Update: Mon Mar 24th, 8PM UTC: Next.js has now backported the patch for this vulnerability to cover Next.js v12 and v13. Users on those versions will need to patch to 13.5.9 and 12.3.5 (respectively) to mitigate the vulnerability. Update: Sat Mar 22nd, 4PM UTC: We have changed this WAF rule to opt-in only, as sites that use auth middleware with third-party auth vendors were observing failing requests. We strongly recommend updating your version of Next.js (if eligible) to the patched versions, as your app will otherwise be vulnerable to an authentication bypass attack regardless of auth provider. Enable the Managed Rule (strongly recommended) This rule is opt-in only for sites on the Pro plan or above in the WAF managed ruleset. To enable the rule: Head to Security > WAF > Managed rules in the Cloudflare dashboard for the zone (website) you want to protect. Click the three dots next to Cloudflare Managed Ruleset and choose Edit Scroll down and choose Browse Rules Search for CVE-2025-29927 (ruleId: 34583778093748cc83ff7b38f472013e) Change the Status to Enabled and the Action to Block. You can optionally set the rule to Log, to validate potential impact before enabling it. Log will not block requests. Click Next Scroll down and choose Save This will enable the WAF rule and block requests with the x-middleware-subrequest header regardless of Next.js version. Create a WAF rule (manual) For users on the Free plan, or who want to define a more specific rule, you can create a Custom WAF rule to block requests with the x-middleware-subrequest header regardless of Next.js version. To create a custom rule: Head to Security > WAF > Custom rules in the Cloudflare dashboard for the zone (website) you want to protect. Give the rule a name - e.g. next-js-CVE-2025-29927 Set the matching parameters for the rule match any request where the x-middleware-subrequest header exists per the rule expression below. (len(http.request.headers["x-middleware-subrequest"]) > 0) Set the action to 'block'. If you want to observe the impact before blocking requests, set the action to 'log' (and edit the rule later). Deploy the rule. Next.js CVE-2025-29927 We've made a WAF (Web Application Firewall) rule available to all sites on Cloudflare to protect against the Next.js authentication bypass vulnerability (CVE-2025-29927) published on March 21st, 2025. Note: This rule is not enabled by default as it blocked requests across sites for specific authentication middleware. This managed rule protects sites using Next.js on Workers and Pages, as well as sites using Cloudflare to protect Next.js applications hosted elsewhere. This rule has been made available (but not enabled by default) to all sites as part of our WAF Managed Ruleset and blocks requests that attempt to bypass authentication in Next.js applications. The vulnerability affects almost all Next.js versions, and has been fully patched in Next.js 14.2.26 and 15.2.4. Earlier, interim releases did not fully patch this vulnerability. Users on older versions of Next.js (11.1.4 to 13.5.6) did not originally have a patch available, but this the patch for this vulnerability and a subsequent additional patch have been backported to Next.js versions 12.3.6 and 13.5.10 as of Monday, March 24th. Users on Next.js v11 will need to deploy the stated workaround or enable the WAF rule. The managed WAF rule mitigates this by blocking external user requests with the x-middleware-subrequest header regardless of Next.js version, but we recommend users using Next.js 14 and 15 upgrade to the patched versions of Next.js as an additional mitigation.

2025/3/22
articleCard.readMore

Workers, Pages - Smart Placement is smarter about running Workers and Pages Functions in the best locations

Smart Placement is a unique Cloudflare feature that can make decisions to move your Worker to run in a more optimal location (such as closer to a database). Instead of always running in the default location (the one closest to where the request is received), Smart Placement uses certain “heuristics” (rules and thresholds) to decide if a different location might be faster or more efficient. Previously, if these heuristics weren't consistently met, your Worker would revert to running in the default location—even after it had been optimally placed. This meant that if your Worker received minimal traffic for a period of time, the system would reset to the default location, rather than remaining in the optimal one. Now, once Smart Placement has identified and assigned an optimal location, temporarily dropping below the heuristic thresholds will not force a return to default locations. For example in the previous algorithm, a drop in requests for a few days might return to default locations and heuristics would have to be met again. This was problematic for workloads that made requests to a geographically located resource every few days or longer. In this scenario, your Worker would never get placed optimally. This is no longer the case.

2025/3/22
articleCard.readMore

AI Gateway - AI Gateway launches Realtime WebSockets API

We are excited to announce that AI Gateway now supports real-time AI interactions with the new Realtime WebSockets API. This new capability allows developers to establish persistent, low-latency connections between their applications and AI models, enabling natural, real-time conversational AI experiences, including speech-to-speech interactions. The Realtime WebSockets API works with the OpenAI Realtime API, Google Gemini Live API, and supports real-time text and speech interactions with models from Cartesia, and ElevenLabs. Here's how you can connect AI Gateway to OpenAI's Realtime API using WebSockets: import WebSocket from "ws"; const url = "wss://gateway.ai.cloudflare.com/v1/<account_id>/<gateway>/openai?model=gpt-4o-realtime-preview-2024-12-17"; const ws = new WebSocket(url, { headers: { "cf-aig-authorization": process.env.CLOUDFLARE_API_KEY, Authorization: "Bearer " + process.env.OPENAI_API_KEY, "OpenAI-Beta": "realtime=v1", }, }); ws.on("open", () => console.log("Connected to server.")); ws.on("message", (message) => console.log(JSON.parse(message.toString()))); ws.send( JSON.stringify({ type: "response.create", response: { modalities: ["text"], instructions: "Tell me a joke" }, }), ); Get started by checking out the Realtime WebSockets API documentation.

2025/3/21
articleCard.readMore

Workers AI - Markdown conversion in Workers AI

Document conversion plays an important role when designing and developing AI applications and agents. Workers AI now provides the toMarkdown utility method that developers can use to for quick, easy, and convenient conversion and summary of documents in multiple formats to Markdown language. You can call this new tool using a binding by calling env.AI.toMarkdown() or the using the REST API endpoint. In this example, we fetch a PDF document and an image from R2 and feed them both to env.AI.toMarkdown(). The result is a list of converted documents. Workers AI models are used automatically to detect and summarize the image. import { Env } from "./env"; export default { async fetch(request: Request, env: Env, ctx: ExecutionContext) { // https://pub-979cb28270cc461d94bc8a169d8f389d.r2.dev/somatosensory.pdf const pdf = await env.R2.get("somatosensory.pdf"); // https://pub-979cb28270cc461d94bc8a169d8f389d.r2.dev/cat.jpeg const cat = await env.R2.get("cat.jpeg"); return Response.json( await env.AI.toMarkdown([ { name: "somatosensory.pdf", blob: new Blob([await pdf.arrayBuffer()], { type: "application/octet-stream", }), }, { name: "cat.jpeg", blob: new Blob([await cat.arrayBuffer()], { type: "application/octet-stream", }), }, ]), ); }, }; This is the result: [ { "name": "somatosensory.pdf", "mimeType": "application/pdf", "format": "markdown", "tokens": 0, "data": "# somatosensory.pdf\n## Metadata\n- PDFFormatVersion=1.4\n- IsLinearized=false\n- IsAcroFormPresent=false\n- IsXFAPresent=false\n- IsCollectionPresent=false\n- IsSignaturesPresent=false\n- Producer=Prince 20150210 (www.princexml.com)\n- Title=Anatomy of the Somatosensory System\n\n## Contents\n### Page 1\nThis is a sample document to showcase..." }, { "name": "cat.jpeg", "mimeType": "image/jpeg", "format": "markdown", "tokens": 0, "data": "The image is a close-up photograph of Grumpy Cat, a cat with a distinctive grumpy expression and piercing blue eyes. The cat has a brown face with a white stripe down its nose, and its ears are pointed upright. Its fur is light brown and darker around the face, with a pink nose and mouth. The cat's eyes are blue and slanted downward, giving it a perpetually grumpy appearance. The background is blurred, but it appears to be a dark brown color. Overall, the image is a humorous and iconic representation of the popular internet meme character, Grumpy Cat. The cat's facial expression and posture convey a sense of displeasure or annoyance, making it a relatable and entertaining image for many people." } ] See Markdown Conversion for more information on supported formats, REST API and pricing.

2025/3/20
articleCard.readMore

Agents, Workers - npm i agents

agents-sdk -> agents Updated 📝 We've renamed the Agents package to agents! If you've already been building with the Agents SDK, you can update your dependencies to use the new package name, and replace references to agents-sdk with agents: # Install the new package npm i agents # Remove the old (deprecated) package npm uninstall agents-sdk # Find instances of the old package name in your codebase grep -r 'agents-sdk' . # Replace instances of the old package name with the new one # (or use find-replace in your editor) sed -i 's/agents-sdk/agents/g' $(grep -rl 'agents-sdk' .) All future updates will be pushed to the new agents package, and the older package has been marked as deprecated. Agents SDK updates New We've added a number of big new features to the Agents SDK over the past few weeks, including: You can now set cors: true when using routeAgentRequest to return permissive default CORS headers to Agent responses. The regular client now syncs state on the agent (just like the React version). useAgentChat bug fixes for passing headers/credentials, including properly clearing cache on unmount. Experimental /schedule module with a prompt/schema for adding scheduling to your app (with evals!). Changed the internal zod schema to be compatible with the limitations of Google's Gemini models by removing the discriminated union, allowing you to use Gemini models with the scheduling API. We've also fixed a number of bugs with state synchronization and the React hooks. JavaScript // via https://github.com/cloudflare/agents/tree/main/examples/cross-domain export default { async fetch(request, env) { return ( // Set { cors: true } to enable CORS headers. (await routeAgentRequest(request, env, { cors: true })) || new Response("Not found", { status: 404 }) ); }, }; TypeScript // via https://github.com/cloudflare/agents/tree/main/examples/cross-domain export default { async fetch(request: Request, env: Env) { return ( // Set { cors: true } to enable CORS headers. (await routeAgentRequest(request, env, { cors: true })) || new Response("Not found", { status: 404 }) ); }, } satisfies ExportedHandler<Env>; Call Agent methods from your client code New We've added a new @unstable_callable() decorator for defining methods that can be called directly from clients. This allows you call methods from within your client code: you can call methods (with arguments) and get native JavaScript objects back. JavaScript // server.ts import { unstable_callable, Agent } from "agents"; export class Rpc extends Agent { // Use the decorator to define a callable method @unstable_callable({ description: "rpc test", }) async getHistory() { return this.sql`SELECT * FROM history ORDER BY created_at DESC LIMIT 10`; } } TypeScript // server.ts import { unstable_callable, Agent, type StreamingResponse } from "agents"; import type { Env } from "../server"; export class Rpc extends Agent<Env> { // Use the decorator to define a callable method @unstable_callable({ description: "rpc test", }) async getHistory() { return this.sql`SELECT * FROM history ORDER BY created_at DESC LIMIT 10`; } } agents-starter Updated We've fixed a number of small bugs in the agents-starter project — a real-time, chat-based example application with tool-calling & human-in-the-loop built using the Agents SDK. The starter has also been upgraded to use the latest wrangler v4 release. If you're new to Agents, you can install and run the agents-starter project in two commands: # Install it $ npm create cloudflare@latest agents-starter -- --template="cloudflare/agents-starter" # Run it $ npm run start You can use the starter as a template for your own Agents projects: open up src/server.ts and src/client.tsx to see how the Agents SDK is used. More documentation Updated We've heard your feedback on the Agents SDK documentation, and we're shipping more API reference material and usage examples, including: Expanded API reference documentation, covering the methods and properties exposed by the Agents SDK, as well as more usage examples. More Client API documentation that documents useAgent, useAgentChat and the new @unstable_callable RPC decorator exposed by the SDK. New documentation on how to call agents and (optionally) authenticate clients before they connect to your Agents. Note that the Agents SDK is continually growing: the type definitions included in the SDK will always include the latest APIs exposed by the agents package. If you're still wondering what Agents are, read our blog on building AI Agents on Cloudflare and/or visit the Agents documentation to learn more.

2025/3/18
articleCard.readMore

Workers AI - New models in Workers AI

Workers AI is excited to add 4 new models to the catalog, including 2 brand new classes of models with a text-to-speech and reranker model. Introducing: @cf/baai/bge-m3 - a multi-lingual embeddings model that supports over 100 languages. It can also simultaneously perform dense retrieval, multi-vector retrieval, and sparse retrieval, with the ability to process inputs of different granularities. @cf/baai/bge-reranker-base - our first reranker model! Rerankers are a type of text classification model that takes a query and context, and outputs a similarity score between the two. When used in RAG systems, you can use a reranker after the initial vector search to find the most relevant documents to return to a user by reranking the outputs. @cf/openai/whisper-large-v3-turbo - a faster, more accurate speech-to-text model. This model was added earlier but is graduating out of beta with pricing included today. @cf/myshell-ai/melotts - our first text-to-speech model that allows users to generate an MP3 with voice audio from inputted text. Pricing is available for each of these models on the Workers AI pricing page. This docs update includes a few minor bug fixes to the model schema for llama-guard, llama-3.2-1b, which you can review on the product changelog. Try it out and let us know what you think! Stay tuned for more models in the coming days.

2025/3/17
articleCard.readMore

Workers - Import `env` to access bindings in your Worker's global scope

You can now access bindings from anywhere in your Worker by importing the env object from cloudflare:workers. Previously, env could only be accessed during a request. This meant that bindings could not be used in the top-level context of a Worker. Now, you can import env and access bindings such as secrets or environment variables in the initial setup for your Worker: import { env } from "cloudflare:workers"; import ApiClient from "example-api-client"; // API_KEY and LOG_LEVEL now usable in top-level scope const apiClient = ApiClient.new({ apiKey: env.API_KEY }); const LOG_LEVEL = env.LOG_LEVEL || "info"; export default { fetch(req) { // you can use apiClient or LOG_LEVEL, configured before any request is handled }, }; Note Workers do not allow I/O from outside a request context. This means that even though env is accessible from the top-level scope, you will not be able to access every binding's methods. For instance, environment variables and secrets are accessible, and you are able to call env.NAMESPACE.get to get a Durable Object stub in the top-level context. However, calling methods on the Durable Object stub, making calls to a KV store, and calling to other Workers will not work. Additionally, env was normally accessed as a argument to a Worker's entrypoint handler, such as fetch. This meant that if you needed to access a binding from a deeply nested function, you had to pass env as an argument through many functions to get it to the right spot. This could be cumbersome in complex codebases. Now, you can access the bindings from anywhere in your codebase without passing env as an argument: // helpers.js import { env } from "cloudflare:workers"; // env is *not* an argument to this function export async function getValue(key) { let prefix = env.KV_PREFIX; return await env.KV.get(`${prefix}-${key}`); } For more information, see documentation on accessing env.

2025/3/17
articleCard.readMore

Workers, Pages - Retry Pages & Workers Builds Directly from GitHub

You can now retry your Cloudflare Pages and Workers builds directly from GitHub. No need to switch to the Cloudflare Dashboard for a simple retry! Let’s say you push a commit, but your build fails due to a spurious error like a network timeout. Instead of going to the Cloudflare Dashboard to manually retry, you can now rerun the build with just a few clicks inside GitHub, keeping you inside your workflow. For Pages and Workers projects connected to a GitHub repository: When a build fails, go to your GitHub repository or pull request Select the failed Check Run for the build Select "Details" on the Check Run Select "Rerun" to trigger a retry build for that commit Learn more about Pages Builds and Workers Builds.

2025/3/17
articleCard.readMore

Workers - Use the latest JavaScript features with Wrangler CLI v4

We've released the next major version of Wrangler, the CLI for Cloudflare Workers — wrangler@4.0.0. Wrangler v4 is a major release focused on updates to underlying systems and dependencies, along with improvements to keep Wrangler commands consistent and clear. You can run the following command to install it in your projects: npm npm i wrangler@latest yarn yarn add wrangler@latest pnpm pnpm add wrangler@latest Unlike previous major versions of Wrangler, which were foundational rewrites and rearchitectures — Version 4 of Wrangler includes a much smaller set of changes. If you use Wrangler today, your workflow is very unlikely to change. A detailed migration guide is available and if you find a bug or hit a roadblock when upgrading to Wrangler v4, open an issue on the cloudflare/workers-sdk repository on GitHub. Going forward, we'll continue supporting Wrangler v3 with bug fixes and security updates until Q1 2026, and with critical security updates until Q1 2027, at which point it will be out of support.

2025/3/13
articleCard.readMore

Workers - Set breakpoints and debug your Workers tests with @cloudflare/vitest-pool-workers

You can now debug your Workers tests with our Vitest integration by running the following command: vitest --inspect --no-file-parallelism Attach a debugger to the port 9229 and you can start stepping through your Workers tests. This is available with @cloudflare/vitest-pool-workers v0.7.5 or later. Learn more in our documentation.

2025/3/13
articleCard.readMore

Email Routing - Threaded replies now possible in Email Workers

We’re removing some of the restrictions in Email Routing so that AI Agents and task automation can better handle email workflows, including how Workers can reply to incoming emails. It's now possible to keep a threaded email conversation with an Email Worker script as long as: The incoming email has to have valid DMARC. The email can only be replied to once in the same EmailMessage event. The recipient in the reply must match the incoming sender. The outgoing sender domain must match the same domain that received the email. Every time an email passes through Email Routing or another MTA, an entry is added to the References list. We stop accepting replies to emails with more than 100 References entries to prevent abuse or accidental loops. Here's an example of a Worker responding to Emails using a Workers AI model: import PostalMime from "postal-mime"; import { createMimeMessage } from "mimetext"; import { EmailMessage } from "cloudflare:email"; export default { async email(message, env, ctx) { const email = await PostalMime.parse(message.raw); const res = await env.AI.run("@cf/meta/llama-2-7b-chat-fp16", { messages: [ { role: "user", content: email.text ?? "", }, ], }); // message-id is generated by mimetext const response = createMimeMessage(); response.setHeader("In-Reply-To", message.headers.get("Message-ID")!); response.setSender("agent@example.com"); response.setRecipient(message.from); response.setSubject("Llama response"); response.addMessage({ contentType: "text/plain", data: res instanceof ReadableStream ? await new Response(res).text() : res.response!, }); const replyMessage = new EmailMessage( "<email>", message.from, response.asRaw(), ); await message.reply(replyMessage); }, } satisfies ExportedHandler<Env>; See Reply to emails from Workers for more information.

2025/3/12
articleCard.readMore

Workers - Access your Worker's environment variables from process.env

You can now access environment variables and secrets on process.env when using the nodejs_compat compatibility flag. const apiClient = ApiClient.new({ apiKey: process.env.API_KEY }); const LOG_LEVEL = process.env.LOG_LEVEL || "info"; In Node.js, environment variables are exposed via the global process.env object. Some libraries assume that this object will be populated, and many developers may be used to accessing variables in this way. Previously, the process.env object was always empty unless written to in Worker code. This could cause unexpected errors or friction when developing Workers using code previously written for Node.js. Now, environment variables, secrets, and version metadata can all be accessed on process.env. To opt-in to the new process.env behaviour now, add the nodejs_compat_populate_process_env compatibility flag to your wrangler.json configuration: wrangler.jsonc { // Rest of your configuration // Add "nodejs_compat_populate_process_env" to your compatibility_flags array "compatibility_flags": ["nodejs_compat", "nodejs_compat_populate_process_env"], // Rest of your configuration wrangler.toml compatibility_flags = [ "nodejs_compat", "nodejs_compat_populate_process_env" ] After April 1, 2025, populating process.env will become the default behavior when both nodejs_compat is enabled and your Worker's compatibility_date is after "2025-04-01".

2025/3/11
articleCard.readMore

Hyperdrive - Hyperdrive reduces query latency by up to 90% and now supports IP access control lists

Hyperdrive now pools database connections in one or more regions close to your database. This means that your uncached queries and new database connections have up to 90% less latency as measured from connection pools. By improving placement of Hyperdrive database connection pools, Workers' Smart Placement is now more effective when used with Hyperdrive, ensuring that your Worker can be placed as close to your database as possible. With this update, Hyperdrive also uses Cloudflare's standard IP address ranges to connect to your database. This enables you to configure the firewall policies (IP access control lists) of your database to only allow access from Cloudflare and Hyperdrive. Refer to documentation on how Hyperdrive makes connecting to regional databases from Cloudflare Workers fast. This improvement is enabled on all Hyperdrive configurations.

2025/3/7
articleCard.readMore

R2 - Set retention polices for your R2 bucket with bucket locks

You can now use bucket locks to set retention policies on your R2 buckets (or specific prefixes within your buckets) for a specified period — or indefinitely. This can help ensure compliance by protecting important data from accidental or malicious deletion. Locks give you a few ways to ensure your objects are retained (not deleted or overwritten). You can: Lock objects for a specific duration, for example 90 days. Lock objects until a certain date, for example January 1, 2030. Lock objects indefinitely, until the lock is explicitly removed. Buckets can have up to 1,000 bucket lock rules. Each rule specifies which objects it covers (via prefix) and how long those objects must remain retained. Here are a couple of examples showing how you can configure bucket lock rules using Wrangler: Ensure all objects in a bucket are retained for at least 180 days npx wrangler r2 bucket lock add <bucket> --name 180-days-all --retention-days 180 Prevent deletion or overwriting of all logs indefinitely (via prefix) npx wrangler r2 bucket lock add <bucket> --name indefinite-logs --prefix logs/ --retention-indefinite For more information on bucket locks and how to set retention policies for objects in your R2 buckets, refer to our documentation.

2025/3/6
articleCard.readMore

Stream - Introducing Media Transformations from Cloudflare Stream

Today, we are thrilled to announce Media Transformations, a new service that brings the magic of Image Transformations to short-form video files, wherever they are stored! For customers with a huge volume of short video — generative AI output, e-commerce product videos, social media clips, or short marketing content — uploading those assets to Stream is not always practical. Sometimes, the greatest friction to getting started was the thought of all that migrating. Customers want a simpler solution that retains their current storage strategy to deliver small, optimized MP4 files. Now you can do that with Media Transformations. To transform a video or image, enable transformations for your zone, then make a simple request with a specially formatted URL. The result is an MP4 that can be used in an HTML video element without a player library. If your zone already has Image Transformations enabled, then it is ready to optimize videos with Media Transformations, too. https://example.com/cdn-cgi/media/<OPTIONS>/<SOURCE-VIDEO> For example, we have a short video of the mobile in Austin's office. The original is nearly 30 megabytes and wider than necessary for this layout. Consider a simple width adjustment: https://example.com/cdn-cgi/media/width=640/<SOURCE-VIDEO> https://developers.cloudflare.com/cdn-cgi/media/width=640/https://pub-d9fcbc1abcd244c1821f38b99017347f.r2.dev/aus-mobile.mp4 The result is less than 3 megabytes, properly sized, and delivered dynamically so that customers do not have to manage the creation and storage of these transformed assets. For more information, learn about Transforming Videos.

2025/3/6
articleCard.readMore

Workers - Use the latest JavaScript features with Wrangler CLI v4.0.0-rc.0

We've released a release candidate of the next major version of Wrangler, the CLI for Cloudflare Workers — wrangler@4.0.0-rc.0. You can run the following command to install it and be one of the first to try it out: npm npm i wrangler@v4-rc yarn yarn add wrangler@v4-rc pnpm pnpm add wrangler@v4-rc Unlike previous major versions of Wrangler, which were foundational rewrites and rearchitectures — Version 4 of Wrangler includes a much smaller set of changes. If you use Wrangler today, your workflow is very unlikely to change. Before we release Wrangler v4 and advance past the release candidate stage, we'll share a detailed migration guide in the Workers developer docs. But for the vast majority of cases, you won't need to do anything to migrate — things will just work as they do today. We are sharing this release candidate in advance of the official release of v4, so that you can try it out early and share feedback. New JavaScript language features that you can now use with Wrangler v4 Version 4 of Wrangler updates the version of esbuild that Wrangler uses internally, allowing you to use modern JavaScript language features, including: The using keyword from Explicit Resource Management The using keyword from the Explicit Resource Management standard makes it easier to work with the JavaScript-native RPC system built into Workers. This means that when you obtain a stub, you can ensure that it is automatically disposed when you exit scope it was created in: function sendEmail(id, message) { using user = await env.USER_SERVICE.findUser(id); await user.sendEmail(message); // user[Symbol.dispose]() is implicitly called at the end of the scope. } Import attributes Import attributes allow you to denote the type or other attributes of the module that your code imports. For example, you can import a JSON module, using the following syntax: import data from "./data.json" with { type: "json" }; Other changes --local is now the default for all CLI commands All commands that access resources (for example, wrangler kv, wrangler r2, wrangler d1) now access local datastores by default, ensuring consistent behavior. Clearer policy for the minimum required version of Node.js required to run Wrangler Moving forward, the active, maintenance, and current versions of Node.js will be officially supported by Wrangler. This means the minimum officially supported version of Node.js you must have installed for Wrangler v4 will be Node.js v18 or later. This policy mirrors how many other packages and CLIs support older versions of Node.js, and ensures that as long as you are using a version of Node.js that the Node.js project itself supports, this will be supported by Wrangler as well. Features previously deprecated in Wrangler v3 are now removed in Wrangler v4 All previously deprecated features in Wrangler v2 and in Wrangler v3 have now been removed. Additionally, the following features that were deprecated during the Wrangler v3 release have been removed: Legacy Assets (using wrangler dev/deploy --legacy-assets or the legacy_assets config file property). Instead, we recommend you migrate to Workers assets. Legacy Node.js compatibility (using wrangler dev/deploy --node-compat or the node_compat config file property). Instead, use the nodejs_compat compatibility flag. This includes the functionality from legacy node_compat polyfills and natively implemented Node.js APIs. wrangler version. Instead, use wrangler --version to check the current version of Wrangler. getBindingsProxy() (via import { getBindingsProxy } from "wrangler"). Instead, use the getPlatformProxy() API, which takes exactly the same arguments. usage_model. This no longer has any effect, after the rollout of Workers Standard Pricing. We'd love your feedback! If you find a bug or hit a roadblock when upgrading to Wrangler v4, open an issue on the cloudflare/workers-sdk repository on GitHub.

2025/2/28
articleCard.readMore

Browser Rendering - New REST API is in open beta!

We've released a new REST API for Browser Rendering in open beta, making interacting with browsers easier than ever. This new API provides endpoints for common browser actions, with more to be added in the future. With the REST API you can: Capture screenshots – Use /screenshot to take a screenshot of a webpage from provided URL or HTML. Generate PDFs – Use /pdf to convert web pages into PDFs. Extract HTML content – Use /content to retrieve the full HTML from a page. Snapshot (HTML + Screenshot) – Use /snapshot to capture both the page's HTML and a screenshot in one request Scrape Web Elements – Use /scrape to extract specific elements from a page. For example, to capture a screenshot: curl -X POST 'https://api.cloudflare.com/client/v4/accounts/<accountId>/browser-rendering/screenshot' \ -H 'Authorization: Bearer <apiToken>' \ -H 'Content-Type: application/json' \ -d '{ "html": "Hello World!", "screenshotOptions": { "type": "webp", "omitBackground": true } }' \ --output "screenshot.webp" Learn more in our documentation.

2025/2/27
articleCard.readMore

AI Gateway - Introducing Guardrails in AI Gateway

AI Gateway now includes Guardrails, to help you monitor your AI apps for harmful or inappropriate content and deploy safely. Within the AI Gateway settings, you can configure: Guardrails: Enable or disable content moderation as needed. Evaluation scope: Select whether to moderate user prompts, model responses, or both. Hazard categories: Specify which categories to monitor and determine whether detected inappropriate content should be blocked or flagged. Learn more in the blog or our documentation.

2025/2/26
articleCard.readMore

Agents, Workers - Introducing the Agents SDK

We've released the Agents SDK, a package and set of tools that help you build and ship AI Agents. You can get up and running with a chat-based AI Agent (and deploy it to Workers) that uses the Agents SDK, tool calling, and state syncing with a React-based front-end by running the following command: npm create cloudflare@latest agents-starter -- --template="cloudflare/agents-starter" # open up README.md and follow the instructions You can also add an Agent to any existing Workers application by installing the agents package directly npm i agents ... and then define your first Agent: import { Agent } from "agents"; export class YourAgent extends Agent<Env> { // Build it out // Access state on this.state or query the Agent's database via this.sql // Handle WebSocket events with onConnect and onMessage // Run tasks on a schedule with this.schedule // Call AI models // ... and/or call other Agents. } Head over to the Agents documentation to learn more about the Agents SDK, the SDK APIs, as well as how to test and deploying agents to production.

2025/2/25
articleCard.readMore

Workers AI - Workers AI now supports structured JSON outputs.

Workers AI now supports structured JSON outputs with JSON mode, which allows you to request a structured output response when interacting with AI models. This makes it much easier to retrieve structured data from your AI models, and avoids the (error prone!) need to parse large unstructured text responses to extract your data. JSON mode in Workers AI is compatible with the OpenAI SDK's structured outputs response_format API, which can be used directly in a Worker: JavaScript import { OpenAI } from "openai"; // Define your JSON schema for a calendar event const CalendarEventSchema = { type: "object", properties: { name: { type: "string" }, date: { type: "string" }, participants: { type: "array", items: { type: "string" } }, }, required: ["name", "date", "participants"], }; export default { async fetch(request, env) { const client = new OpenAI({ apiKey: env.OPENAI_API_KEY, // Optional: use AI Gateway to bring logs, evals & caching to your AI requests // https://developers.cloudflare.com/ai-gateway/usage/providers/openai/ // baseUrl: "https://gateway.ai.cloudflare.com/v1/{account_id}/{gateway_id}/openai" }); const response = await client.chat.completions.create({ model: "gpt-4o-2024-08-06", messages: [ { role: "system", content: "Extract the event information." }, { role: "user", content: "Alice and Bob are going to a science fair on Friday.", }, ], // Use the `response_format` option to request a structured JSON output response_format: { // Set json_schema and provide ra schema, or json_object and parse it yourself type: "json_schema", schema: CalendarEventSchema, // provide a schema }, }); // This will be of type CalendarEventSchema const event = response.choices[0].message.parsed; return Response.json({ calendar_event: event, }); }, }; TypeScript import { OpenAI } from "openai"; interface Env { OPENAI_API_KEY: string; } // Define your JSON schema for a calendar event const CalendarEventSchema = { type: "object", properties: { name: { type: "string" }, date: { type: "string" }, participants: { type: "array", items: { type: "string" } }, }, required: ["name", "date", "participants"], }; export default { async fetch(request: Request, env: Env) { const client = new OpenAI({ apiKey: env.OPENAI_API_KEY, // Optional: use AI Gateway to bring logs, evals & caching to your AI requests // https://developers.cloudflare.com/ai-gateway/usage/providers/openai/ // baseUrl: "https://gateway.ai.cloudflare.com/v1/{account_id}/{gateway_id}/openai" }); const response = await client.chat.completions.create({ model: "gpt-4o-2024-08-06", messages: [ { role: "system", content: "Extract the event information." }, { role: "user", content: "Alice and Bob are going to a science fair on Friday.", }, ], // Use the `response_format` option to request a structured JSON output response_format: { // Set json_schema and provide ra schema, or json_object and parse it yourself type: "json_schema", schema: CalendarEventSchema, // provide a schema }, }); // This will be of type CalendarEventSchema const event = response.choices[0].message.parsed; return Response.json({ calendar_event: event, }); }, }; To learn more about JSON mode and structured outputs, visit the Workers AI documentation.

2025/2/25
articleCard.readMore

Workflows - Concurrent Workflow instances limits increased.

Workflows now supports up to 4,500 concurrent (running) instances, up from the previous limit of 100. This limit will continue to increase during the Workflows open beta. This increase applies to all users on the Workers Paid plan, and takes effect immediately. Review the Workflows limits documentation and/or dive into the get started guide to start building on Workflows.

2025/2/25
articleCard.readMore

Cloudflare Images - Bind the Images API to your Worker

You can now interact with the Images API directly in your Worker. This allows more fine-grained control over transformation request flows and cache behavior. For example, you can resize, manipulate, and overlay images without requiring them to be accessible through a URL. The Images binding can be configured in the Cloudflare dashboard for your Worker or in the wrangler.toml file in your project's directory: wrangler.jsonc { "images": { "binding": "IMAGES", // i.e. available in your Worker on env.IMAGES }, } wrangler.toml [images] binding = "IMAGES" Within your Worker code, you can interact with this binding by using env.IMAGES. Here's how you can rotate, resize, and blur an image, then output the image as AVIF: const info = await env.IMAGES.info(stream); // stream contains a valid image, and width/height is available on the info object const response = ( await env.IMAGES.input(stream) .transform({ rotate: 90 }) .transform({ width: 128 }) .transform({ blur: 20 }) .output({ format: "image/avif" }) ).response(); return response; For more information, refer to Images Bindings.

2025/2/24
articleCard.readMore

R2 - Super Slurper now supports migrations from all S3-compatible storage providers

Super Slurper can now migrate data from any S3-compatible object storage provider to Cloudflare R2. This includes transfers from services like MinIO, Wasabi, Backblaze B2, and DigitalOcean Spaces. For more information on Super Slurper and how to migrate data from your existing S3-compatible storage buckets to R2, refer to our documentation.

2025/2/24
articleCard.readMore

Workers AI - Workers AI larger context windows

We've updated the Workers AI text generation models to include context windows and limits definitions and changed our APIs to estimate and validate the number of tokens in the input prompt, not the number of characters. This update allows developers to use larger context windows when interacting with Workers AI models, which can lead to better and more accurate results. Our catalog page provides more information about each model's supported context window.

2025/2/24
articleCard.readMore

Zaraz - Zaraz moves to the “Tag Management” category in the Cloudflare dashboard

Previously, you could only configure Zaraz by going to each individual zone under your Cloudflare account. Now, if you’d like to get started with Zaraz or manage your existing configuration, you can navigate to the Tag Management section on the Cloudflare dashboard – this will make it easier to compare and configure the same settings across multiple zones. These changes will not alter any existing configuration or entitlements for zones you already have Zaraz enabled on. If you’d like to edit existing configurations, you can go to the Tag Setup section of the dashboard, and select the zone you'd like to edit.

2025/2/24
articleCard.readMore

Workers for Platforms - Workers for Platforms - Instant dispatch for newly created User Workers

Workers for Platforms is an architecture wherein a centralized dispatch Worker processes incoming requests and routes them to isolated sub-Workers, called User Workers. Previously, when a new User Worker was uploaded, there was a short delay before it became available for dispatch. This meant that even though an API request could return a 200 OK response, the script might not yet be ready to handle requests, causing unexpected failures for platforms that immediately dispatch to new Workers. With this update, first-time uploads of User Workers are now deployed synchronously. A 200 OK response guarantees the script is fully provisioned and ready to handle traffic immediately, ensuring more predictable deployments and reducing errors.

2025/2/21
articleCard.readMore

Workers AI - Workers AI updated pricing

We've updated the Workers AI pricing to include the latest models and how model usage maps to Neurons. Each model's core input format(s) (tokens, audio seconds, images, etc) now include mappings to Neurons, making it easier to understand how your included Neuron volume is consumed and how you are charged at scale Per-model pricing, instead of the previous bucket approach, allows us to be more flexible on how models are charged based on their size, performance and capabilities. As we optimize each model, we can then pass on savings for that model. You will still only pay for what you consume: Workers AI inference is serverless, and not billed by the hour. Going forward, models will be launched with their associated Neuron costs, and we'll be updating the Workers AI dashboard and API to reflect consumption in both raw units and Neurons. Visit the Workers AI pricing page to learn more about Workers AI pricing.

2025/2/20
articleCard.readMore

Workers - Autofix Worker name configuration errors at build time

Small misconfigurations shouldn’t break your deployments. Cloudflare is introducing automatic error detection and fixes in Workers Builds, identifying common issues in your wrangler.toml or wrangler.jsonc and proactively offering fixes, so you spend less time debugging and more time shipping. Here's how it works: Before running your build, Cloudflare checks your Worker's Wrangler configuration file (wrangler.toml or wrangler.jsonc) for common errors. Once you submit a build, if Cloudflare finds an error it can fix, it will submit a pull request to your repository that fixes it. Once you merge this pull request, Cloudflare will run another build. We're starting with fixing name mismatches between your Wrangler file and the Cloudflare dashboard, a top cause of build failures. This is just the beginning, we want your feedback on what other errors we should catch and fix next. Let us know in the Cloudflare Developers Discord, #workers-and-pages-feature-suggestions.

2025/2/20
articleCard.readMore

Queues - Customize queue message retention periods

You can now customize a queue's message retention period, from a minimum of 60 seconds to a maximum of 14 days. Previously, it was fixed to the default of 4 days. You can customize the retention period on the settings page for your queue, or using Wrangler: $ wrangler queues update my-queue --message-retention-period-secs 600 This feature is available on all new and existing queues. If you haven't used Cloudflare Queues before, get started with the Cloudflare Queues guide.

2025/2/14
articleCard.readMore

Agents, Workers, Workflows - Build AI Agents with Example Prompts

We've added an example prompt to help you get started with building AI agents and applications on Cloudflare Workers, including Workflows, Durable Objects, and Workers KV. You can use this prompt with your favorite AI model, including Claude 3.5 Sonnet, OpenAI's o3-mini, Gemini 2.0 Flash, or Llama 3.3 on Workers AI. Models with large context windows will allow you to paste the prompt directly: provide your own prompt within the <user_prompt></user_prompt> tags. {paste_prompt_here} <user_prompt> user: Build an AI agent using Cloudflare Workflows. The Workflow should run when a new GitHub issue is opened on a specific project with the label 'help' or 'bug', and attempt to help the user troubleshoot the issue by calling the OpenAI API with the issue title and description, and a clear, structured prompt that asks the model to suggest 1-3 possible solutions to the issue. Any code snippets should be formatted in Markdown code blocks. Documentation and sources should be referenced at the bottom of the response. The agent should then post the response to the GitHub issue. The agent should run as the provided GitHub bot account. </user_prompt> This prompt is still experimental, but we encourage you to try it out and provide feedback.

2025/2/14
articleCard.readMore

R2 - Super Slurper now transfers data to R2 up to 5x faster

Super Slurper now transfers data from cloud object storage providers like AWS S3 and Google Cloud Storage to Cloudflare R2 up to 5x faster than it did before. We moved from a centralized service to a distributed system built on the Cloudflare Developer Platform — using Cloudflare Workers, Durable Objects, and Queues — to both improve performance and increase system concurrency capabilities (and we'll share more details about how we did it soon!) Time to copy 75,000 objects from AWS S3 to R2 decreased from 15 minutes 30 seconds (old) to 3 minutes 25 seconds (after performance improvements) For more information on Super Slurper and how to migrate data from existing object storage to R2, refer to our documentation.

2025/2/14
articleCard.readMore

Stream - Rewind, Replay, Resume: Introducing DVR for Stream Live

Previously, all viewers watched "the live edge," or the latest content of the broadcast, synchronously. If a viewer paused for more than a few seconds, the player would automatically "catch up" when playback started again. Seeking through the broadcast was only available once the recording was available after it concluded. Starting today, customers can make a small adjustment to the player embed or manifest URL to enable the DVR experience for their viewers. By offering this feature as an opt-in adjustment, our customers are empowered to pick the best experiences for their applications. When building a player embed code or manifest URL, just add dvrEnabled=true as a query parameter. There are some things to be aware of when using this option. For more information, refer to DVR for Live.

2025/2/14
articleCard.readMore

Workers - Create and deploy Workers from Git repositories

You can now create a Worker by: Importing a Git repository: Choose an existing Git repo on your GitHub/GitLab account and set up Workers Builds to deploy your Worker. Deploying a template with Git: Choose from a brand new selection of production ready examples to help you get started with popular frameworks like Astro, Remix and Next or build stateful applications with Cloudflare resources like D1 databases, Workers AI or Durable Objects! When you're ready to deploy, Cloudflare will set up your project by cloning the template to your GitHub/GitLab account, provisioning any required resources and deploying your Worker. With every push to your chosen branch, Cloudflare will automatically build and deploy your Worker. To get started, go to the Workers dashboard. These new features are available today in the Cloudflare dashboard to a subset of Cloudflare customers, and will be coming to all customers in the next few weeks. Don't see it in your dashboard, but want early access? Add your Cloudflare Account ID to this form.

2025/2/7
articleCard.readMore

AI Gateway - Request timeouts and retries with AI Gateway

AI Gateway adds additional ways to handle requests - Request Timeouts and Request Retries, making it easier to keep your applications responsive and reliable. Timeouts and retries can be used on both the Universal Endpoint or directly to a supported provider. Request timeouts A request timeout allows you to trigger fallbacks or a retry if a provider takes too long to respond. To set a request timeout directly to a provider, add a cf-aig-request-timeout header. curl https://gateway.ai.cloudflare.com/v1/{account_id}/{gateway_id}/workers-ai/@cf/meta/llama-3.1-8b-instruct \ --header 'Authorization: Bearer {cf_api_token}' \ --header 'Content-Type: application/json' \ --header 'cf-aig-request-timeout: 5000' --data '{"prompt": "What is Cloudflare?"}' Request retries A request retry automatically retries failed requests, so you can recover from temporary issues without intervening. To set up request retries directly to a provider, add the following headers: cf-aig-max-attempts (number) cf-aig-retry-delay (number) cf-aig-backoff ("constant" | "linear" | "exponential)

2025/2/6
articleCard.readMore

AI Gateway - AI Gateway adds Cerebras, ElevenLabs, and Cartesia as new providers

AI Gateway has added three new providers: Cartesia, Cerebras, and ElevenLabs, giving you more even more options for providers you can use through AI Gateway. Here's a brief overview of each: Cartesia provides text-to-speech models that produce natural-sounding speech with low latency. Cerebras delivers low-latency AI inference to Meta's Llama 3.1 8B and Llama 3.3 70B models. ElevenLabs offers text-to-speech models with human-like voices in 32 languages. To get started with AI Gateway, just update the base URL. Here's how you can send a request to Cerebras using cURL: curl -X POST https://gateway.ai.cloudflare.com/v1/ACCOUNT_TAG/GATEWAY/cerebras/chat/completions \ --header 'content-type: application/json' \ --header 'Authorization: Bearer CEREBRAS_TOKEN' \ --data '{ "model": "llama-3.3-70b", "messages": [ { "role": "user", "content": "What is Cloudflare?" } ] }'

2025/2/5
articleCard.readMore

Workers - Revamped Workers Metrics

We've revamped the Workers Metrics dashboard. Now you can easily compare metrics across Worker versions, understand the current state of a gradual deployment, and review key Workers metrics in a single view. This new interface enables you to: Drag-and-select using a graphical timepicker for precise metric selection. Use histograms to visualize cumulative metrics, allowing you to bucket and compare rates over time. Focus on Worker versions by directly interacting with the version numbers in the legend. Monitor and compare active gradual deployments. Track error rates across versions with grouping both by version and by invocation status. Measure how Smart Placement improves request duration. Learn more about metrics.

2025/2/3
articleCard.readMore

Workers for Platforms - Workers for Platforms now supports Static Assets

Workers for Platforms customers can now attach static assets (HTML, CSS, JavaScript, images) directly to User Workers, removing the need to host separate infrastructure to serve the assets. This allows your platform to serve entire front-end applications from Cloudflare's global edge, utilizing caching for fast load times, while supporting dynamic logic within the same Worker. Cloudflare automatically scales its infrastructure to handle high traffic volumes, enabling you to focus on building features without managing servers. What you can build Static Sites: Host and serve HTML, CSS, JavaScript, and media files directly from Cloudflare's network, ensuring fast loading times worldwide. This is ideal for blogs, landing pages, and documentation sites because static assets can be efficiently cached and delivered closer to the user, reducing latency and enhancing the overall user experience. Full-Stack Applications: Combine asset hosting with Cloudflare Workers to power dynamic, interactive applications. If you're an e-commerce platform, you can serve your customers' product pages and run inventory checks from within the same Worker. JavaScript export default { async fetch(request, env) { const url = new URL(request.url); // Check real-time inventory if (url.pathname === "/api/inventory/check") { const product = url.searchParams.get("product"); const inventory = await env.INVENTORY_KV.get(product); return new Response(inventory); } // Serve static assets (HTML, CSS, images) return env.ASSETS.fetch(request); }, }; TypeScript export default { async fetch(request, env) { const url = new URL(request.url); // Check real-time inventory if (url.pathname === '/api/inventory/check') { const product = url.searchParams.get('product'); const inventory = await env.INVENTORY_KV.get(product); return new Response(inventory); } // Serve static assets (HTML, CSS, images) return env.ASSETS.fetch(request); } }; Get Started: Upload static assets using the Workers for Platforms API or Wrangler. For more information, visit our Workers for Platforms documentation.

2025/1/31
articleCard.readMore

Workers - Transform HTML quickly with streaming content

You can now transform HTML elements with streamed content using HTMLRewriter. Methods like replace, append, and prepend now accept Response and ReadableStream values as Content. This can be helpful in a variety of situations. For instance, you may have a Worker in front of an origin, and want to replace an element with content from a different source. Prior to this change, you would have to load all of the content from the upstream URL and convert it into a string before replacing the element. This slowed down overall response times. Now, you can pass the Response object directly into the replace method, and HTMLRewriter will immediately start replacing the content as it is streamed in. This makes responses faster. JavaScript class ElementRewriter { async element(element) { // able to replace elements while streaming content // the fetched body is not buffered into memory as part // of the replace let res = await fetch("https://upstream-content-provider.example"); element.replace(res); } } export default { async fetch(request, env, ctx) { let response = await fetch("https://site-to-replace.com"); return new HTMLRewriter() .on("[data-to-replace]", new ElementRewriter()) .transform(response); }, }; TypeScript class ElementRewriter { async element(element: any) { // able to replace elements while streaming content // the fetched body is not buffered into memory as part // of the replace let res = await fetch('https://upstream-content-provider.example'); element.replace(res); } } export default { async fetch(request, env, ctx): Promise<Response> { let response = await fetch('https://site-to-replace.com'); return new HTMLRewriter().on('[data-to-replace]', new ElementRewriter()).transform(response); }, } satisfies ExportedHandler<Env>; For more information, see the HTMLRewriter documentation.

2025/1/31
articleCard.readMore

AI Gateway - AI Gateway Introduces New Worker Binding Methods

We have released new Workers bindings API methods, allowing you to connect Workers applications to AI Gateway directly. These methods simplify how Workers calls AI services behind your AI Gateway configurations, removing the need to use the REST API and manually authenticate. To add an AI binding to your Worker, include the following in your Wrangler configuration file: With the new AI Gateway binding methods, you can now: Send feedback and update metadata with patchLog. Retrieve detailed log information using getLog. Execute universal requests to any AI Gateway provider with run. For example, to send feedback and update metadata using patchLog:

2025/1/30
articleCard.readMore

Workers, Browser Rendering - Increased Browser Rendering limits!

Browser Rendering now supports 10 concurrent browser instances per account and 10 new instances per minute, up from the previous limits of 2. This allows you to launch more browser tasks from Cloudflare Workers. To manage concurrent browser sessions, you can use Queues or Workflows: JavaScript export default { async queue(batch, env) { for (const message of batch.messages) { const browser = await puppeteer.launch(env.BROWSER); const page = await browser.newPage(); try { await page.goto(message.url, { waitUntil: message.waitUntil, }); // Process page... } finally { await browser.close(); } } }, }; TypeScript interface QueueMessage { url: string; waitUntil: number; } export interface Env { BROWSER_QUEUE: Queue<QueueMessage>; BROWSER: Fetcher; } export default { async queue(batch: MessageBatch<QueueMessage>, env: Env): Promise<void> { for (const message of batch.messages) { const browser = await puppeteer.launch(env.BROWSER); const page = await browser.newPage(); try { await page.goto(message.url, { waitUntil: message.waitUntil }); // Process page... } finally { await browser.close(); } } } };

2025/1/30
articleCard.readMore

Stream - Expanded language support for Stream AI Generated Captions

Stream's generated captions leverage Workers AI to automatically transcribe audio and provide captions to the player experience. We have added support for these languages: cs - Czech nl - Dutch fr - French de - German it - Italian ja - Japanese ko - Korean pl - Polish pt - Portuguese ru - Russian es - Spanish For more information, learn about adding captions to videos.

2025/1/30
articleCard.readMore

Hyperdrive - Automatic configuration for private databases on Hyperdrive

Hyperdrive now automatically configures your Cloudflare Tunnel to connect to your private database. When creating a Hyperdrive configuration for a private database, you only need to provide your database credentials and set up a Cloudflare Tunnel within the private network where your database is accessible. Hyperdrive will automatically create the Cloudflare Access, Service Token, and Policies needed to secure and restrict your Cloudflare Tunnel to the Hyperdrive configuration. To create a Hyperdrive for a private database, you can follow the Hyperdrive documentation. You can still manually create the Cloudflare Access, Service Token, and Policies if you prefer. This feature is available from the Cloudflare dashboard.

2025/1/28
articleCard.readMore

KV - Workers KV namespace limits increased to 1000

You can now have up to 1000 Workers KV namespaces per account. Workers KV namespace limits were increased from 200 to 1000 for all accounts. Higher limits for Workers KV namespaces enable better organization of key-value data, such as by category, tenant, or environment. Consult the Workers KV limits documentation for the rest of the limits. This increased limit is available for both the Free and Paid Workers plans.

2025/1/28
articleCard.readMore

Workers - Support for Node.js DNS, Net, and Timer APIs in Workers

When using a Worker with the nodejs_compat compatibility flag enabled, you can now use the following Node.js APIs: node:net node:dns node:timers node:net You can use node:net to create a direct connection to servers via a TCP sockets with net.Socket. JavaScript import net from "node:net"; const exampleIP = "127.0.0.1"; export default { async fetch(req) { const socket = new net.Socket(); socket.connect(4000, exampleIP, function () { console.log("Connected"); }); socket.write("Hello, Server!"); socket.end(); return new Response("Wrote to server", { status: 200 }); }, }; TypeScript import net from "node:net"; const exampleIP = "127.0.0.1"; export default { async fetch(req): Promise<Response> { const socket = new net.Socket(); socket.connect(4000, exampleIP, function () { console.log("Connected"); }); socket.write("Hello, Server!"); socket.end(); return new Response("Wrote to server", { status: 200 }); }, } satisfies ExportedHandler; Additionally, you can now use other APIs including net.BlockList and net.SocketAddress. Note that net.Server is not supported. node:dns You can use node:dns for name resolution via DNS over HTTPS using Cloudflare DNS at 1.1.1.1. JavaScript import dns from "node:dns"; let response = await dns.promises.resolve4("cloudflare.com", "NS"); TypeScript import dns from 'node:dns'; let response = await dns.promises.resolve4('cloudflare.com', 'NS'); All node:dns functions are available, except lookup, lookupService, and resolve which throw "Not implemented" errors when called. node:timers You can use node:timers to schedule functions to be called at some future period of time. This includes setTimeout for calling a function after a delay, setInterval for calling a function repeatedly, and setImmediate for calling a function in the next iteration of the event loop. JavaScript import timers from "node:timers"; console.log("first"); timers.setTimeout(() => { console.log("last"); }, 10); timers.setTimeout(() => { console.log("next"); }); TypeScript import timers from "node:timers"; console.log("first"); timers.setTimeout(() => { console.log("last"); }, 10); timers.setTimeout(() => { console.log("next"); });

2025/1/28
articleCard.readMore

Workflows - Increased Workflows limits and improved instance queueing.

Workflows (beta) now allows you to define up to 1024 steps. sleep steps do not count against this limit. We've also added: instanceId as property to the WorkflowEvent type, allowing you to retrieve the current instance ID from within a running Workflow instance Improved queueing logic for Workflow instances beyond the current maximum concurrent instances, reducing the cases where instances are stuck in the queued state. Support for pause and resume for Workflow instances in a queued state. We're continuing to work on increases to the number of concurrent Workflow instances, steps, and support for a new waitForEvent API over the coming weeks.

2025/1/15
articleCard.readMore

D1 - 40-60% Faster D1 Worker API Requests

Users making D1 requests via the Workers API can see up to a 60% end-to-end latency improvement due to the removal of redundant network round trips needed for each request to a D1 database. p50, p90, and p95 request latency aggregated across entire D1 service. These latencies are a reference point and should not be viewed as your exact workload improvement. This performance improvement benefits all D1 Worker API traffic, especially cross-region requests where network latency is an outsized latency factor. For example, a user in Europe talking to a database in North America. D1 location hints can be used to influence the geographic location of a database. For more details on how D1 removed redundant round trips, see the D1 specific release note entry.

2025/1/7
articleCard.readMore

AI Gateway - AI Gateway adds DeepSeek as a Provider

AI Gateway now supports DeepSeek, including their cutting-edge DeepSeek-V3 model. With this addition, you have even more flexibility to manage and optimize your AI workloads using AI Gateway. Whether you're leveraging DeepSeek or other providers, like OpenAI, Anthropic, or Workers AI, AI Gateway empowers you to: Monitor: Gain actionable insights with analytics and logs. Control: Implement caching, rate limiting, and fallbacks. Optimize: Improve performance with feedback and evaluations. To get started, simply update the base URL of your DeepSeek API calls to route through AI Gateway. Here's how you can send a request using cURL: curl https://gateway.ai.cloudflare.com/v1/{account_id}/{gateway_id}/deepseek/chat/completions \ --header 'content-type: application/json' \ --header 'Authorization: Bearer DEEPSEEK_TOKEN' \ --data '{ "model": "deepseek-chat", "messages": [ { "role": "user", "content": "What is Cloudflare?" } ] }' For detailed setup instructions, see our DeepSeek provider documentation.

2025/1/2
articleCard.readMore

Workers - Faster Workers Builds with Build Caching and Watch Paths

Workers Builds, the integrated CI/CD system for Workers (currently in beta), now lets you cache artifacts across builds, speeding up build jobs by eliminating repeated work, such as downloading dependencies at the start of each build. Build Caching: Cache dependencies and build outputs between builds with a shared project-wide cache, ensuring faster builds for the entire team. Build Watch Paths: Define paths to include or exclude from the build process, ideal for monorepos to target only the files that need to be rebuilt per Workers project. To get started, select your Worker on the Cloudflare dashboard then go to Settings > Builds, and connect a GitHub or GitLab repository. Once connected, you'll see options to configure Build Caching and Build Watch Paths.

2024/12/29
articleCard.readMore

Hyperdrive - Up to 10x faster cached queries for Hyperdrive

Hyperdrive now caches queries in all Cloudflare locations, decreasing cache hit latency by up to 90%. When you make a query to your database and Hyperdrive has cached the query results, Hyperdrive will now return the results from the nearest cache. By caching data closer to your users, the latency for cache hits reduces by up to 90%. This reduction in cache hit latency is reflected in a reduction of the session duration for all queries (cached and uncached) from Cloudflare Workers to Hyperdrive, as illustrated below. P50, P75, and P90 Hyperdrive session latency for all client connection sessions (both cached and uncached queries) for Hyperdrive configurations with caching enabled during the rollout period. This performance improvement is applied to all new and existing Hyperdrive configurations that have caching enabled. For more details on how Hyperdrive performs query caching, refer to the Hyperdrive documentation.

2024/12/11
articleCard.readMore

Workers - Bypass caching for subrequests made from Cloudflare Workers, with Request.cache

You can now use the cache property of the Request interface to bypass Cloudflare's cache when making subrequests from Cloudflare Workers, by setting its value to no-store. JavaScript export default { async fetch(req, env, ctx) { const request = new Request("https://cloudflare.com", { cache: "no-store", }); const response = await fetch(request); return response; }, }; TypeScript export default { async fetch(req, env, ctx): Promise<Response> { const request = new Request("https://cloudflare.com", { cache: 'no-store'}); const response = await fetch(request); return response; } } satisfies ExportedHandler<Environment> When you set the value to no-store on a subrequest made from a Worker, the Cloudflare Workers runtime will not check whether a match exists in the cache, and not add the response to the cache, even if the response includes directives in the Cache-Control HTTP header that otherwise indicate that the response is cacheable. This increases compatibility with NPM packages and JavaScript frameworks that rely on setting the cache property, which is a cross-platform standard part of the Request interface. Previously, if you set the cache property on Request, the Workers runtime threw an exception. If you've tried to use @planetscale/database, redis-js, stytch-node, supabase, axiom-js or have seen the error message The cache field on RequestInitializerDict is not implemented in fetch — you should try again, making sure that the Compatibility Date of your Worker is set to on or after 2024-11-11, or the cache_option_enabled compatibility flag is enabled for your Worker. Learn how the Cache works with Cloudflare Workers Enable Node.js compatibility for your Cloudflare Worker Explore Runtime APIs and Bindings available in Cloudflare Workers

2024/11/11
articleCard.readMore

Workers, Workflows - Workflows is now in open beta

Workflows is now in open beta, and available to any developer a free or paid Workers plan. Workflows allow you to build multi-step applications that can automatically retry, persist state and run for minutes, hours, days, or weeks. Workflows introduces a programming model that makes it easier to build reliable, long-running tasks, observe as they progress, and programmatically trigger instances based on events across your services. Get started You can get started with Workflows by following our get started guide and/or using npm create cloudflare to pull down the starter project: npm create cloudflare@latest workflows-starter -- --template "cloudflare/workflows-starter" You can open the src/index.ts file, extend it, and use wrangler deploy to deploy your first Workflow. From there, you can: Learn the Workflows API Trigger Workflows via your Workers apps. Understand the Rules of Workflows and how to adopt best practices

2024/10/24
articleCard.readMore