Skip to content

Changelog

New updates and improvements at Cloudflare.

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.

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:

{
	"durable_objects": {
		"bindings": [
			{
				"name": "MY_DURABLE_OBJECT",
				"class_name": "MyDurableObject"
			}
		]
	}
}
[[durable_objects.bindings]]
name = "MY_DURABLE_OBJECT"
class_name = "MyDurableObject"

Then define the storage backend for your Durable Object:

{
	"migrations": [
		{
			"tag": "v1", // Should be unique for each entry
			"new_sqlite_classes": [ // Array of new classes
				"MyDurableObject"
			]
		}
	]
}
[[migrations]]
tag = "v1"
new_sqlite_classes = [ "MyDurableObject" ]

Then test your new Durable Object locally by running wrangler dev:

npx wrangler dev

Consult the Durable Objects documentation for more details.

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 ↗︎.

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.

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:

Cloudflare R2 Dashboard

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.

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:

Create a queue with a pull based consumersh
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:

Pull messages from a queuebash
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.

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.

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

Today, we are launching R2 Data Catalog in open beta, a managed Apache Iceberg catalog built directly into your Cloudflare R2 bucket.

If you are 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.

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:

Create a pipelinebash
$ 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.

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.

Deploy to Cloudflare

To learn more about how read replication was implemented, go to our blog post ↗︎.

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.

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.

Hyperdrive provides edge connection setup and global connection pooling for optimal latencies.

Visit the docs to get started with Hyperdrive for PostgreSQL or MySQL.

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.

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.

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:

Deploy to Cloudflare

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:

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 ↗︎.

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.

Pause and resume a queuebash
$ 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:

Purge a queuebash
$ 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.

Pause and purge using the dashboard

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.

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.

Hyperdrive query latency decreases by 90% during Hyperdrive's gradual rollout of regional pooling.

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.

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.

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.

Customize a queue's message retention period

You can customize the retention period on the settings page for your queue, or using Wrangler:

Update message retention periodbash
$ 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.

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!)

Super Slurper Objects Migrated

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.

Automatic configuration for private databases on Hyperdrive

Hyperdrive now automatically configures your Cloudflare Tunnel to connect to your private database.

Automatic configuration of Cloudflare Access and Service Token in the Cloudflare dashboard for Hyperdrive.

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.

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.

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.

D1 Worker API latency

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.