Skip to main content
Protobuf

Protocol Buffers

Active

Google's language-neutral, platform-neutral mechanism for serializing structured data. Schemas defined in .proto files compile to language-specific code. Significantly smaller and faster than JSON for the same data.

Data FormatBinaryIDLGooglegRPC2008

In one line

Protocol Buffers (Protobuf) is Google's binary serialization format and IDL. .proto files define message schemas that compile to type-safe code in 10+ languages. Wire encoding uses 4 wire types (varint, 64-bit, length-delimited, 32-bit). Protobuf is the wire format for gRPC and is 3-10x smaller than equivalent JSON.

Quick Reference

FieldSizeDescription
Tag encodingvarinttag = (field_number << 3) | wire_type. Field 1, wire type 0 = 0x08.
Wire type 0VarintVariable-length integer. 7 bits per byte, MSB = continuation bit. Signed uses zigzag.
Wire type 164-bit8 bytes little-endian. Used for fixed64, sfixed64, double.
Wire type 2Length-delimitedVarint length prefix, then bytes. Used for string, bytes, embedded messages, packed repeated.
Wire type 532-bit4 bytes little-endian. Used for fixed32, sfixed32, float.
Field numbers1-5368709111-15 encode in 1 byte (use for frequent fields). 16-2047 in 2 bytes. 19000-19999 reserved.
MIME types2application/protobuf (binary), application/x-protobuf (legacy). RFC 9996.

Key Characteristics

Compact binary

3-10x smaller than JSON for equivalent data. Field names not transmitted – only field numbers.

Schema-first

.proto schema required for encoding and decoding. Breaking changes (removing fields, changing types) require field number management.

gRPC transport

gRPC uses Protobuf as its default serialization. HTTP/2 frames carry length-prefixed Protobuf messages.

Forward compatible

Unknown fields are preserved. Old clients can read new messages. New clients can read old messages. Field numbers must never be reused.

Message Format

Request
http
// .proto schema definition
syntax = "proto3";

message SearchRequest {
  string query = 1;
  int32  page  = 2;
  int32  limit = 3;
}

// Wire encoding of SearchRequest{query:"foo", page:1, limit:10}
// Field 1 (query "foo"):  0x0a 0x03 0x66 0x6f 0x6f
//   0x0a = tag (field=1, wire_type=2=length-delimited)
//   0x03 = length 3
//   0x66 0x6f 0x6f = "foo"
// Field 2 (page 1):       0x10 0x01
//   0x10 = tag (field=2, wire_type=0=varint)
//   0x01 = varint 1
// Field 3 (limit 10):     0x18 0x0a
//   0x18 = tag (field=3, wire_type=0=varint)
//   0x0a = varint 10
Response
http
// Varint encoding examples:
// 1   = 0x01
// 127 = 0x7f
// 128 = 0x80 0x01  (two bytes: continuation bit set)
// 300 = 0xac 0x02

// Zigzag encoding (sint32/sint64):
// 0  → 0,  -1 → 1,  1 → 2,  -2 → 3
// n >= 0: (n << 1)
// n <  0: ((-n-1) << 1) | 1

// gRPC message framing:
// [1 byte compressed flag][4 bytes big-endian length][N bytes protobuf]

Implementations

linuxsince protoc compiler + SDKs for C++, Java, Python, Go, Rust, C#, Ruby, PHP, Dart, Kotlinavailable
macossince protoc via Homebrew (brew install protobuf)available
windowssince protoc binary, NuGet Google.Protobufavailable
iossince SwiftProtobuf (Apple), protoc-gen-swiftavailable
androidsince protoc-gen-javalite, Kotlin/Java SDKavailable