Technology · Protocol

MessagePack

Compact binary serialisation on the agent runtime's message bus and the broker's internal entries.

FAFO Core · Inference Fabric · Agent SwarmCompact payloads on the write path and the bus
Producersappend and go
Redis stream
Writerinto PostgreSQL
  • 16fixed fields in every write message
  • 3encodings, each chosen for its path

One write path, no database connections

In FAFO Core and Function Forge I wanted hundreds of workers to write results without any of them holding a database connection, so functions never write to PostgreSQL directly. A producer client encodes each write as a flat MessagePack message and appends it fire-and-forget to a Redis stream. A single governed write service then owns the write, one path from many producers into the database.

I chose MessagePack because producers needed a compact, self-describing encoding that the writer could route without decoding the whole message. On a hot path I prefer a flat, fixed field set: the writer reads where a message goes with no database query and no schema lookup.

schema, table, operation, column count: what the writer routes on
the rest of the fixed field set

A contract checked only by convention

The flat contract also taught me a lesson. It was enforced by convention, and one producer, the vector store, sent a single-field blob instead.

Flat messages
stream
Writerroutes each one
The vector store's blobs
stream
Writercannot route them
stranded, with no signal, until someone found the backlog

Consumer-side contract checks are now part of the design. The write path's own performance diagnosis is in 196 deadlocks to zero, and the Write-behind persistence page covers the pattern.

A wire contract that matters has to be checked where it is consumed.

An encoding for each path

The Inference Fabric moves several kinds of data between Rust services, and I chose each encoding for its job.

MessagePack
compact and self-describing: routable without decoding
Canonical CBOR
The same config again
identical bytes, carried unread by the broker
bincode
fixed layout, Rust to Rust
Byte strips are illustrative.

The vector shard manager takes framed CBOR requests over TCP and carries MessagePack in its dependency set. Extraction specifications for hidden-state capture are canonical CBOR, so a given configuration always produces the same bytes, and the broker carries them to the GPU consumer without interpreting them, which keeps it independent of any one model. The broker is in A message broker that understands tokens.

Relay frames in the agent runtime

In Agent Swarm the cross-host relay and hub router frame their wire messages in MessagePack. The durability writers read journal streams in the same encoding before writing agent activity and message journals to PostgreSQL.

Relay and hubMessagePack frames
journal streams
Durability writers
Journalsactivity, messages

I pay attention to the failure mode of a contract as much as to its format. MessagePack, CBOR and bincode come in through standard Rust crates (rmp-serde, ciborium, bincode); the contracts on top of them are my design, and the write path they feed is on the PostgreSQL Fabric page.