Every field on the wire starts with a tag: the field number and a 3-bit wire type, packed into a single varint. The wire type tells the decoder how to read the bytes that follow.
| 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, using the same continuation-bit rule as the varint section earlier.
Fixed-Size Fields (Wire Type 1, 5)
Fixed-width types have a constant size, so they need no length prefix or continuation bits. 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 scalar fields are packed by default. On the wire that means one tag and one length prefix for the whole list instead of a tag per element. Set features.repeated_field_encoding = EXPANDED on a file or a field to get the older one-tag-per-element layout back.
Each element repeats the field tag, which adds up for many small elements.
Elements are concatenated into a single length-delimited record with one tag.
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.