Skip to content

Maps aren't a native wire-level primitive. They're syntactic sugar for a repeated message, nothing more.

map<string, int32> items = 1;
Is equivalent to:
message Entry {
  string key = 1;
  int32 value = 2;
}
repeated Entry items = 1;

On the wire, each entry is an ordinary length-delimited sub-message, with the key in field 1 and the value in field 2. A decoder that has never heard of maps still parses the data correctly, just as a repeated field. That's what keeps maps compatible with older Protobuf implementations.

This representation also explains a couple of things that surprise people. Entries carry no defined order. And when the same key shows up twice in a payload, the last one wins, exactly like it would when merging a repeated field.

Further Reading

  • Maps in the language guide

    The official maps documentation, including the backwards-compatibility note behind the repeated-entry representation on this page.

Next

Presence

Why unset and default-valued Protobuf fields take zero bytes on the wire, and how that interacts with field presence semantics when decoding.