createBatch() now accepts an options object that creates up to 100 Workflow instances in one call. The result lists the created instances and explains why any others were not created. To use this form in local development and get its types from wrangler types, use Wrangler 4.148.0 or later.
To create instances that share the same options, pass count. Each instance receives a generated ID:
created contains the created instances. errors contains each entry that was not created, identified by its position in the input. IDs that already exist and IDs repeated within the batch are reported as errors instead of being skipped silently.
Passing an array to createBatch() is deprecated. Existing code that uses the array form continues to work.
Traffic to split tunnel excluded resources is no longer briefly blocked while the client is connecting or reconnecting. The client now keeps its learned split tunnel configuration across reconnects.
Support for routing non-RFC 1918 local IPv4 networks through the tunnel when unrestricted LAN inclusion is enabled by policy or MDM.
Faster connects and lower memory use. The hosts file is now read once and shared across the client’s DNS resolvers instead of being reloaded by each one.
Additional changes and improvements
Improved reauthentication reliability and fixed an issue where a reauthentication could force a new registration.
Improved client reaction to the current network lowering its MTU.
Improved DNS reliability on networks with lower MTUs by clamping the TCP maximum segment size (MSS) for DNS-over-HTTPS connections sent through the tunnel.
Individual DNS-over-HTTPS queries now time out instead of hanging when the upstream server stops responding.
Improved API reliability by retrying requests dropped when reusing pooled connections.
Added an MDM setting to prefer IPv4 when resolving hostnames in proxy mode. The setting is off by default.
Fixed the client reconnecting while Emergency Disconnect was active after switching organizations or re-registering.
Fixed the client being unable to connect after an upgrade when its stored registration credentials no longer matched its configuration.
Fixed the client service restarting unexpectedly when it was slow to respond, such as after waking from sleep.
Fixed Extra Logging failing to capture packets across all interfaces.
Fixed an issue that could prevent remote diagnostics from completing.
Fixed DNS connectivity checks failing on IPv6-only networks.
Fixed the client service exiting when its route-monitoring socket was closed after sleep or wake.
Fixed DNS enforcement checks making the client service unresponsive on systems with large routing tables.
Fixed slow captive portal checks causing the client service to become unresponsive or restart while connecting.
Fixed a race when switching tunnel protocols during key rotation that could prevent WireGuard from connecting.
Fixed the client continuing to report “No network” after a successful manual disconnect.
Fixed a client UI crash that could occur when the daemon connection was reset during an IPC request.
Fixed a startup crash when date formatting data for the system locale had not yet loaded.
Traffic to split tunnel excluded resources is no longer briefly blocked while the client is connecting or reconnecting. The client now keeps its learned split tunnel configuration across tunnel reconnections.
Support for routing non-RFC 1918 local IPv4 networks through the tunnel when unrestricted LAN inclusion is enabled by policy or MDM.
Improved connection reliability on devices with very large hosts files. The client now detects a large hosts file, allows more time for its initial DNS check, and shows a banner letting the user know that connecting may take longer.
Faster tunnel reconnections and lower memory use. The hosts file is now read once and shared across the client’s DNS resolvers instead of being reloaded by each one.
A service recovery mechanism, backed by a Windows scheduled task, now starts the client service on system unlock if it is not already running. This is enabled by default.
Additional changes and improvements
Improved reauthentication reliability and fixed an issue where a reauthentication could force a new registration.
Improved client reaction to the current network lowering its MTU.
Improved DNS reliability on networks with lower MTUs by clamping the TCP maximum segment size (MSS) for DNS-over-HTTPS connections sent through the tunnel.
Individual DNS-over-HTTPS queries now time out instead of hanging when the upstream server stops responding.
Improved API reliability by retrying requests dropped when reusing pooled connections.
Added an MDM setting to prefer IPv4 when resolving hostnames in proxy mode. The setting is off by default.
The client no longer requires the Windows WLAN AutoConfig service to be running.
Fixed the client reconnecting while Emergency Disconnect was active after switching organizations or re-registering.
Fixed the client being unable to connect after an upgrade when its stored registration credentials no longer matched its configuration.
Fixed the client service restarting unexpectedly when it was slow to respond, such as after waking from sleep.
Fixed the client service failing to restart after an unexpected termination.
Fixed the client UI getting stuck in a connecting state after sleep and wake even though the tunnel was connected.
Fixed slow captive portal checks causing the client service to become unresponsive or restart while connecting.
Fixed a race when switching tunnel protocols during key rotation that could prevent WireGuard from connecting.
Fixed the client continuing to report “No network” after a successful manual disconnect.
Fixed Digital Experience Monitoring (DEX) HTTP tests failing TLS validation.
Fixed latency spikes and traffic interruptions during TPM-backed API authentication when hardware-backed registration is enabled.
Fixed trailing whitespace in BIOS serial numbers causing serial-number and client-certificate device posture checks to fail.
Fixed the client UI crashing at startup when it could not write to the Windows registry.
Fixed a client UI crash that could occur when the daemon connection was reset during an IPC request.
Fixed a startup crash when date formatting data for the system locale had not yet loaded.
Known issues
A Windows DNS client regression may cause connectivity check failures on systems containing large hosts files. While this release includes a fix to mitigate this issue, users may still experience reduced DNS performance and connectivity check failures.
Traffic to split tunnel excluded resources is no longer briefly blocked while the client is connecting or reconnecting. The client now keeps its learned split tunnel configuration across reconnects.
Support for routing non-RFC 1918 local IPv4 networks through the tunnel when unrestricted LAN inclusion is enabled by policy or MDM.
Faster tunnel reconnections and lower memory use. The hosts file is now read once and shared across the client’s DNS resolvers instead of being reloaded by each one.
Added an MDM setting to prefer IPv4 when resolving hostnames in proxy mode. The setting is off by default.
Additional changes and improvements
Improved reauthentication reliability and fixed an issue where a reauthentication could force a new registration.
Improved client reaction to the current network lowering its MTU.
Improved DNS reliability on networks with lower MTUs by clamping the TCP maximum segment size (MSS) for DNS-over-HTTPS connections sent through the tunnel.
Individual DNS-over-HTTPS queries now time out instead of hanging when the upstream server stops responding.
Improved API reliability by retrying requests dropped when reusing pooled connections.
Fixed the client reconnecting while Emergency Disconnect was active after switching organizations or re-registering.
Fixed the client being unable to connect after an upgrade when its stored registration credentials no longer matched its configuration.
Fixed the client service restarting unexpectedly when it was slow to respond, such as after waking from sleep.
Fixed the client window not appearing on first launch after a fresh install on RHEL 10.
Fixed duplicate WARP routing policy rules accumulating on reconnect.
Fixed slow captive portal checks causing the client service to become unresponsive or restart while connecting.
Fixed a race when switching tunnel protocols during key rotation that could prevent WireGuard from connecting.
Fixed the client continuing to report “No network” after a successful manual disconnect.
Fixed a client UI crash that could occur when the daemon connection was reset during an IPC request.
Fixed a startup crash when date formatting data for the system locale had not yet loaded.
Known issues
When in DNS Only mode, the client may send DNS queries for names that are configured for Local Domain Fallback to the encrypted DNS server instead of falling back to the system configuration. Local Domain Fallback works as expected in other client modes.
Cloudflare Organizations is now generally available for Enterprise customers and MSSP/Distributor partners.
Organizations provides a top-level container for centrally managing accounts, members, analytics, and shared policies. Organization Super Administrators receive implicit access to every account in their Organization without requiring separate account memberships.
Enterprise customers can manage accounts in a single-tier Organization. MSSP/Distributor partners can use nested sub-organizations to manage customer accounts.
Organization Roles remains in beta, and current product limitations still apply.
Cloudflare CASB now supports custom finding types, giving security teams full control over the security conditions CASB detects across their SaaS and cloud integrations.
In addition to CASB's library of standard finding types, you can now write your own detection logic using Rego ↗︎, the open-source policy language from Open Policy Agent (OPA). Use custom finding types to match your organization's own thresholds and exceptions, such as flagging admin accounts without two-factor authentication, and get higher-confidence findings to act on.
Key capabilities
Write your own detection logic — Define exactly what CASB flags using Rego expressions evaluated against asset data from your connected integrations.
Target any supported provider and asset class — Scope a custom finding type to a provider (such as Google Workspace or Microsoft 365) and asset class (such as users, files, or groups), and apply it to all integrations for that provider or a selected subset.
Built-in validation — Select Validate to check your expression for syntax errors and schema issues before you create the finding type.
Inspect and duplicate standard finding types — Open any standard finding type to view its detection logic, then duplicate it as the starting point for a custom finding type.
Works with CASB policies — Use custom finding types in CASB remediation policies to send matching findings to Slack, ServiceNow, or any other webhook destination.
Get started
In Cloudflare One ↗︎, go to Cloud & SaaS findings > Findings library.
Select Create finding.
Enter a name, description, and severity.
Select a provider and asset class, then set the integration scope.
Write your Rego expression and select Validate.
Select Create finding.
CASB evaluates the custom finding type against assets as they are created or updated within the selected scope. Matching assets appear as posture finding instances under Posture Findings.
BGP peering over IPsec and GRE tunnels is generally available for Cloudflare WAN and Magic Transit. You can use it for production workloads.
BGP peering exchanges routes dynamically between your devices and your Cloudflare virtual network routing table. You no longer need to update static routes manually as your network changes.
BGP over IPsec and GRE tunnels is available to all accounts that use Unified Routing. No enablement is required. BGP over CNI remains in closed beta.
The strict service token authentication setting applies consistent behavior to requests made with service tokens. When the setting is on for a Zero Trust organization, Access handles requests with service token headers as follows:
If authentication or authorization fails, Access always returns 401 or 403 instead of redirecting the client to the login page with 302.
Only Service Auth policies can authorize the request. Access ignores Allow policies and any CF_Authorization cookie sent with the request.
Access does not return a CF_Authorization cookie to the client after successful authentication. Subsequent requests should continue to use service token headers.
Zero Trust organizations created on or after October 5, 2026 have strict service token authentication turned on by default and cannot turn it off. Cloudflare recommends that existing organizations turn it on as well.
Organizations created before October 5, 2026 can configure the setting in the dashboard or through the API.
The Agents SDK now provides first-class support for building agents using the Pi harness. You can build long-running agents using the combination of Pi 1.0 ↗︎, Pi Durable ↗︎, and the new PiHarness class that the Cloudflare Agents SDK provides, ensuring your agent's work is durably persisted, even if interrupted mid-turn.
Built with Earendil ↗︎, this integration is our first step toward first-class support for third-party agent harnesses on Cloudflare.
PiHarness is a new "Lifecycle capability" provided by the Cloudflare Agents SDK. Pi Durable provides the agent harness and the Lifecycle is responsible for keeping the agent running in the Durable Object. The Lifecycle is a core concept in the Agents SDK ensuring that long-running work can run in a Durable Object, surviving restarts, crashes, and network issues. We will share more on Lifecycle capabilities in the near future.
Install
npm i agents@latest @earendil-works/pi-durable @earendil-works/pi-ai
The agents/models/pi-ai entry point supports AI Gateway and Workers AI models, so you can get started with Cloudflare models right away or use your existing Pi AI provider.
Add tools with extensions
Both tools and system prompt sections are provided to the Pi Harness via extensions.
import { Type } from "@earendil-works/pi-ai";import { skills } from "agents/harness/pi";const WordCount = Type.Object({ text: Type.String() });const wordCount = { name: "word_count", description: "Count the words in a text.", parameters: WordCount, replay: "safe", async execute({ text }) { const words = text.split(/\s+/).filter(Boolean).length; return { content: [{ type: "text", text: String(words) }] }; },};// In the harness factory, before Harness.open():registry.install({ name: "editor", sections: [ { key: "preamble", render: () => "You are an editor.", tag: false }, ], tools: [wordCount],});registry.install(await skills(sources));
import { Type } from "@earendil-works/pi-ai";import type { ToolRegistration } from "@earendil-works/pi-durable";import { skills } from "agents/harness/pi";const WordCount = Type.Object({ text: Type.String() });const wordCount: ToolRegistration<typeof WordCount> = { name: "word_count", description: "Count the words in a text.", parameters: WordCount, replay: "safe", async execute({ text }) { const words = text.split(/\s+/).filter(Boolean).length; return { content: [{ type: "text", text: String(words) }] }; },};// In the harness factory, before Harness.open():registry.install({ name: "editor", sections: [ { key: "preamble", render: () => "You are an editor.", tag: false }, ], tools: [wordCount],});registry.install(await skills(sources));
For more information on creating and configuring extensions, refer to Extensions.
You can now restrict who can access a Quick Tunnel. Use the new --allowed-mail flag in cloudflared to require visitors to authenticate with a one-time PIN sent to their email before they reach your local service.
Previously, anyone with a trycloudflare.com URL could access the service behind it. Protected Quick Tunnels let you share a local development server, webhook receiver, or demo with specific people without creating a Cloudflare account or configuring a domain.
You can allow:
A single email address: --allowed-mail alice@example.com
Multiple email addresses, by repeating the flag or using a comma-separated list: --allowed-mail 'alice@example.com,bob@example.com'
Every address on a domain: --allowed-mail '*@example.com'
Visitors do not need a Cloudflare account. Access ends for everyone when you stop the cloudflared process.
@cloudflare/workers-oauth-provider ↗︎ is now v1, with a new split API. One Worker acts as the authorization server: it signs users in and issues tokens. Your MCP server acts as the resource server, and can run in another Worker. It validates each token with the authorization server over a Service Binding, without crossing the public Internet.
A migration skill ↗︎ ships in the npm package so a coding agent can perform the upgrade.
The split API
import { OAuthAuthorizationServer, OAuthResourceServer, insufficientScope,} from "@cloudflare/workers-oauth-provider";import { WorkerEntrypoint } from "cloudflare:workers";// auth-server Worker: signs users in and issues tokens for both MCP servers.const authorizationServer = new OAuthAuthorizationServer({ issuer: "https://auth.example.com", resources: [ "https://calendar.example.com/mcp", "https://drive.example.com/mcp", ], scopesSupported: ["calendar:read", "calendar:write", "offline_access"], clientIdMetadataDocumentEnabled: true,});export class AuthServer extends WorkerEntrypoint { fetch(request) { if (new URL(request.url).pathname === "/authorize") { return showConsent(request, this.env); } return authorizationServer.fetch(request, this.env, this.ctx); } validateToken(resource, token) { return authorizationServer.validateToken(resource, token, this.env); }}// calendar MCP Worker: checks tokens with AuthServer over a Service Binding.export const calendar = new OAuthResourceServer({ resourceMetadata: { resource: "https://calendar.example.com/mcp", authorization_servers: ["https://auth.example.com"], }, requiredScopes: ["calendar:read"], validateToken: (env) => env.AUTH_SERVER.validateToken, handler: { fetch(request, env, ctx) { if ( request.method === "POST" && !ctx.auth.scope.includes("calendar:write") ) { return insufficientScope(ctx.auth, ["calendar:read", "calendar:write"]); } return handleMcp(request, ctx.props); }, },});
import { OAuthAuthorizationServer, OAuthResourceServer, insufficientScope,} from "@cloudflare/workers-oauth-provider";import { WorkerEntrypoint } from "cloudflare:workers";// auth-server Worker: signs users in and issues tokens for both MCP servers.const authorizationServer = new OAuthAuthorizationServer<Env>({ issuer: "https://auth.example.com", resources: [ "https://calendar.example.com/mcp", "https://drive.example.com/mcp", ], scopesSupported: ["calendar:read", "calendar:write", "offline_access"], clientIdMetadataDocumentEnabled: true,});export class AuthServer extends WorkerEntrypoint<Env> { fetch(request: Request) { if (new URL(request.url).pathname === "/authorize") { return showConsent(request, this.env); } return authorizationServer.fetch(request, this.env, this.ctx); } validateToken(resource: string, token: string) { return authorizationServer.validateToken(resource, token, this.env); }}// calendar MCP Worker: checks tokens with AuthServer over a Service Binding.export const calendar = new OAuthResourceServer<Env, AuthProps>({ resourceMetadata: { resource: "https://calendar.example.com/mcp", authorization_servers: ["https://auth.example.com"], }, requiredScopes: ["calendar:read"], validateToken: (env) => env.AUTH_SERVER.validateToken, handler: { fetch(request, env, ctx) { if ( request.method === "POST" && !ctx.auth.scope.includes("calendar:write") ) { return insufficientScope(ctx.auth, ["calendar:read", "calendar:write"]); } return handleMcp(request, ctx.props); }, },});
In the example, env.AUTH_SERVER.validateToken is that Service Binding call. The calendar Worker needs no KV namespace of its own.
{ "name": "calendar-mcp", "main": "src/index.ts", // Set this to today's date "compatibility_date": "2026-10-11", "services": [ { "binding": "AUTH_SERVER", "service": "auth-server", "entrypoint": "AuthServer", }, ],}
name = "calendar-mcp"main = "src/index.ts"# Set this to today's datecompatibility_date = "2026-10-11"[[services]]binding = "AUTH_SERVER"service = "auth-server"entrypoint = "AuthServer"
OAuthResourceServer publishes the RFC 9728 ↗︎ protected resource metadata that MCP clients use to find your authorization server. It answers requests without a token with a 401 challenge that points to that metadata. It also rejects tokens issued for any other resource.
You can still use OAuthProvider as both the authorization server and the MCP server. For most 0.x deployments, the only required change is to add resourceMetadata: { resource }.
Artifacts, Cloudflare's versioned file system that speaks Git, is now in open beta. Artifacts is built for scale, so you can create a repository per project, user, session, or task.
With Artifacts, you can:
Deploy repositories to Workers — Connect an Artifacts repository through Workers Builds. Pushes to the production branch deploy the updated Worker, while other branches create or update Worker Previews.
Programmatically manage repositories — Use an Artifacts binding from a Worker to create or fork repos, inspect files and commits, read files by path, and issue repo-scoped Git tokens.
React to repository changes — Subscribe to events when a repository is created, imported, forked, deleted, pushed to, cloned, or fetched.
Control where repository data is stored — Choose to store and process your data in the US or EU.
Monitor repository usage — View total operations, pulls, pushes, errors, and error rates in the Cloudflare dashboard or via API for analytics.
Artifacts is available for customers on the Workers Paid plan. Cloudflare will begin billing for Artifacts on October 14, 2026.
Build the next GitHub on Cloudflare
We are hosting a competition to see who can build the next GitHub on Cloudflare using Workers and Artifacts.
Apply today ↗︎ — submissions are open until October 14, 2026.
The first-place team will receive $25,000 in Cloudflare credits. The top three teams will be flown to San Francisco to present what they built at Cloudflare Connect.
You can now tag targets using only the Zero Trust Write API token permission. Previously, tagging targets through the API required both Zero Trust Write and Tag Write permissions on the API token.
The Workers Web Crypto API now supports ML-KEM-768, ML-KEM-1024, ML-DSA-44, ML-DSA-65, and ML-DSA-87. ML-KEM establishes shared secrets, while ML-DSA signs and verifies data.
The opt-in API also adds key encapsulation and decapsulation methods, getPublicKey(), SubtleCrypto.supports(), and JSON Web Keys (JWKs) with the AKP key type.
Turn on the webcrypto_modern_algorithms compatibility flag to use these features:
Workers implements a subset of the evolving Modern Algorithms in the Web Cryptography API ↗︎ draft. ML-KEM-512 and the draft's other algorithms are not supported. The API may change as the draft evolves.
This beta release includes the following changes and improvements:
Fixed an issue that could briefly block traffic to split tunnel excluded resources while the client was connecting or reconnecting.
Improved reauthentication reliability and fixed an issue where a reauthentication could force a new registration.
Improved client reaction to the current network lowering its MTU.
Added support for routing non-RFC 1918 local IPv4 networks through the WARP tunnel when unrestricted LAN inclusion is enabled by policy or MDM.
Improved DNS reliability on networks with lower MTUs by clamping the TCP maximum segment size (MSS) for DNS-over-HTTPS connections sent through the tunnel.
Improved API reliability by retrying requests dropped when reusing pooled connections.
The client no longer requires the Windows WLAN AutoConfig service to be running.
Implemented a service recovery mechanism backed by Windows scheduler task to start WARP service on system unlock if not already started.
Fixed slow captive portal checks causing the client service to become unresponsive or restart while connecting.
Fixed a race when switching tunnel protocols during key rotation that could prevent WireGuard from connecting.
Fixed the client continuing to report 'No network' after a successful manual disconnect.
Fixed Digital Experience Monitoring (DEX) HTTP tests failing TLS validation on Windows.
Fixed the client UI crashing at startup when it could not write to the Windows registry.
Fixed latency spikes and traffic interruptions during TPM-backed API authentication when hardware-backed registration is enabled.
Fixed trailing whitespace in BIOS serial numbers causing serial-number and client-certificate device posture checks to fail.
Fixed a client UI crash that could occur when the daemon connection was reset during an IPC request.
Fixed a startup crash when date formatting data for the system locale had not yet loaded.
Isolation policies support role-based access control (RBAC). Because isolation policies are Gateway HTTP policies with the Isolate action, Gateway's account-level and resource-scoped roles apply to them directly.
Use the Zero Trust HTTP Policies Admin account-level role to grant access to all HTTP policies in the account. You can also assign a resource-scoped role to let a team member manage a specific isolation policy without exposing other Gateway resources.
Policy settings such as copy/paste, file download/upload, keyboard, and printing are part of the policy object and follow the same permissions.
This beta release includes the following changes and improvements:
Fixed an issue that could briefly block traffic to split tunnel excluded resources while the client was connecting or reconnecting.
Improved reauthentication reliability and fixed an issue where a reauthentication could force a new registration.
Improved client reaction to the current network lowering its MTU.
Added support for routing non-RFC 1918 local IPv4 networks through the WARP tunnel when unrestricted LAN inclusion is enabled by policy or MDM.
Improved DNS reliability on networks with lower MTUs by clamping the TCP maximum segment size (MSS) for DNS-over-HTTPS connections sent through the tunnel.
Improved API reliability by retrying requests dropped when reusing pooled connections.
The client no longer requires the Windows WLAN AutoConfig service to be running.
Implemented a service recovery mechanism backed by Windows scheduler task to start WARP service on system unlock if not already started.
Fixed slow captive portal checks causing the client service to become unresponsive or restart while connecting.
Fixed a race when switching tunnel protocols during key rotation that could prevent WireGuard from connecting.
Fixed the client continuing to report 'No network' after a successful manual disconnect.
Fixed Digital Experience Monitoring (DEX) HTTP tests failing TLS validation on Windows.
Fixed the client UI crashing at startup when it could not write to the Windows registry.
Fixed latency spikes and traffic interruptions during TPM-backed API authentication when hardware-backed registration is enabled.
Fixed trailing whitespace in BIOS serial numbers causing serial-number and client-certificate device posture checks to fail.
Fixed a client UI crash that could occur when the daemon connection was reset during an IPC request.
Fixed a startup crash when date formatting data for the system locale had not yet loaded.
This beta release includes the following changes and improvements:
Fixed an issue that could briefly block traffic to split tunnel excluded resources while the client was connecting or reconnecting.
Improved reauthentication reliability and fixed an issue where a reauthentication could force a new registration.
Improved client reaction to the current network lowering its MTU.
Added support for routing non-RFC 1918 local IPv4 networks through the WARP tunnel when unrestricted LAN inclusion is enabled by policy or MDM.
Improved DNS reliability on networks with lower MTUs by clamping the TCP maximum segment size (MSS) for DNS-over-HTTPS connections sent through the tunnel.
Improved API reliability by retrying requests dropped when reusing pooled connections.
Fixed Extra Logging failing to capture packets across all interfaces.
Fixed an issue that could prevent remote diagnostics from completing.
Fixed DNS connectivity checks failing on IPv6-only networks.
Fixed the client service exiting when its route-monitoring socket was closed after sleep or wake.
Fixed DNS enforcement checks making the client service unresponsive on systems with large routing tables.
Fixed slow captive portal checks causing the client service to become unresponsive or restart while connecting.
Fixed a race when switching tunnel protocols during key rotation that could prevent WireGuard from connecting.
Fixed the client continuing to report 'No network' after a successful manual disconnect.
Fixed a client UI crash that could occur when the daemon connection was reset during an IPC request.
Fixed a startup crash when date formatting data for the system locale had not yet loaded.
You can now tell a person on a laptop apart from a Mesh node or an AI agent running on Workers, without matching on connector email addresses or Mesh IP ranges — and see exactly which Cloudflare Tunnel and cloudflared replica received each session.
Mesh — Traffic sent from or delivered to a Cloudflare Mesh node. Previously, Mesh nodes were logged the same way as devices running the Cloudflare One Client, because Mesh nodes run the client in headless mode.
Workers VPC — Traffic sent by a Worker through a Workers VPC binding. Previously, Workers VPC sessions were not recorded in Network Session Logs.
Gateway network logs
To view these values in the dashboard, go to Zero Trust > Insights & Logs > Logs > Network logs, select Columns, and turn on Traffic Source and Traffic Destination. Both values also appear under Network query details when you open a log entry.
Network Session Logs
The zero_trust_network_sessions dataset, available through Logpush, includes the following fields:
Field
Description
OnrampType
How the session entered Cloudflare One. Values: CF1_CLIENT, MESH, WORKERS_VPC, MAGIC, OTHER.
Offramp
Where the session was routed. Sessions routed to a Mesh node report MESH.
SourceName
Name of the Worker that started the session. Only populated for Workers VPC sessions.
SourceID
Stable identifier of the Worker that started the session. Only populated for Workers VPC sessions.
DestinationReplicaID
The replica that served the session, such as a specific replica of a Mesh node or a cloudflared replica of a Cloudflare Tunnel.
For example, OnrampType = 'WORKERS_VPC' AND Offramp = 'MESH' returns every session where a Worker reached a service behind a Mesh node, and SourceName tells you which Worker it was.
See which tunnel and replica received a session
With DestinationReplicaID, you can now confirm which Cloudflare Tunnel and which cloudflared replica received traffic for a specific session. Combine it with the existing DestinationTunnelID field to trace a session to an exact tunnel replica — or Mesh node replica — when you run multiple replicas for high availability. The replica ID matches the Connector ID shown in the dashboard, so you can stream that replica's logs with cloudflared tail --connector-id.
Workers Cache now supports invalidate(), the soft counterpart of purge(). purge() deletes matching cached responses, so the next request is a cache miss. invalidate() keeps them but marks them stale, so the cache revalidates them with your Worker instead.
To revalidate a response, the cache sends your Worker a conditional request built from the validators stored with it — for example, If-None-Match carrying the cached ETag. If your Worker answers 304 Not Modified, the cache keeps the stored body. If your Worker answers with a full 200 response, that response replaces the cached one.
invalidate() accepts the same options as purge(): tags, pathPrefixes, or purgeEverything. It follows the same per-entrypoint scoping and resolves to the same result object. Call it as ctx.cache.invalidate(), or import cache from cloudflare:workers and call cache.invalidate().
Use invalidate() when one call covers many cached responses but only some of them changed. Your Worker needs to emit ETag or Last-Modified and answer matching conditional requests with 304. Each unchanged response then costs a validator check instead of a full regeneration:
src/index.jsjs
export default { async fetch(request, env, ctx) { if (request.method === "POST") { // Write the updated catalog, then mark every cached product page stale. await syncCatalog(env, await request.json()); await ctx.cache.invalidate({ tags: ["products"] }); return new Response("Synced"); } const product = await getProduct(env, request); const etag = `"${product.revision}"`; const headers = { "Cache-Control": "public, max-age=86400", "Cache-Tag": "products", ETag: etag, }; // The product has not changed since it was cached. Answer 304, and the // cache keeps the body it already has. if (request.headers.get("If-None-Match") === etag) { return new Response(null, { status: 304, headers }); } return new Response(renderProductPage(product), { headers }); },};
src/index.tsts
export default { async fetch(request, env, ctx): Promise<Response> { if (request.method === "POST") { // Write the updated catalog, then mark every cached product page stale. await syncCatalog(env, await request.json()); await ctx.cache.invalidate({ tags: ["products"] }); return new Response("Synced"); } const product = await getProduct(env, request); const etag = `"${product.revision}"`; const headers = { "Cache-Control": "public, max-age=86400", "Cache-Tag": "products", ETag: etag, }; // The product has not changed since it was cached. Answer 304, and the // cache keeps the body it already has. if (request.headers.get("If-None-Match") === etag) { return new Response(null, { status: 304, headers }); } return new Response(renderProductPage(product), { headers }); },} satisfies ExportedHandler<Env>;
The Cloudflare CLI, cf, is now in beta. cf is one command-line interface for the public Cloudflare API and for Workers projects. Use it to manage zones, DNS, storage, and security settings, and to create, develop, and deploy Workers, without switching between tools.
Install cf globally, then sign in:
npm install --global cf
yarn global add cf
pnpm add --global cf
bun add --global cf
cf auth login
With cf, you can:
Manage resources across Cloudflare. More than 2,900 commands cover the public Cloudflare API, and most print their results as JSON.
Create and deploy Workers.cf init creates a project that uses cloudflare.config.ts, a typed configuration file. cf dev, cf build, and cf deploy develop, build, and deploy it.
Move from Wrangler.cf migrate converts a Wrangler configuration file to cloudflare.config.ts. You can also run cf resource commands in an existing Wrangler project without migrating it.
Work with coding agents.cf cli search finds the command for a task from a plain-language description, so an agent can find and run commands without prior knowledge of cf.
cf is in beta. Commands, configuration, and Build Output can change before the stable release.
A Worker can now call the Workflows it declares in the exports field of its Wrangler configuration through ctx.exports. You no longer need a workflows binding to call a Workflow from the Worker that defines it.
Each Workflow is keyed by class name, and has the same API as a Workflow binding:
A workflows binding and a workflow export with the same name share their instances. You can move a Workflow from a binding to an export without losing its instances.
wrangler dev, the Cloudflare Vite plugin, and the Workers Vitest integration run Workflows on ctx.exports locally. Local development requires Wrangler 4.142.0, @cloudflare/vite-plugin 1.61.0, or @cloudflare/vitest-plugin 1.3.0 or above.
In Vitest, introspectWorkflow() and introspectWorkflowInstance() still need a Workflow binding. To introspect a Workflow declared in exports, add a test-only binding to it.
Custom spans in Workers now support more of the OpenTelemetry span API, so you can instrument more of your code and record errors directly on your spans.
tracing.startSpan(name) creates a span without making it the active span, and returns it. Other spans do not nest under it. Call span.end() when the operation is complete.
tracing.getActiveSpan() returns the currently active span. Use it to annotate the current span from helper functions and libraries without passing the span object through your code. Outside any custom span, it returns the invocation's root span.
span.recordException(exception) records an exception event on a span. It accepts an Error, a string, or an object with a code, name, or message.
span.setAttributes(attributes) sets multiple attributes at once. setAttribute() and setAttributes() now return the span, so you can chain calls.
Workers Metrics charts now show every release in the selected time range, including the full progression of gradual deployments. This makes it easier to correlate changes in memory, CPU time, errors, or latency with the code that was serving traffic.
A gradual deployment appears as a single rollout across the chart, with shading that increases as more traffic moves to the new version. Hover over a rollout to see the previous and new versions, the rollout duration, and the traffic percentage configured at each step.
Use these annotations to:
Find when a regression started — See which traffic percentage was configured when errors, latency, CPU time, or wall time changed.
Compare rollout stages — Check whether a metric changed as more traffic moved to the new version.
Confirm rollbacks — Rollbacks appear as separate release events, so you can check whether metrics recovered after a rollback.
Direct deployments that send 100% of traffic to a single version still appear as individual markers. Nearby direct deployments are grouped to reduce visual clutter. Versions that are only uploaded, or only configured at 0%, do not appear on metrics charts.
To view release annotations, open the Metrics tab for your Worker ↗︎.