Connect RPC is a family of libraries for building browser-compatible and gRPC-compatible HTTP APIs. A developer writes a Protocol Buffers schema and the service logic, and Connect generates the code for marshalling, routing, compression, content-type negotiation and type-safe clients. It addresses two long-standing gRPC frictions: browsers cannot speak gRPC directly, and a plain gRPC endpoint cannot be called with curl or inspected easily. Connect was created by Buf, which describes it as its family of alternatives to Google’s gRPC implementations, and Buf announced it as a CNCF project in June 2024. The CNCF page lists it as a Sandbox project, accepted on April 13, 2024.
CNCF daily · Sprint 2, day 4 · Remote Procedure Call
At a glance
| Category | Orchestration & Management › Remote Procedure Call |
| CNCF status | Sandbox. Accepted April 13, 2024 |
| Written in | Per-language libraries: Go (connect-go) is the reference; TypeScript, Swift, Kotlin and Python implementations also exist |
| License | Apache 2.0 |
| Protocols | Connect (HTTP/1.1, HTTP/2 and HTTP/3), gRPC, and gRPC-Web, selectable per client |
| Schema language | Protocol Buffers |
| Language status (project docs) | Go, TypeScript/JavaScript and Swift stable; Kotlin and Python beta |
Architecture
flowchart TB
PROTO[Protobuf schema<br/>.proto files] ==>|buf generate| GEN[Generated code<br/>messages, handlers, clients]
GEN -->|clients| CLI
subgraph CALLERS[Callers]
BR[Browser app]
CURL[curl and scripts]
CLI[Connect clients<br/>Go, TypeScript, Swift]
GRPCC[Existing gRPC clients]
end
BR -->|Connect or gRPC-Web| GW
CURL -->|JSON over HTTP| GW
CLI -->|Connect protocol| GW
GRPCC -->|gRPC over HTTP 2| GW
GW[Ingress or gateway<br/>HTTP proxy] ==> SRV[Connect server<br/>net http handler]
GEN ==>|handlers| SRV
SRV ==> LOGIC[Service logic<br/>interceptors and business code]
classDef actor fill:#eceff1,stroke:#455a64,stroke-width:1.5px,color:#1d1c1a
classDef core fill:#0f766e,stroke:#064e4a,stroke-width:2px,color:#ffffff
classDef ctrl fill:#ede7f6,stroke:#5e35b1,stroke-width:1.5px,color:#1d1c1a
classDef data fill:#e3f2fd,stroke:#1565c0,stroke-width:1.5px,color:#1d1c1a
classDef store fill:#fff3e0,stroke:#e65100,stroke-width:1.5px,color:#1d1c1a
classDef sec fill:#fce4ec,stroke:#ad1457,stroke-width:1.5px,color:#1d1c1a
classDef obs fill:#e8f5e9,stroke:#2e7d32,stroke-width:1.5px,color:#1d1c1a
class PROTO store
class GEN ctrl
class BR,CURL,GRPCC actor
class CLI,SRV core
class GW,LOGIC data
style CALLERS fill:#78909c12,stroke:#78909c,stroke-width:2px
Key: teal blocks are the project itself, blue are workloads and proxies, purple are control and configuration, amber are storage, red are security and identity, green are observability, grey are external actors. Thick arrows show the primary path, thin solid arrows other data flows, dashed arrows control, discovery and telemetry.
| Component | Responsibility |
|---|---|
| Protobuf schema | The contract: services, methods and messages, kept in a repository or a schema registry. |
| Code generation | protoc-gen-go plus the Connect plugin (run through Buf) produce message types, a server handler interface and a typed client. |
| Server handler | A standard HTTP handler (for Go, an http.Handler) that accepts all three protocols by default, so any gRPC, gRPC-Web or Connect client can call it. |
| Client | A generated client that uses the Connect protocol by default, with a switch to gRPC or gRPC-Web without other code changes. |
| Interceptors | Middleware for authentication, logging, metrics and tracing that applies to unary and streaming calls. |
| Connect protocol | A simple HTTP protocol: unary calls are ordinary POST requests with JSON or binary Protobuf bodies, so they work in browsers and with curl. |
Design principle. Connect builds on the standard HTTP libraries of each platform (net/http, fetch, URLSession) and does not ship its own HTTP stack. Because of that it runs behind ordinary load balancers and proxies, and unary calls do not require end-to-end HTTP/2. One implementation serves three wire protocols, and errors, headers, trailers and streaming behave the same whichever one is used.
Production reference design
A common pattern on EKS, GKE, AKS or on-premises Kubernetes: Go or TypeScript services expose Connect APIs, a gateway routes external traffic, and the schema is managed with Buf.
- Define and generate. Keep
.protofiles in a repository and lint them with Buf. A minimalbuf.gen.yaml:
Then runversion: v2 plugins: - remote: buf.build/protocolbuffers/go out: gen opt: paths=source_relative - remote: buf.build/connectrpc/go out: gen opt: paths=source_relativebuf generate. - Serve the handler. In Go, mount the generated handler on a mux. Using
h2callows HTTP/2 without TLS behind the cluster ingress, which streaming calls need:mux := http.NewServeMux() path, handler := greetv1connect.NewGreetServiceHandler(&GreetServer{}) mux.Handle(path, handler) http.ListenAndServe(":8080", h2c.NewHandler(mux, &http2.Server{})) - Deploy as an ordinary Deployment and Service. Add readiness and liveness probes, resource limits and at least two replicas. The gRPC service type is not required, because Connect is plain HTTP.
- Route traffic at the gateway. Any HTTP-capable ingress or Gateway API implementation works. For streaming RPCs, enable HTTP/2 to the upstream explicitly (for NGINX, as the project’s FAQ notes); unary RPCs need no special settings.
- Test with curl. The Connect protocol makes a quick check possible without extra tools:
curl --header "Content-Type: application/json" \ --data '{"name": "Jane"}' \ https://api.example.com/greet.v1.GreetService/Greet - Add interceptors for authentication, request IDs, metrics and OpenTelemetry tracing, and run
buf breakingin CI so a schema change cannot silently break clients.
Typical production uses are internal service-to-service APIs, public APIs consumed by web and mobile apps, and gradual replacement of REST or gRPC-Web proxies with a single typed contract.
Operational considerations
- Scaling: handlers are stateless HTTP servers, so scale them with the Horizontal Pod Autoscaler on CPU or request rate. Long-lived streams spread unevenly across pods, so set connection or stream lifetimes that allow rebalancing.
- High availability: run multiple replicas across zones and set sensible deadlines on every call. The project’s FAQ advises short deadlines and repeated calls for browser server-streaming, because intermediaries may time out long streams.
- Security: terminate TLS at the gateway or the pod, authenticate in interceptors, and validate input. Treat the JSON form of the protocol as a public attack surface and apply size limits.
- Cost and sizing: the libraries are light and add little over the HTTP server; the main costs are those of the gateway and the services themselves.
- Common pitfalls:
- Assuming browsers can stream both ways: client streaming from browsers is limited.
- Forgetting HTTP/2 on proxies in front of streaming endpoints.
- Treating the Kotlin and Python implementations as stable when the project lists them as beta.
- Changing field numbers in the schema, which breaks wire compatibility.
Adoption
Buf’s CNCF announcement names CrowdStrike, PlanetScale, RedPanda, Chick-fil-A, Bluesky and Dropbox as organisations using Connect. The CNCF project page does not list adopters, so the list rests on the project maintainers’ own statement. Buf itself runs Connect in production, and the project documents Go as used in production by Buf and others. The project is governed through an RFC process in which community maintainers hold votes equal to those of Buf employees.
Alternatives
| Solution | Model | Best suited to |
|---|---|---|
| gRPC (CNCF Incubating) | Google’s RPC framework over HTTP/2 | Server-to-server systems that need the widest language support and tooling |
| gRPC-Gateway (NON CNCF) | Generates a REST/JSON proxy in front of a gRPC server | Teams that want to keep gRPC servers and add a REST face |
| Twirp (NON CNCF) | Small Protobuf RPC framework over HTTP/1.1 and JSON | Simple internal APIs without streaming |
| tRPC (NON CNCF) | End-to-end typed APIs for TypeScript projects | Full-stack TypeScript teams that do not need cross-language contracts |
| REST with OpenAPI | Resource-oriented HTTP APIs described by OpenAPI | Public APIs that must be consumed by any client without code generation |
Strengths and limitations
| Strengths | Limitations |
|---|---|
| One handler speaks Connect, gRPC and gRPC-Web, so no translating proxy is needed for browsers | Sandbox project with a smaller community than gRPC |
| Works with curl and standard HTTP tooling for unary calls | Language coverage is narrower: Kotlin and Python are beta, and other languages rely on contributors |
| Interoperates with existing gRPC clients and servers | Browser streaming has limits, especially for client streaming |
| Built on standard HTTP libraries, so it runs behind ordinary proxies | Maintainers are concentrated at one company, Buf, despite the community governance |
| Type-safe generated clients and Buf tooling for linting and breaking-change checks | Teams still need to learn Protobuf and a code generation workflow |
Recommendation
Trial Connect RPC for new APIs that serve both browsers and backend services, and for teams that find gRPC-Web proxies or curl-less debugging a recurring cost. Start with Go or TypeScript services, where the project marks the libraries stable, and keep the gRPC protocol available for existing clients. Teams already committed to gRPC in languages that Connect does not cover should stay on gRPC for now and revisit as the ecosystem grows.
References: CNCF project page · Connect documentation · Connect FAQ · Buf: Connect RPC joins the CNCF · CNCF presentations page · connect-go on GitHub