Skip to content

Changelog

New updates and improvements at Cloudflare.

Workers traces now automatically include JavaScript RPC session spans

Workers traces can now follow JavaScript RPC calls across Worker boundaries and into Durable Objects. Previously, a trace stopped at the caller's RPC boundary. The dashboard now shows the caller-side session and method calls alongside the callee invocation, nested calls, and callbacks into another Worker.

A session span covers the lifetime of a caller-side session and groups calls that reuse it. Individual call spans show each method invocation. Execution colors distinguish the Workers or Durable Object entrypoints involved, while arrows mark outgoing and incoming calls. Together, these details show where time was spent, which calls reused a session, and how returned stubs and callbacks fit into the request.

A Workers trace of a Worker-to-Worker RPC session, showing the session span, the caller's getCounter and increment call spans, and the callee's invocation and matching call spans

Enable tracing with one setting in your Wrangler configuration file:

{
  "$schema": "./node_modules/wrangler/config-schema.json",
  "observability": {
    "traces": {
      "enabled": true
    }
  }
}
[observability.traces]
enabled = true

Cloudflare records these spans automatically. You do not need to change your application code or add an observability SDK.

For supported spans and attributes, refer to Spans and attributes.

Durable Objects can use up to ten Dynamic Workers concurrently

Durable Objects can have up to ten distinct Dynamic Workers with in-flight requests, increased from four. This limit applies across all concurrent requests to the same Durable Object because they share an input/output (I/O) context. Other Workers can have up to four distinct Dynamic Workers with in-flight requests per request.

Multiple in-flight requests to the same Dynamic Worker count as one toward this limit.

For more information, refer to Dynamic Workers limits.

Inspect Worker startup performance with Wrangler

wrangler check startup now reports your Worker's raw and compressed bundle sizes. It also summarizes local CPU activity during startup directly in your terminal.

Large bundles and costly startup work can introduce cold-start latency, so use this command to find code and large dependencies that slow your Worker before it handles requests.

The summary includes sampled, active, garbage collection, and idle time. Wrangler continues to save a .cpuprofile file for detailed flamegraph analysis in Chrome DevTools or VS Code.

⛅️ wrangler 4.116.0
───────────────────────────────────────────────
├ Building your Worker
│ Worker Built! 🎉
│
├ Analysing
│ Startup phase analysed
│
│ Bundle: 7171.25 KiB / gzip: 2197.00 KiB
│
│ Local startup profile:
│   Profile window: 70.3 ms
│   Sampled time: 70.3 ms
│   Active: 38.5 ms (including 3.7 ms garbage collection)
│   Idle: 31.8 ms
│   Samples: 36
│
│ CPU Profile has been written to worker-startup.cpuprofile. Load it into the Chrome DevTools profiler (or directly in VSCode) to view a flamegraph.
│
│ Note that the CPU Profile was measured on your Worker running locally on your machine, which has a different CPU than when your Worker runs on Cloudflare.
│
│ As such, CPU Profile can be used to understand where time is spent at startup, but the overall startup time in the profile should not be expected to exactly match what your Worker's startup time will be when deploying to Cloudflare.

The profile runs locally, so its duration will differ from startup time on Cloudflare. For authoritative startup time, deploy your Worker or upload a version.

Available in Wrangler version 4.116.0 or later. For more information, refer to wrangler check startup.

Filter Durable Object logs and traces by instance ID

Workers Logs and OpenTelemetry spans for Durable Object requests include the Durable Object instance ID.

Use $workers.durableObjectId to filter logs for a specific instance. Root and child spans include the same ID in cloudflare.durable_object.id.

Query Builder filtering traces by Durable Object instance ID

Use these fields to isolate a specific instance and correlate its logs and traces.

For more information, refer to Durable Objects metrics and analytics and Workers tracing spans and attributes.

Track memory usage for Workers and Durable Objects in the dashboard

You can now monitor how much memory your Workers and Durable Objects consume across invocations with the new Memory Usage chart in the Workers Metrics tab, broken down by P50, P90, P99, and P999 percentiles.

Memory usage chart showing P50, P90, P99, and P999 percentiles with deployment markers

Memory usage measures the V8 isolate memory at the time of each invocation, subject to the 128 MB per-isolate limit — a single isolate can handle many concurrent requests and shares memory across them.

Use the Memory Usage chart to:

  • Track memory trends — Spot gradual increases that may indicate a memory leak before they cause Exceeded Memory errors.
  • Correlate with deployments — Deployment markers on the chart help you identify whether a new version introduced a memory regression.
  • Right-size your Worker — Understand your baseline memory footprint and how much headroom you have before hitting the 128 MB limit.

For Durable Objects, memory usage reflects the in-memory state an object holds (class properties, caches, active WebSocket connections), which persists across invocations until the object is hibernated or evicted. This state is not preserved across eviction, hibernation, or a crash, so persist anything important to storage.

To view memory usage, open the Metrics tab for your Worker ↗︎ or Durable Object namespace ↗︎. For Durable Objects, you can filter by DO ID or name to drill down into memory usage for a specific object. You can also query memory usage programmatically via the GraphQL Analytics API using the workersInvocationsAdaptive dataset — the quantiles.memoryUsageBytesP50 through quantiles.memoryUsageBytesP999 fields return percentile values in bytes.

For local memory debugging, you can also profile memory with DevTools to take heap snapshots and identify specific objects causing high memory usage.

Test Durable Object eviction with new cloudflare:test helpers

The @cloudflare/vitest-pool-workers package now includes evictDurableObject and evictAllDurableObjects test helpers, exported from cloudflare:test.

These helpers let you test how a Durable Object behaves across evictions, simulating the production lifecycle where an idle Durable Object can be evicted from memory.

For more context, refer to Lifecycle of a Durable Object.

import { evictDurableObject, evictAllDurableObjects } from "cloudflare:test";
import { env } from "cloudflare:workers";

const id = env.COUNTER.idFromName("my-counter");
const stub = env.COUNTER.get(id);

// Evict the Durable Object instance pointed to by a specific stub
await evictDurableObject(stub);

// Close WebSockets instead of hibernating them
await evictDurableObject(stub, { webSockets: "close" });

// Evict all currently-running Durable Objects in evictable namespaces
await evictAllDurableObjects();

These helpers are available in @cloudflare/vitest-pool-workers@0.16.20 and later.

Learn more in the Test APIs reference and the Testing Durable Objects guide.

Billable usage and budget alerts now in product sidebars

Pay-as-you-go customers can now view billable usage and create budget alerts directly from the product overview pages for Workers & Pages, D1, R2, Workers KV, Queues, Vectorize, Durable Objects, and Containers. A new sidebar widget shows current-period spend and the billing cycle date range, alongside a button to create a budget alert.

The widget pulls from the same data as the Billable Usage dashboard and aligns to your billing cycle (or the current day on Free plans), so the numbers match your invoice. Enterprise contract accounts are not yet supported.

Billable usage widget in the Durable Objects product sidebar showing current-period spend and a breakdown by service

Selecting Create budget alert opens the budget alert flow inline so you can set a dollar threshold in the same place you are reviewing usage. Budget alerts apply to your total account-level spend across all products, not just the product page you create them from.

For more information, refer to the Usage-based billing documentation.

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.