Apache Iggy
Binary Protocol

Message batches

Messages travel and rest in exactly one layout, the batch: the SendMessages body, the replicated record, the persisted segment record, and the poll reply all share it. There is no other message encoding.

[batch header: 256 bytes][blob: message frames]
frame = [frame header: 48 bytes][payload][user_headers]

Batch header (256 bytes)

OffsetSizeFieldTypeDescription
08partition_idu64Server-stamped at admission. Producers send zero.
88base_offsetu64Server-stamped when the batch is appended to the partition journal. Producers send zero.
168base_timestampu64Server-stamped at journal append (microseconds). Producers send zero.
248origin_timestampu64Producer-set: the earliest origin_timestamp among the batch's messages (microseconds).
328batch_lengthu64Total batch size: 256 + blob length.
408batch_checksumu64XxHash3-64 over the header fields (partition_id, base_offset, base_timestamp, origin_timestamp, batch_length, message_count, in that order, little-endian bytes) followed by each frame's 8 checksum bytes. Recomputed by the server when it stamps the header.
484message_countu32Number of frames in the blob.
52204reservedbytesMust be zero; the server rejects a batch with nonzero reserved bytes.

Message frame header (48 bytes)

OffsetSizeFieldTypeDescription
08checksumu64XxHash3-64 over frame bytes 8..48 followed by payload and user_headers. Producer-computed; verified at admission.
816idu128Message id (for example a UUID).
244offset_deltau32Message offset = base_offset + offset_delta. Producer sends the frame's index in the batch.
284timestamp_deltau32Microsecond delta against the batch origin_timestamp. One batch spans at most about 71.6 minutes of producer clock (u32 microseconds).
324user_headers_lengthu32Byte length of the user headers block.
364payload_lengthu32Byte length of the payload.
408reservedu64Must be zero.

After the 48 header bytes: payload (payload_length bytes), then user_headers (user_headers_length bytes). The payload comes first.

A frame's absolute position is derived, not stored: offset = base_offset + offset_delta. The server-stamped time is the flat batch base_timestamp (the delta does not apply to it); producer time resolves as origin_timestamp + timestamp_delta.

The 64-byte IggyMessageHeader (checksum, id, offset, timestamp, origin_timestamp, lengths, reserved) that earlier protocol generations put in front of every message no longer exists on the wire or on disk. It survives only as an in-memory model.

On this page