Skip to content

Changelog

New updates and improvements at Cloudflare.

Storage
hero image
  1. 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 architecture

    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:

    Terminal window
    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:

    Example R2 bucket created event
    {
    "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.

  1. 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.

  1. 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.

    JavaScript
    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".

    JavaScript
    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.

    JavaScript
    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.

  1. 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:

    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:

    Terminal window
    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",
    }),
    },
    });

    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.

  1. 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.

  1. 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:

    Python
    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:

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

    Then define the storage backend for your Durable Object:

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

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

    npx wrangler dev

    Consult the Durable Objects documentation for more details.

  1. 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.

  1. 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:

    Terminal window
    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.

  1. 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.

  1. 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 consumer
    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 queue
    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.

  1. 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.

    JavaScript
    // 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.

  1. 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.

    TypeScript
    // 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.

  1. 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 pipeline
    $ 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.

  1. 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:

    Terminal window
    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.

  1. 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:

    Terminal window
    # 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:

    Terminal window
    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.

  1. 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.

  1. 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.

    TypeScript
    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.

  1. 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.

  1. 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

    JavaScript
    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:

  1. 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.

    JavaScript
    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.

  1. 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 queue
    $ 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 queue
    $ 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.

  1. 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.

  1. 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

    Terminal window
    npx wrangler r2 bucket lock add <bucket> --name 180-days-all --retention-days 180

    Prevent deletion or overwriting of all logs indefinitely (via prefix)

    Terminal window
    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.

  1. 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.

    Super Slurper S3-Compatible Source

    For more information on Super Slurper and how to migrate data from your existing S3-compatible storage buckets to R2, refer to our documentation.

  1. 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 period
    $ 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.