Chapter 28: gRPC Internals — The Wire Protocol

gRPC Message Framing

Each gRPC message on the wire is prefixed with a 5-byte header:

// Length-Prefixed Message format:
┌──────────────┬────────────────────────┐
│ Compressed   │    Message Length       │
│  (1 byte)    │     (4 bytes, BE)      │
├──────────────┴────────────────────────┤
│         Protobuf-encoded message       │
│         (Message Length bytes)          │
└────────────────────────────────────────┘

// Example: 10-byte protobuf message, uncompressed:
00 00 00 00 0A [10 bytes of protobuf data]

HTTP/2 Mapping

// Request:
:method: POST
:path: /package.Service/Method
:authority: server:port
content-type: application/grpc
te: trailers
grpc-timeout: 5S

// Response trailers (AFTER body):
grpc-status: 0
grpc-message: (empty for success)

Compression

// gRPC supports per-message compression:
// Compressed byte = 1 → message is gzip/deflate compressed
// Negotiated via grpc-accept-encoding header
// Useful for large messages, adds CPU overhead for small ones