Map Fields in Protobuf
Define map fields in protobuf for key-value pairs. Learn about supported key types, value types, ordering behavior, and when to use maps vs repeated messages.
Detailed Explanation
Key-Value Data with Map Fields
Map fields provide a built-in way to define associative arrays (dictionaries, hash maps) in protobuf. They are syntactic sugar over repeated messages with key and value fields.
syntax = "proto3";
message UserProfile {
string user_id = 1;
string display_name = 2;
// String to string map (metadata, headers, labels)
map<string, string> attributes = 3;
// String to message map
map<string, Permission> permissions = 4;
// Integer key map
map<int32, string> error_messages = 5;
}
message Permission {
bool read = 1;
bool write = 2;
bool admin = 3;
}
Supported Key Types
Map keys can be any integral or string type: int32, int64, uint32, uint64, sint32, sint64, fixed32, fixed64, sfixed32, sfixed64, bool, or string. Floating point types (float, double) and bytes cannot be used as map keys.
Supported Value Types
Map values can be any type except another map. This means you can use scalar types, enums, or message types as values.
Important Behavior
| Aspect | Behavior |
|---|---|
| Ordering | Not guaranteed — iteration order may differ across languages and runs |
| Duplicate keys | Last value wins during parsing; behavior is undefined in text format |
| Default | Empty map (no entries) is the default; not serialized on wire |
| Wire format | Equivalent to repeated MapEntry { key_type key = 1; value_type value = 2; } |
Maps vs. Repeated Messages
Use maps when you need fast lookup by key and don't care about ordering. Use repeated messages when ordering matters or when you need multiple values per key.
Use Case
Storing configuration key-value pairs, HTTP headers, user metadata, feature flags, localization strings, or any data structure that naturally maps keys to values.