Commands
Catalog
The u32 command codes. Replicated commands are identified on the wire by their operation byte (see Operation discriminants). The code column below is the protocol-level registry and, for non-replicated commands, the value carried in header bytes 196..200.
# System
PING = 1 # non-replicated; works without login
GET_STATS = 10 # non-replicated
GET_SNAPSHOT = 11 # non-replicated
GET_CLUSTER_METADATA = 12 # non-replicated
DESCRIBE_OPTIONS = 13 # non-replicated
GET_ME = 20 # non-replicated
GET_CLIENT = 21 # non-replicated
GET_CLIENTS = 22 # non-replicated
# Users
GET_USER = 31 # non-replicated
GET_USERS = 32 # non-replicated
CREATE_USER = 33 # operation 141
DELETE_USER = 34 # operation 143
UPDATE_USER = 35 # operation 142
UPDATE_PERMISSIONS = 36 # operation 145
CHANGE_PASSWORD = 37 # operation 144
LOGIN_USER = 38 # legacy; server rejects with MalformedLogin eviction
LOGOUT_USER = 39 # operation 3 (Logout)
LOGIN_REGISTER = 40 # operation 1 (Register)
LOGIN_REGISTER_WITH_PAT = 45 # operation 1 (Register)
# Personal access tokens
GET_PERSONAL_ACCESS_TOKENS = 41 # non-replicated
CREATE_PERSONAL_ACCESS_TOKEN = 42 # operation 146
DELETE_PERSONAL_ACCESS_TOKEN = 43 # operation 147
LOGIN_WITH_PERSONAL_ACCESS_TOKEN = 44 # legacy; server rejects with MalformedLogin eviction
# Messages
POLL_MESSAGES = 100 # non-replicated
SEND_MESSAGES = 101 # operation 160
FLUSH_UNSAVED_BUFFER = 102 # parses, but always fails with FeatureUnavailable
# Consumer offsets
GET_CONSUMER_OFFSET = 120 # non-replicated
STORE_CONSUMER_OFFSET = 121 # operation 161
DELETE_CONSUMER_OFFSET = 122 # operation 162
# Streams
GET_STREAM = 200 # non-replicated
GET_STREAMS = 201 # non-replicated
CREATE_STREAM = 202 # operation 128
DELETE_STREAM = 203 # operation 130
UPDATE_STREAM = 204 # operation 129
PURGE_STREAM = 205 # operation 131
# Topics
GET_TOPIC = 300 # non-replicated
GET_TOPICS = 301 # non-replicated
CREATE_TOPIC = 302 # operation 132
DELETE_TOPIC = 303 # operation 134
UPDATE_TOPIC = 304 # operation 133
PURGE_TOPIC = 305 # operation 135
# Partitions
CREATE_PARTITIONS = 402 # operation 136
DELETE_PARTITIONS = 403 # operation 137
# Segments
DELETE_SEGMENTS = 503 # operation 138
# Consumer groups
GET_CONSUMER_GROUP = 600 # non-replicated
GET_CONSUMER_GROUPS = 601 # non-replicated
CREATE_CONSUMER_GROUP = 602 # operation 139
DELETE_CONSUMER_GROUP = 603 # operation 140
JOIN_CONSUMER_GROUP = 604 # operation 148
LEAVE_CONSUMER_GROUP = 605 # operation 149
SYNC_CONSUMER_GROUP = 606 # non-replicatedFLUSH_UNSAVED_BUFFER still decodes on the wire, but the server has no on-demand flush primitive and answers every call with FeatureUnavailable. Per-topic durability is configured with the enforce_fsync topic option instead.
Payloads
Payloads below are the request body (the bytes after the 256-byte header). Types reference the shared encodings. Empty payload means the body has zero bytes.
System
Ping. Code: 1. Empty payload. The only command accepted before login.
Get stats. Code: 10. Empty payload.
Get snapshot. Code: 11.
[compression: u8][types_count: u8][snapshot_type: u8] x types_countCompression codes: 1 = Stored, 2 = Deflated, 3 = Bzip2, 4 = Zstd, 5 = Lzma, 6 = Xz. Snapshot type codes: 1 = FilesystemOverview, 2 = ProcessList, 3 = ResourceUsage, 4 = Test, 5 = ServerLogs, 6 = ServerConfig, 100 = All.
Get cluster metadata. Code: 12. Empty payload.
Describe options. Code: 13.
[scope: u8]Scope: 1 = topic, 2 = stream, 3 = user. Returns the option catalog for the scope: keys, value kinds, defaults, and descriptions. See Options block.
Get me. Code: 20. Empty payload.
Get client. Code: 21.
[client_id: u32]Get clients. Code: 22. Empty payload.
Streams
Get stream. Code: 200.
[stream_id: Identifier]Get streams. Code: 201. Empty payload.
Create stream. Code: 202.
[name_len: u8][name: N][options block to end]The stream option catalog is empty today, so the block is normally empty (zero bytes).
Delete stream. Code: 203.
[stream_id: Identifier]Update stream. Code: 204.
[stream_id: Identifier][name_len: u8][name: N][options block to end]Patch semantics: absent option keys are left unchanged.
Purge stream. Code: 205.
[stream_id: Identifier]Topics
Get topic. Code: 300.
[stream_id: Identifier][topic_id: Identifier]Get topics. Code: 301.
[stream_id: Identifier]Create topic. Code: 302.
[stream_id: Identifier][partitions_count: u32][name_len: u8][name: N][options block to end]The fixed fields are the shape of the operation: which stream, how many partitions, what name. Every topic setting (compression_algorithm, message_expiry, max_topic_size, segment_size, enforce_fsync, messages_required_to_save, size_of_messages_required_to_save, preallocate_segments) rides the options block. See Topic options. partitions_count is an argument, not a setting: it is consumed at admission and never persisted as an option.
Delete topic. Code: 303.
[stream_id: Identifier][topic_id: Identifier]Update topic. Code: 304.
[stream_id: Identifier][topic_id: Identifier][name_len: u8][name: N][options block to end]Only compression_algorithm, message_expiry, and max_topic_size are updatable. Absent keys are left unchanged.
Purge topic. Code: 305.
[stream_id: Identifier][topic_id: Identifier]Partitions
Create partitions. Code: 402.
[stream_id: Identifier][topic_id: Identifier][partitions_count: u32]Delete partitions. Code: 403.
[stream_id: Identifier][topic_id: Identifier][partitions_count: u32]Segments
Delete segments. Code: 503.
[stream_id: Identifier][topic_id: Identifier][partition_id: u32][segments_count: u32]Deletes the segments_count oldest sealed segments of the partition.
Messages
Poll messages. Code: 100.
[consumer: Consumer][stream_id: Identifier][topic_id: Identifier]
[partition_flag: u8][partition_id: u32]
[strategy: 9 bytes][count: u32][auto_commit: u8]strategy is a polling strategy. count is the requested number of messages. auto_commit = 1 stores the consumer offset server-side as part of the poll.
The response body:
[partition_id: u32][current_offset: u64][messages_count: u32]
[batch records to end]The 16-byte prefix is followed by a stream of batch records served as stored: each record's header carries the stamped base_offset and base_timestamp, and each frame's deltas resolve against them. A record may be a server-sliced view of a larger stored batch, so the first polled offset is base_offset + offset_delta of the first frame, not necessarily base_offset itself. current_offset is the partition's newest offset at poll time.
Send messages. Code: 101.
[metadata_length: u32]
[stream_id: Identifier][topic_id: Identifier][partitioning: Partitioning]
[messages_count: u32]
[batch: 256-byte batch header + frames]metadata_length counts the bytes from stream_id through messages_count inclusive, so a reader can skip straight to the batch. The producer leaves partition_id, base_offset, and base_timestamp zero in the batch header, and the server stamps them. Every checksum is producer-computed and verified at admission. The reserved regions must be zero.
Flush unsaved buffer. Code: 102.
[stream_id: Identifier][topic_id: Identifier][partition_id: u32][fsync: u8]Parses, but the server always answers FeatureUnavailable: there is no on-demand flush primitive. Use the per-topic enforce_fsync option for durability guarantees.
Consumer offsets
Get consumer offset. Code: 120.
[consumer: Consumer][stream_id: Identifier][topic_id: Identifier]
[partition_flag: u8][partition_id: u32]Response body (20 bytes):
[partition_id: u32][current_offset: u64][stored_offset: u64]Store consumer offset. Code: 121.
[consumer: Consumer][stream_id: Identifier][topic_id: Identifier]
[partition_flag: u8][partition_id: u32][offset: u64][ack: u8]Delete consumer offset. Code: 122.
[consumer: Consumer][stream_id: Identifier][topic_id: Identifier]
[partition_flag: u8][partition_id: u32][ack: u8]The trailing ack byte is mandatory on both write commands. A payload without it fails to decode. Ack levels:
| Value | Level | Meaning |
|---|---|---|
| 0 | NoAck | Leader-local write; respond as soon as local state is updated (the fast path PollMessages auto-commit uses) |
| 1 | Quorum | Replicate through partition consensus; respond after a quorum commit (default for explicit writes) |
Consumer groups
Get consumer group. Code: 600.
[stream_id: Identifier][topic_id: Identifier][group_id: Identifier]Get consumer groups. Code: 601.
[stream_id: Identifier][topic_id: Identifier]Create consumer group. Code: 602.
[stream_id: Identifier][topic_id: Identifier][name_len: u8][name: N]Delete consumer group. Code: 603.
[stream_id: Identifier][topic_id: Identifier][group_id: Identifier]Join consumer group. Code: 604.
[stream_id: Identifier][topic_id: Identifier][group_id: Identifier]Leave consumer group. Code: 605.
[stream_id: Identifier][topic_id: Identifier][group_id: Identifier]Sync consumer group. Code: 606.
[stream_id: Identifier][topic_id: Identifier][group_id: Identifier]Read-only: a member asks for its current partition assignment and the group generation, so it can select partitions to poll client-side.
Users
Get user. Code: 31.
[user_id: Identifier]Get users. Code: 32. Empty payload.
Create user. Code: 33.
[username_len: u8][username: N][password_len: u8][password: N][status: u8]
[has_permissions: u8][permissions_len: u32, only when has_permissions = 1][permissions: M bytes]
[options block to end]permissions_len and the permissions bytes are present only when has_permissions = 1. When it is 0 the options block follows immediately. The user option catalog is empty today, so the block is normally empty. status: 1 = active, 2 = inactive.
Delete user. Code: 34.
[user_id: Identifier]Update user. Code: 35.
[user_id: Identifier]
[has_username: u8][username_len: u8, only when 1][username: N, only when 1]
[has_status: u8][status: u8, only when 1]
[options block to end]Update permissions. Code: 36.
[user_id: Identifier][has_permissions: u8]
[permissions_len: u32, only when has_permissions = 1][permissions: M bytes, only when 1]As in CreateUser, the length field is conditional: with has_permissions = 0 the payload ends at the flag.
Change password. Code: 37.
[user_id: Identifier]
[current_password_len: u8][current_password: N]
[new_password_len: u8][new_password: N]Authentication
Login and logout are part of the connection lifecycle:
- Login register. Code: 40.
Operation::Register. The body isClientVersionInfo+ credentials, described in Login-register. - Login register with PAT. Code: 45.
Operation::Register. The body isClientVersionInfo+ token. - Logout user. Code: 39.
Operation::Logout. Empty payload. - Codes 38 and 44 are the pre-register login shapes. The server rejects both with a
MalformedLogineviction.
Personal access tokens
Get personal access tokens. Code: 41. Empty payload.
Create personal access token. Code: 42.
[name_len: u8][name: N][expiry: u64]expiry is a duration in microseconds. Two sentinel values exist: 0 (server default, which currently means no expiry) and u64::MAX (never expires).
Delete personal access token. Code: 43.
[name_len: u8][name: N]