Skip to content

A repeated field holds a list: zero or more values of one type, in the order they were added. The example has a list of numbers and a list of strings. An empty list writes no bytes, so on the wire it looks the same as a field that was never set. A repeated field has no presence to check, and generated code gives you an empty list until you add to it. Order is preserved when the list is encoded and decoded, and duplicates are allowed.

Repeated scalars, such as int32, float, bool, and enums, are packed by default: the whole list travels as one length-prefixed block instead of a tag per element, which keeps long lists of numbers compact. Strings, bytes, and messages can't be packed and are written one element at a time. The Binary chapter shows both layouts.

All four values share one entry for the field. Add more numbers and watch only the payload grow.

schema.proto
edition = "2024";

package demo.v1;

message Batch {
  repeated int32 ids = 1;
  repeated string tags = 2;
}
Input JSON (editable)
{
  "ids": [1, 2, 3, 150]
}
ProtoJSON

Compiling the schema...

Next

Maps

Protobuf map fields: which key and value types are allowed, the rules that constrain them, and how maps are really repeated entries underneath.