Every field on the wire is wrapped in an "envelope." The envelope tells the decoder which field number it is and how to read the payload. Both get packed into a single tag value, encoded as a varint.
| Wire type | Protobuf types |
|---|---|
| 0 (Varint) | |
| 1 (I64) | |
| 2 (LEN) | also used for packed repeated scalars |
| 3 (SGROUP) | group start (deprecated) |
| 4 (EGROUP) | group end (deprecated) |
| 5 (I32) |
Varint Fields (Wire Type 0)
Most numeric types use Wire Type 0. The length is implicit because the decoder reads bytes one by one until it finds a byte where the MSB is 0. That's the same continuation-bit rule from the varint section earlier, doing the delimiting on its own.
Fixed-Size Fields (Wire Type 1, 5)
Some types have a known size, so nothing needs to be measured. Wire Type 1 is always 8 bytes, used by double and fixed64. Wire Type 5 is always 4 bytes, used by float and fixed32. The decoder reads that many bytes after the tag.
Length-Delimited (Wire Type 2)
string, bytes, and nested message fields use Length-Delimited encoding. These fields carry an explicit length prefix, encoded as a varint, right after the tag. That prefix tells the decoder exactly how many of the bytes that follow belong to this field.
Packed Repeated Fields
Repeated fields of primitive types use a specialized encoding that avoids repeating the field tag for every element. Edition 2024 packs them by default. Set features.repeated_field_encoding to opt a file, message, or field back out.
Each element repeats the field tag. High overhead for many small elements.
Elements are concatenated into a single length-delimited record. One tag for the whole set.
Further Reading
- Message structure, in the encoding reference
The official wire-type table and the rules for how tags frame each payload.
- Repeated elements and packed encoding
The reference treatment of repeated fields on the wire, including when they pack and when they don't.
Next
Map Encoding
How Protobuf maps look on the wire: each entry as a repeated key/value message, and why that representation keeps old decoders compatible.