Stream And Queue Workflow
Private BetaStream create, publish, replay, queue claim, ack, and payload-free inspection routes are implemented in the private beta broker surface.
Quickstart
Run a packaged local Message Broker node, create a stream, publish and replay records, claim and acknowledge queue work, inspect the worker result, and keep private beta limits visible.
Current availability
Private Beta. Public beta is scheduled for .
You will have a local broker workflow that creates broker-quickstart.telemetry, publishes reading-1 and reading-2, replays them from offset 0, claims job-1 from broker-quickstart.jobs, acknowledges the delivery, and inspects payload-free queue state showing the work is complete.
Stream create, publish, replay, queue claim, ack, and payload-free inspection routes are implemented in the private beta broker surface.
This tutorial does not approve production support, performance, scale, external identity-provider validation, Kafka protocol compatibility, or cross-site replication outcomes.
Required
mq --version from the Message Broker private beta packagecurl --version for HTTP requestsmktemp, and sed for the local workflowRequired
mq CLI.9101 available for the local broker.Required
local-1 at http://127.0.0.1:9101.insecure-local auth mode, so the quickstart does not require credentials.Optional
jq can make local JSON inspection easier, but the copy/paste path only requires shell, curl, and sed.See local prerequisites for the shared tool baseline.
Use a dedicated service terminal for the complete startup script and a separate workflow terminal for requests. The script owns a new data directory on each run and cleans it after stopping its service.
Service terminal
Use a fresh Bash service terminal with the installed private beta mq package on PATH.
mq --versionMessage Broker release metadata prints from the installed private beta package.Service terminal
Save this complete file as start-broker.sh, then run bash start-broker.sh. Leave it running while using a separate workflow terminal. Each run creates fresh data. On exit or Ctrl-C, the script stops its own child, waits up to five seconds, and forcibly terminates that child if needed before removing only its temporary directory. Capture service-terminal output and results before stopping.
#!/usr/bin/env bash
set -euo pipefail
command -v mq >/dev/null
BROKER_DATA_DIR="$(mktemp -d "${TMPDIR:-/tmp}/message-broker-quickstart.XXXXXX")"
readonly BROKER_DATA_DIR
service_pid=
cleanup() {
trap '' INT TERM
if [ -n "$service_pid" ]; then
kill -TERM "$service_pid" 2>/dev/null || true
for attempt in 1 2 3 4 5; do
kill -0 "$service_pid" 2>/dev/null || break
sleep 1
done
if kill -0 "$service_pid" 2>/dev/null; then
kill -KILL "$service_pid" 2>/dev/null || true
fi
wait "$service_pid" 2>/dev/null || true
fi
rm -rf -- "$BROKER_DATA_DIR"
}
trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
printf 'Temporary broker data: %s\n' "$BROKER_DATA_DIR"
mq --validate-config \
--node-id local-1 \
--http-bind 127.0.0.1:9101 \
--data-dir "$BROKER_DATA_DIR" \
--flush-policy append-only \
--auth-mode insecure-local \
--metrics-exposure http
mq \
--node-id local-1 \
--http-bind 127.0.0.1:9101 \
--data-dir "$BROKER_DATA_DIR" \
--flush-policy append-only \
--auth-mode insecure-local \
--metrics-exposure http &
service_pid=$!
status=0
wait "$service_pid" || status=$?
service_pid=
exit "$status"
Temporary broker data: /tmp/message-broker-quickstart.<unique>
Configuration validation succeeds, then the broker starts at 127.0.0.1:9101.
The actual temporary path and service output vary.Workflow terminal
Open a separate Bash workflow terminal and set the endpoint there. If readiness fails, inspect the service terminal before retrying; no service PID or data-directory variable is needed here.
export BROKER_ENDPOINT=http://127.0.0.1:9101
(
for attempt in 1 2 3 4 5; do
if curl -fsS "$BROKER_ENDPOINT/health"; then
exit 0
fi
sleep 1
done
printf 'Message Broker did not become ready. Check the service terminal.\n' >&2
exit 1
){"status":"ok","service":"stornamics-message-broker","node_id":"local-1","http_bind":"127.0.0.1:9101","storage":{"status":"ready",...},"security":{"auth_mode":"insecure-local",...}}Workflow terminal
Use the same workflow terminal as the readiness check. Set the endpoint and quickstart-scoped stream, consumer-group, and replay-consumer names here; service-shell variables are not shared.
export BROKER_ENDPOINT=http://127.0.0.1:9101
export BROKER_STREAM=broker-quickstart.telemetry
export BROKER_QUEUE_STREAM=broker-quickstart.jobs
export BROKER_GROUP=broker-quickstart-workers
export BROKER_CONSUMER=broker-quickstart-readerThese variables are shell-local. The streams and consumer group names are scoped to this quickstart.Workflow terminal
Create the stream used for the publish and replay workflow through the versioned management route.
curl -s -X PUT \
-H 'Content-Type: application/json' \
--data '{}' \
"$BROKER_ENDPOINT/v1/streams/$BROKER_STREAM"{"api_version":"v1","stream":"broker-quickstart.telemetry","created":true,...}Workflow terminal
Append two local records. The broker returns offsets and durable acknowledgement fields for each publish.
curl -s -X POST \
-H 'Content-Type: application/json' \
--data '{"message_id":"reading-1","key":"machine-17","event_time_ms":1700000000000,"payload":"hello","durability_mode":"local-append"}' \
"$BROKER_ENDPOINT/v1/streams/$BROKER_STREAM/records"
curl -s -X POST \
-H 'Content-Type: application/json' \
--data '{"message_id":"reading-2","key":"machine-17","event_time_ms":1700000000001,"payload":"world","durability_mode":"local-append"}' \
"$BROKER_ENDPOINT/v1/streams/$BROKER_STREAM/records"{"api_version":"v1","stream":"broker-quickstart.telemetry","offset":0,"next_offset":1,"message_id":"reading-1","payload_bytes":5,...}
{"api_version":"v1","stream":"broker-quickstart.telemetry","offset":1,"next_offset":2,"message_id":"reading-2","payload_bytes":5,...}Workflow terminal
Fetch from offset 0 and include replay consumer metadata so the inspection route has activity to report.
curl -s \
"$BROKER_ENDPOINT/v1/streams/$BROKER_STREAM/records?start_offset=0&max_records=10&consumer_group=$BROKER_GROUP&consumer_id=$BROKER_CONSUMER"{
"api_version": "v1",
"stream": "broker-quickstart.telemetry",
"records": [
{"offset":0,"message_id":"reading-1","payload_hex":"68656c6c6f"},
{"offset":1,"message_id":"reading-2","payload_hex":"776f726c64"}
],
"next_offset": 2,
"end_of_stream": true,
"diagnostics": {"returned_records":2}
}Workflow terminal
Use the payload-free replay consumer inspection route to confirm the replay was observed without returning message payloads.
curl -s \
"$BROKER_ENDPOINT/v1/streams/$BROKER_STREAM/consumer-groups/$BROKER_GROUP/replay-consumers"{"api_version":"v1","stream":"broker-quickstart.telemetry","consumer_group":"broker-quickstart-workers","consumers":[{"consumer_id":"broker-quickstart-reader","returned_records":2,"end_of_stream":true,...}]}Workflow terminal
Use a separate stream for queue work so the worker result is easy to inspect.
curl -s -X PUT \
-H 'Content-Type: application/json' \
--data '{}' \
"$BROKER_ENDPOINT/v1/streams/$BROKER_QUEUE_STREAM"
curl -s -X POST \
-H 'Content-Type: application/json' \
--data '{"message_id":"job-1","key":"worker","event_time_ms":1700000000100,"payload":"work","durability_mode":"local-append"}' \
"$BROKER_ENDPOINT/v1/streams/$BROKER_QUEUE_STREAM/records"{"api_version":"v1","stream":"broker-quickstart.jobs","created":true,...}
{"api_version":"v1","stream":"broker-quickstart.jobs","offset":0,"next_offset":1,"message_id":"job-1",...}Workflow terminal
Claim one available record for the worker group and keep the response so the ack step can reuse the broker-assigned ids.
CLAIM_RESPONSE="$(curl -s -X POST \
-H 'Content-Type: application/json' \
--data '{"max_messages":1,"lease_timeout_millis":30000}' \
"$BROKER_ENDPOINT/v1/streams/$BROKER_QUEUE_STREAM/consumer-groups/$BROKER_GROUP/claims")"
printf '%s\n' "$CLAIM_RESPONSE"{"api_version":"v1","stream":"broker-quickstart.jobs","consumer_group":"broker-quickstart-workers","subscription_id":"sub-...","deliveries":[{"delivery_id":"del-...","attempt":1,"record":{"message_id":"job-1","payload_hex":"776f726b"}}],"delivery_count":1}Workflow terminal
Extract the subscription and delivery ids from the claim response, then ack the active delivery.
SUBSCRIPTION_ID="$(printf '%s' "$CLAIM_RESPONSE" | sed -nE 's/.*"subscription_id":"([^"]+)".*/\1/p')"
DELIVERY_ID="$(printf '%s' "$CLAIM_RESPONSE" | sed -nE 's/.*"delivery_id":"([^"]+)".*/\1/p')"
curl -s -X POST \
-H 'Content-Type: application/json' \
--data '{}' \
"$BROKER_ENDPOINT/v1/streams/$BROKER_QUEUE_STREAM/subscriptions/$SUBSCRIPTION_ID/deliveries/$DELIVERY_ID/ack"{"api_version":"v1","stream":"broker-quickstart.jobs","subscription_id":"sub-...","delivery_id":"del-...","offset":0,"attempt":1,"acknowledgement":{"durability":{"outcome":"durable",...}}}Workflow terminal
Claim again with the same worker group to prove the acknowledged delivery is no longer available.
curl -s -X POST \
-H 'Content-Type: application/json' \
--data '{"max_messages":1,"lease_timeout_millis":30000}' \
"$BROKER_ENDPOINT/v1/streams/$BROKER_QUEUE_STREAM/consumer-groups/$BROKER_GROUP/claims"{"api_version":"v1","stream":"broker-quickstart.jobs","consumer_group":"broker-quickstart-workers","deliveries":[],"delivery_count":0}Workflow terminal
Inspect the consumer group and completed leases. These routes are payload-free and show the worker result without returning the job body.
curl -s \
"$BROKER_ENDPOINT/v1/streams/$BROKER_QUEUE_STREAM/consumer-groups/$BROKER_GROUP"
curl -s \
"$BROKER_ENDPOINT/v1/streams/$BROKER_QUEUE_STREAM/consumer-groups/$BROKER_GROUP/leases?include_completed=true"{"api_version":"v1","stream":"broker-quickstart.jobs","consumer_group":"broker-quickstart-workers","description":{"mode":"shared_queue","highest_next_offset":1,"progress_offset":1,"lag_messages":0,"in_flight_count":0,...}}
{"api_version":"v1","stream":"broker-quickstart.jobs","consumer_group":"broker-quickstart-workers","leases":[{"offset":0,"attempt":1,"state":"acked",...}]}Workflow terminal
Replication status is visible, but the local quickstart node does not configure workers or prove cross-site outcomes.
curl -s "$BROKER_ENDPOINT/v1/replication/status"{"api_version":"v1","status":"not_configured","node_id":"local-1","runtime_boundary":"read-only status binding; no replication workers or network transports are started by this route",...}The quickstart is successful when replay returns both message ids and next_offset:2, the queue claim returns delivery_count:1, the ack response includes a durable acknowledgement, the second claim returns delivery_count:0, and lease inspection shows the first delivery in acked state.
Service terminal
Return to the service terminal and press Ctrl-C. Its startup script stops and waits for its owned broker process before deleting that run's temporary data. The installed package and saved startup script remain. Start a new script invocation for a fresh run; do not reuse a saved PID or an older data directory.
# Press Ctrl-C in the service terminal running start-broker.sh.The owned broker process exits and its unique temporary data directory is removed. Unrelated broker processes and directories remain.| Symptom | How to recognize it | Likely cause | Fix |
|---|---|---|---|
| Start command says the address is already in use | The mq startup output reports a bind or listener failure for 127.0.0.1:9101. | Another process is using the quickstart port, or a previous quickstart broker is still running. | Stop your earlier quickstart with Ctrl-C in its service terminal. Leave unrelated processes alone, or choose another loopback port in the startup script and update BROKER_ENDPOINT. |
| Health check cannot connect | curl reports connection refused or times out against 127.0.0.1:9101. | The broker is still starting, startup validation failed, or another process owns port 9101. | Check the service terminal output, then restart the script after fixing the reported startup issue. Each invocation uses fresh temporary data. |
Create stream returns stream_already_exists | The response status is 409 Conflict or the JSON error code is stream_already_exists. | The stream already exists in the quickstart data directory from an earlier run. | Reuse the existing stream for the rest of the quickstart or set a new quickstart-scoped stream name. |
Publish returns stream_not_found or missing_stream | The response body contains stream_not_found or missing_stream. | The publish step ran before the stream create step or used a different stream variable. | Create the stream again and confirm BROKER_STREAM or BROKER_QUEUE_STREAM matches the publish URL. |
Ack returns delivery_not_found | The response body contains delivery_not_found. | The extracted SUBSCRIPTION_ID or DELIVERY_ID is empty, stale, or from another stream. | Re-run the claim step, confirm delivery_count is 1, and reuse the ids from that response. |
Ack returns lease_expired | The response body contains lease_expired. | The 30-second delivery lease expired before the ack request reached the broker. | Claim the message again and ack the fresh delivery id, or use a longer lease_timeout_millis while debugging. |
| Replay inspection shows no consumers | The replay-consumers response has an empty consumers array. | The replay request omitted consumer_group or consumer_id, or used a different group name. | Replay again with the documented query string and confirm BROKER_GROUP and BROKER_CONSUMER are set. |
| Workflow step | Source scope | Status |
|---|---|---|
| Private beta package startup and health | Message Broker CLI lifecycle reference, runtime configuration source, and main broker startup source | Source-backed; local run still needs product confirmation |
| Stream create, publish, and replay | Message Broker stream route contract, HTTP route scope, and broader product walkthrough checks | Source-backed |
| Replay consumer inspection | Message Broker HTTP route scope and runtime inspection tests | Source-backed |
| Queue claim and ack | Shared queue route contract, durable queue state integration, and broader product walkthrough checks | Source-backed |
| Private beta limits | Message Broker private beta package and product fact sheet | Source-backed; claims remain product-bound |
This quickstart proves a local private beta stream, replay, and shared-queue worker path; it is not a general release support promise.
The commands use a single local node in insecure-local auth mode and a disposable data directory.
Replay and claim responses include payload bytes as hex, while consumer-group, lease, and replay-consumer inspection routes are payload-free.
Replication status is inspectable, but cross-site durability, availability, failover, and topology outcomes require separate evidence.
Available now
Review Message Broker limitsUse the limits and compatibility guidance before strengthening stream, queue, auth, replication, or pilot-readiness claims.
Available now
Read tutorial prerequisitesCheck the shared local tool baseline and product-specific setup expectations for first-success tutorials.
Available
Read HTTP referenceLook up stream, record, cursor, queue, audit, metrics, storage, auth, and replication route details.
Available
Compare route and auth scopeSeparate private beta routes from auth, replication, queue, CLI, SDK, and Kafka protocol boundaries.
Available
Use SDK examplesReview tested Rust SDK publish, replay, cursor, queue worker, retry, and dead-letter flows.