Quickstart: Produce → Fetch Roundtrip
This quickstart walks through producing records to Rafka and fetching them back — the complete produce→fetch loop — using kcat. Both operations use standard Kafka wire protocol. Records are persisted to the durable WAL and survive broker restarts.
:::info Verified behavior The full ApiVersions → Metadata → Produce → ListOffsets → Fetch sequence is built and Jaeger-verified in Rafka P1. This quickstart reflects actual live behavior. :::
Prerequisites
- kcat installed (
brew install kcat/apt install kcat) - Rafka running via the dev compose stack (see Quickstart: Produce)
- Optional: Jaeger UI at
http://localhost:16686to observe traces
Produce records
printf "first-record\nsecond-record\nthird-record\n" | kcat -P \
-b localhost:9092 \
-t my-topic \
-p 0
kcat performs the full standard handshake:
ApiVersions— negotiates supported API versions.Metadataformy-topic— Rafka self-advertises as the single broker, partition 0.ProduceRequest— gateway routes records to the broker via the iroh mesh KafkaOp carrier.ProduceResponsewitherror_code: 0andbase_offset: 0.
Fetch records back
kcat -C \
-b localhost:9092 \
-t my-topic \
-p 0 \
-o beginning \
-e
-o beginning starts from offset 0; -e exits after the last available record.
Expected output:
first-record
second-record
third-record
kcat performs:
ApiVersions+MetadataListOffsetswithtimestamp=-2(earliest) →offset=0FetchRequestfrom offset 0 → Rafka reads records from the WAL and returns them
Check the offset watermark
kcat -Q \
-b localhost:9092 \
-t my-topic:0:-1
-1 queries the latest (high-watermark) offset. After producing 3 records the output should be my-topic [0] offset 3.
Observe the trace in Jaeger
Open http://localhost:16686, select service mesh1.gateway, and click Find Traces. The fetch trace shows:
gateway.kafka.connect
└── gateway.kafka.request (api_key=3, Metadata)
└── gateway.kafka.request (api_key=2, ListOffsets)
└── rafka.gateway.kafka.list_offsets
└── rafka.broker.list_offsets.read
└── gateway.kafka.request (api_key=1, Fetch)
└── rafka.gateway.kafka.fetch
└── rafka.broker.fetch.read
All spans across gateway and broker join one trace via W3C traceparent propagation in the mesh frame header.
Restart durability
Stop and restart the broker:
podman compose -f deployment/dev/compose.yml restart rafka-broker
Fetch again — the same records are returned. The SingleWal WAL persists records to disk; the broker's recovery scan rebuilds the virtual topic index on startup. See WAL Durability for details.
Next steps
- Concepts: Fetch — how FetchRequest flows from client through the mesh to the WAL
- Concepts: WAL Durability — the storage engine behind restart-safe records
- Kafka API & Wire Compatibility — full version table and wire behavior