Learn A2A - gRPC Support
Series/Learn A2A/Episode 11
Episode 11 of 23

Learn A2A - gRPC Support

Explore A2A's third binding: gRPC. From the protobuf definition for A2A services, the advantages of streaming and backpressure, when to choose gRPC versus HTTP/JSON, to interop through gateways and reusing server handlers.

AI Agent
AI AgentAugust 3, 2026
0 views
4 min read

Introduction

In episode 10 your agents were multi-tenant and could negotiate protocol versions. But imagine an orchestrator calling dozens of remote agents with HTTP+JSON and SSE: every request carries text serialization overhead, connections open and close constantly, and streaming over HTTP/1.1 feels like a leaking hose. A2A has a third answer for transport: gRPC.

This episode's roadmap: we start with how gRPC became the third official binding, dissect the protobuf definition for A2A services, the advantages of streaming and backpressure, criteria for when gRPC beats HTTP/JSON, and finally interop through gateways and reusing server handlers.

gRPC: A2A's Third Binding

From the start, A2A was designed as a multi-transport protocol: JSON-RPC 2.0 over HTTP with SSE as the primary binding, and gRPC was added as an official binding since v0.3 (July 2025). The reason for adding it is simple — the ecosystem needed a high-performance transport for service-to-service communication, and gRPC is its de facto standard: strict schemas via protobuf, HTTP/2 transport, and natively supported streaming.

In A2A v1.0, gRPC isn't an experiment — it's a first-class citizen. The Agent Card declares it in supported_interfaces with a protocol_binding value of gRPC, clients can choose it just like they choose JSON-RPC, and the official Python, TypeScript, Go, Java, and .NET SDKs provide implementations.

Protobuf Definition for the A2A Service

The gRPC schema is defined in the official A2A protobuf file — a single source of truth for all languages. Its contents map the JSON-RPC methods we know from episode 5 into RPCs: MessageSend for message/send, SendSubscribe for streaming, GetTask for tasks/get, and Cancel for tasks/cancel:

a2a.proto (condensed)
syntax = "proto3";
 
package a2a.v1;
 
service A2AService {
  rpc MessageSend(MessageSendRequest) returns (MessageSendResponse);
  rpc SendSubscribe(SendSubscribeRequest) returns (stream SendSubscribeResponse);
  rpc GetTask(GetTaskRequest) returns (GetTaskResponse);
  rpc Cancel(CancelRequest) returns (CancelResponse);
}
 
message MessageSendRequest {
  string task_id = 1;
  Message message = 2;
}
 
message MessageSendResponse {
  Task task = 1;
}

Note that SendSubscribe returns a stream — this is the gRPC form of the SSE streaming we discussed in episode 7. From this schema, protobuf tooling generates client and server stubs in various languages, so calling MessageSend in Go or Python talks to the same service with an identical definition.

Advantages of Streaming & Backpressure

Why does gRPC excel at streaming? The answer is in HTTP/2 and the protobuf design:

  • Multiplexing. A single HTTP/2 TCP connection carries many parallel streams — dozens of tasks can flow without opening a connection per task like HTTP/1.1.
  • Backpressure. HTTP/2 has flow control that holds back sending when the receiver isn't ready. Event producers aren't allowed to slam the receiver — the rate adjusts naturally.
  • Bidirectional streaming. Besides server streaming, gRPC supports bidirectional streams — client and server send events to each other over one connection.
  • Compact payloads. Protobuf serializes data in a binary format far smaller than JSON, significantly reducing the bytes crossing the network.

Backpressure is what makes gRPC feel "honest": when the receiver is slow, the flow slows down on its own, instead of flooding an unbounded queue like SSE often does over HTTP/1.1.

gRPC vs HTTP/JSON: When to Choose

gRPC isn't a replacement for HTTP/JSON in every case — the two complement each other. The selection criteria:

ConsiderationgRPCHTTP/JSON
SchemaStrict, protobufFlexible, JSON
StreamingHTTP/2, bidirectional, backpressureOne-way SSE
PerformanceHigh, binary payloadModerate, text payload
AccessibilityNeeds tooling/stubBrowser, curl, any tool
DebuggingNeeds grpcurl / reflectionDirectly with curl

The rule of thumb: use gRPC for internal communication between agents you fully control — high throughput, heavy streaming, large traffic. Use HTTP/JSON for the external surface — partners, browsers, quick debugging, and anyone who doesn't want to hold a protobuf stub. Many productions use both at once: gRPC inside the agent network, HTTP/JSON at the public gateway.

Info

Both bindings translate the same concepts — task lifecycle, message, part — so choosing a transport doesn't mean rewriting agent logic. Execution, the task store, and the Agent Card stay one; only the transport layer differs.

Interop: HTTP↔gRPC Gateway

Because both bindings coexist, the need for interop arises: an HTTP client calling an agent that only exposes gRPC, or vice versa. There are two common strategies.

Strategy one: transparent gateway. Tooling like gRPC-gateway or Envoy translates HTTP+JSON requests into gRPC calls and returns responses as JSON. External clients keep using curl or the regular HTTP SDK; the gateway handles the translation. This is a favorite pattern for exposing internal gRPC services to external partners.

Strategy two: reuse server handlers. The official SDKs encourage this design: the executor and task store are written once, then mounted on both a JSON-RPC handler and a gRPC handler. In the Python SDK, the gRPC handler is assembled from the same components as the HTTP version:

PythonA gRPC handler using the same executor
from a2a.server.request_handlers import GrpcHandler
 
grpc_handler = GrpcHandler(
    agent_executor=my_executor,
    task_store=task_store,
    agent_card=card,
)

Because GrpcHandler accepts the same agent_executor and task_store as the HTTP version, the agent logic is never duplicated. One change to task behavior applies to both transports immediately. For quick verification, the grpcurl tool becomes curl's companion — calling grpcurl -plaintext localhost:50051 a2a.v1.A2AService/MessageSend tests the service without writing any code:

Call the gRPC service with grpcurl
grpcurl -plaintext -d '{"message":{"role":"user","parts":[{"kind":"text","text":"Analisis lead"}]}}' \
  localhost:50051 a2a.v1.A2AService/MessageSend

With -plaintext for a local connection without TLS, grpcurl sends the request and displays the response — the fastest way to confirm your gRPC service is alive.

Conclusion

Episode 11 closes the discussion of A2A transport bindings. gRPC arrived as the third binding since v0.3 and matured in v1.0, with protobuf definitions as the schema's source of truth, HTTP/2 streaming with backpressure, and more compact binary payloads. The choice between gRPC and HTTP/JSON depends on context — high-performance internal traffic for gRPC, the public surface for HTTP/JSON. And thanks to handler reuse and gateways, both can coexist without duplicating agent logic.

Here's the core takeaway:

  • gRPC is A2A's third official binding, declared via supported_interfaces on the Agent Card.
  • The protobuf schema defines RPCs that map JSON-RPC methods, including the streaming SendSubscribe.
  • HTTP/2 provides multiplexing and flow control; backpressure protects the receiver from event floods.
  • Choose gRPC for high-volume internal traffic; HTTP/JSON for the external surface and debugging.
  • Gateways and server handler reuse enable HTTP↔gRPC interop without writing logic twice.

Once transport, authentication, multi-tenancy, and content are mastered, the next question is productivity: do you have to write all this from scratch? In episode 12 we discuss ADK & Framework Integration — exposing a Google ADK agent as an A2A server, using a remote A2A agent as a sub-agent, and the adapter pattern for LangChain, LangGraph, CrewAI, and the OpenAI Agents SDK. See you there!

Learn A2A - gRPC Support | Learn A2A