Skip to content

An int32 in memory is four bytes whether it holds 3 or three hundred million. A varint is not. It uses one byte for small numbers and grows only when the number needs the room, which is why field numbers 1 through 15 cost so little.

The trick is that only 7 bits of each byte carry the number. The top bit, the most significant one, is spent on bookkeeping. It is set to 1 on every byte except the last, so a decoder reading bytes one at a time knows to keep going until it hits a byte whose top bit is 0. That byte is the end.

The 7-bit groups come out least significant group first. So the number is written backwards from how you would say it, and a decoder has to read the whole varint before it knows what value it has. In practice this never matters to you, but it does explain why varints show up reversed if you ever dump the bytes by hand.

Varint encoding steps
1

Chunk Data

The number gets split into 7-bit groups. A byte has 8 bits, so that leaves the top one free to use as a continuation bit.

Group 1
0000001
Group 0
0010110
2

Reverse & Add MSB Flag

Those groups go out least significant first, which is the little-endian order. Every byte then gets its top bit set to 1, apart from the last one.

Byte 0
10010110
MSBDATA
0x96
Byte 1
00000001
MSBDATA
0x01

Further Reading

Next

ZigZag

Why negative numbers are expensive as plain varints and how ZigZag encoding maps signed integers to small unsigned ones for sint32 and sint64.