Article summary — original
Cloudflare Workers and Containers Introduce Inbound TCP and gRPC Support in Private Beta
Cloudflare has announced inbound TCP connection support and native gRPC capabilities for Workers and Containers in private beta, aimed at supporting low-latency applications such as real-time voice AI.
A new connect() handler in the Workers runtime and Spectrum integration allow raw inbound TCP sockets to be routed to Workers, Durable Objects, and Containers.
Developers can run containerized gRPC servers in any language with full bidirectional streaming across Cloudflare's 330+ locations.
Cloudflare automatically translates between gRPC and gRPC-web, enabling lightweight unary gRPC servers and clients directly inside standard Workers.
Inbound TCP Sockets and Spectrum Routing
The Workers runtime now features a connect() handler that receives a raw socket for reading and writing. Inbound traffic is captured using a new Cloudflare Spectrum application type that directs TCP connections to a designated Worker. From there, sockets can be passed between Workers, sent to Durable Objects, or routed directly into Containers, giving developers full-duplex control over arbitrary TCP-based protocols in any programming language.
Full-Duplex gRPC in Containers
The combination of raw TCP handling and Cloudflare Containers allows teams to deploy standard gRPC servers across more than 330 network locations. This supports bidirectional streaming over persistent connections, which is particularly beneficial for voice AI interfaces and colocated inference requiring low latency between clients and models.
Bidirectional gRPC-Web Translation for Workers
For lightweight implementations that do not require containers, Cloudflare bridges HTTP/2 gRPC traffic and the Workers runtime by translating inbound gRPC to gRPC-web and outbound gRPC-web to gRPC. This approach works around web API limitations regarding HTTP/2 framing, allowing developers to build unary gRPC servers and clients with tools like the connectrpc package while preserving Cloudflare security inspection features such as WAF and Bot Management.
Saved original article
AI is changing how people interact with computers, and voice is becoming an increasingly important part of that shift. Real-time assistants, AI-powered dictation, and other voice interfaces need low-latency communication between clients, models, and supporting services. Many developers use [gRPC](https://grpc.io/), a Remote Procedure Call (RPC) framework built on HTTP/2 and TCP, for this infrastructure.
Ever since Workers [launched in 2017](https://blog.cloudflare.com/introducing-cloudflare-workers/), we’ve been expanding their capabilities, including adding the ability to [open outbound TCP connections](https://blog.cloudflare.com/workers-tcp-socket-api-connect-databases/) and a [JavaScript-native RPC system](https://blog.cloudflare.com/workers-javascript-modules/) built on [Cap’n Proto](https://capnproto.org/). And so as part of Agents Week, we’re extending Workers in the other direction, supporting inbound TCP connections and adding new ways to run gRPC applications on Cloudflare.
Today, we’re announcing:
We’re introducing this in private beta — you can sign up [here](https://forms.gle/Q2SoJLUKjBFGxBgW6).
Let’s dig into each of these below.
The Workers runtime now provides a [connect() handler](https://developers.cloudflare.com/workers/runtime-apis/handlers/) that accepts a socket that you can read from and write to:
You can pass this socket from one Worker to another Worker, or from a Worker to a Durable Object. This lets your Worker control where an incoming TCP connection is routed:
You can pass a socket from a Durable Object to [its Container](https://developers.cloudflare.com/durable-objects/api/container/):
And then handle the socket in the container:
This gives you full control over the entire path from client to your server running in a container on Cloudflare, opening the door to full-duplex communication between client and server running any program, in any language, for any TCP-based protocol.
To expose the raw TCP socket to the client, we’re introducing a new type of [Spectrum](https://developers.cloudflare.com/spectrum/) application, where you specify a Worker that you want incoming TCP connections to be routed to. [Spectrum](https://developers.cloudflare.com/spectrum/) is Cloudflare’s ingress proxy for non-HTTP traffic, and allows Cloudflare to sit in front of any TCP or UDP application.
[gRPC](https://grpc.io/) is a well-established and popular Remote Procedure Call (RPC) framework that was initially released by Google almost 10 years ago, and is now used across mobile apps, distributed systems, and most recently — voice AI applications.
Real-time voice AI applications demand low-latency, and both client and server to be able to send messages to each other over a single, persistent connection. WebSockets and Durable Objects are excellent fits for this, and the Cloudflare Agents SDK provides [@cloudflare/voice](https://developers.cloudflare.com/agents/communication-channels/voice/) to make this easy. But there is a ton of software out there that uses gRPC for real-time client-server communication.
Using the APIs described above, you can now deploy gRPC servers to Cloudflare, written in any language, with full support for bidirectional streaming between client and server. This lets you take advantage of Cloudflare’s network of [330+ locations](https://www.cloudflare.com/network/) and handle requests much closer to clients than is possible elsewhere. We’re excited about the doors this opens up for low-latency voice and colocated inference.
For example, here’s a minimal gRPC server that echoes messages it receives back to the client:
With this, there’s pretty much no gRPC-based application that you can’t deploy to Cloudflare, no matter what language it’s in or dependencies it relies on. But what if you need to do something simpler, and just serve a basic gRPC server or connect from a Worker to a gRPC server running somewhere else?
[gRPC-web](https://grpc.io/docs/platforms/web/basics/) is a browser-compatible version of gRPC. Web browsers don’t expose the lower-level HTTP/2 features that gRPC requires, and there is no raw TCP Socket API built into web browsers — this is why the WebSocket API exists, and why Workers have supported WebSockets [since 2021](https://blog.cloudflare.com/introducing-websockets-in-workers/).
HTTP/2 splits each request and response into small binary messages called [frames](https://httpwg.org/specs/rfc7540.html#FramingLayer). This is core to how a single HTTP/2 or HTTP/3 connection is able to multiplex — many requests can be interleaved over one connection. Each frame has a stream ID, allowing the receiver to reassemble it into the correct request or response. gRPC depends on this stream-level control for efficient streaming, cancellation, flow control, and [trailers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Trailer).
Web platform APIs like [fetch()](https://developers.cloudflare.com/workers/runtime-apis/fetch/) don’t provide this control. So how can we make it simple and easy to use gRPC from Cloudflare Workers — without clients needing to make any changes? We translate incoming gRPC to gRPC-web, and translate outgoing gRPC-web to gRPC.
We’ve actually used gRPC-web within Cloudflare’s reverse proxy since 2020, when we wrote about the [Road to gRPC](https://blog.cloudflare.com/road-to-grpc/#converting-to-http11) on the Cloudflare blog. We convert requests to HTTP/1.1 so that messages can be inspected and gRPC apps can benefit from [Cloudflare’s security features](https://www.cloudflare.com/solutions/security/), like WAF rules and Bot Management.
Now, in private beta and then rolling out to everyone, we’re extending this so that given a Protocol Buffer (protobuf) definition file like this:
You can write a unary gRPC server in a Worker in just a few lines of code, using the [@connectrpc/connect](https://connectrpc.com/) open-source package:
You can make outbound requests to external gRPC servers this way too, by using the client built into [@connectrpc/connect](http://@connectrpc/connect):
Your code uses gRPC-web, but when it speaks to the outside world, it is automatically translated into gRPC. This means that clients and servers that you already depend on don’t need to change. For example, you can:
We’re introducing everything from this post in private beta — you can sign up [here](https://forms.gle/Q2SoJLUKjBFGxBgW6).
At Cloudflare, we use [Cap’n Proto](https://capnproto.org/) and [Cap’n Web](https://blog.cloudflare.com/capnweb-javascript-rpc-library/) and the [JavaScript-native RPC system that is built into Cloudflare Workers](https://blog.cloudflare.com/javascript-native-rpc/) instead of gRPC. And when we ship things, we always aim to be using them ourselves. So in this case, we want to first work closely with a smaller set of developers using gRPC, and make sure we’ve nailed it before turning this on for everyone.
More broadly, we’re excited to continue to push the bounds of what types of traffic the Workers platform can serve, going beyond TCP and into UDP-based protocols. Keep [telling us what you want to build](https://x.com/CloudflareDev) on Workers, and we’ll keep pushing the bounds of what is possible.