Skip to content

Wire Protocol

YantrikDB Server speaks a custom binary wire protocol on port 7437 alongside the JSON HTTP gateway on port 7438. The wire protocol is faster (multiplexed, binary-encoded), supports streaming responses, and is the same protocol nodes use to talk to each other.

The codec is published as the yantrikdb-protocol crate.

Every message is a length-prefixed frame:

┌──────────┬──────────┬──────────┬──────────┬────────────┐
│ Length │ Version │ OpCode │ StreamID │ Payload │
│ (4 bytes)│ (1 byte) │ (1 byte) │ (4 bytes)│ (variable) │
└──────────┴──────────┴──────────┴──────────┴────────────┘
  • Length: big-endian u32, total bytes after this field
  • Version: protocol version + flag bits
    • Bit 7 (0x80): JSON payload mode (debug)
    • Bit 6 (0x40): zstd-compressed payload
  • OpCode: u8, identifies the message type (see table below)
  • StreamID: big-endian u32, allows multiplexing concurrent requests on one connection
  • Payload: MessagePack-serialized message struct, optionally zstd-compressed
Client Server
│ │
├── AUTH(token="ydb_abc123") ──────────► │
│ ├── validate token
│ ◄──────────────── AUTH_OK(db="default")│
│ │
├── REMEMBER(text="...") ──────────────► │
│ ◄──────── REMEMBER_OK(rid="mem_01") │
│ │
├── RECALL(query="...") ────────────────► │
│ ◄──────── RECALL_RESULT(mem_01, 0.93) │
│ ◄──────── RECALL_RESULT(mem_07, 0.71) │
│ ◄──────── RECALL_END(total=2) │
│ │

The recall response is streamed — each result is its own frame, ended by a RECALL_END frame. This lets clients start processing results before the server has finished computing them all.

CodeNameDirection
0x01AUTHC→S
0x02AUTH_OKS→C
0x03AUTH_FAILS→C
CodeNameDirection
0x20REMEMBERC→S
0x21REMEMBER_OKS→C
0x22REMEMBER_BATCHC→S
0x30RECALLC→S
0x31RECALL_RESULTS→C (streamed)
0x32RECALL_ENDS→C
CodeName
0x40RELATE
0x41RELATE_OK
0x42EDGES
0x43EDGES_RESULT
CodeName
0x50FORGET
0x51FORGET_OK
0x60SESSION_START
0x61SESSION_END
0x62SESSION_OK
0x70THINK
0x71THINK_RESULT
CodeNameDirection
0xC0CLUSTER_HELLOpeer→peer
0xC1CLUSTER_HELLO_OKpeer→peer
0xC2OPLOG_PULLpeer→peer
0xC3OPLOG_PULL_RESULTpeer→peer
0xC4OPLOG_PUSHpeer→peer
0xC5OPLOG_PUSH_OKpeer→peer
0xC6HEARTBEATleader→follower
0xC7HEARTBEAT_ACKfollower→leader
0xC8REQUEST_VOTEcandidate→voter
0xC9VOTE_GRANTEDvoter→candidate
0xCAVOTE_DENIEDvoter→candidate
0xCBCLUSTER_STATUSC→S
0xCCCLUSTER_STATUS_RESULTS→C
0xCDREADONLY_ERRORS→C
0xCECLUSTER_DATABASE_LISTpeer→peer
0xCFCLUSTER_DATABASE_LIST_RESULTpeer→peer
CodeName
0xF0ERROR
0xF1PING
0xF2PONG

Large payloads (oplog batches, recall results) are auto-compressed with zstd when they exceed 4KB. The compression flag (bit 6 of the version byte) tells the receiver to decompress before unpacking the MessagePack body.

Compressed payloads typically reach 3–5× compression ratio for natural language memory text.

You have three options:

  1. Use the Rust crate: cargo add yantrikdb-protocol — gives you the full Frame/codec/message types
  2. Use the HTTP gateway: simpler, just JSON over HTTPS — most clients should do this
  3. Implement from scratch: follow the frame format above. The MessagePack message structs are documented in the protocol crate’s source code

YantrikDB workloads are chatty (5–20 ops per agent turn), session-aware, and benefit from streaming. HTTP works fine for occasional clients but adds overhead per request. The wire protocol gives:

  • Lower latency — single connection, no per-request HTTP parsing
  • Multiplexing — multiple streams on one connection
  • Streaming recall — process results as they arrive
  • Server push — events (conflicts, decay, triggers) flow without polling
  • Native binary — no JSON parse on the hot path

The HTTP gateway is the universal interface; the wire protocol is the optimized one.