A Queen deployment is one process and one database. The broker is a single stateless Rust binary that serves HTTP on port 6632 and keeps every byte of state in PostgreSQL: no data directory to back up, no coordination service, no sidecar, no message file format on disk.
Four parts, of which two are required:
- the
queenbroker, one process, run as one to three identical replicas - PostgreSQL, the only source of truth: messages, offsets, the dedup index, queue configuration, dead letters
- the disk spool, node-local, where pushes land when PostgreSQL is unreachable
queen_proxy, optional, a separate binary that fronts the broker with API keys, quotas and tenants
Nothing is installed into either required part. The DDL and the 27 stored-procedure files are
compiled into the binary and re-applied idempotently at every boot under an advisory lock, so
there is no migration step and no extension. The dashboard, queenctl and the PostgreSQL client
tools travel inside the same image.
A complete deployment, ready to verify:
docker network create queen
docker run -d --name queen-pg --network queen -e POSTGRES_PASSWORD=postgres postgres:16
docker run -d --name queen --restart on-failure:10 --network queen -p 6632:6632 -e PG_HOST=queen-pg -e PG_PASSWORD=postgres -v queen-spool:/var/lib/queen/buffers ghcr.io/queen-mq/queen:latest
curl -s http://localhost:6632/healthThe only ordering requirement is a reachable PostgreSQL. Without one the broker fails its boot
loudly instead of starting half-working, which is what the restart policy is for: pasted as a
block, the third command lands while PostgreSQL is still initialising, and Docker brings the broker
back as soon as it can. Expect the curl to answer nothing on the first try and to answer within a
couple of seconds on the next. A broker that loses the database later answers 503 on /health
until it comes back.
The variables of the first day
PG_HOST, PG_PORT, PG_USER, PG_PASSWORD and PG_DATABASE reach the database. PG_USER and
PG_DATABASE default to postgres and PG_PORT to 5432, so in a container the host and the
password are usually the whole of it.
PORT moves the HTTP listener off 6632. DB_POOL_SIZE, default 160, is the ceiling on concurrent
database work for one broker and has to fit inside max_connections across every replica.
FILE_BUFFER_DIR is where the spool lives: mount it, because it is replayed only from the same
directory.
Booleans are strict everywhere: true/false, 1/0, yes/no, on/off, case-insensitive. Anything
else is a fatal boot error rather than a guess, and every boot prints the configuration the broker
actually resolved, secrets masked.
JWT_ENABLED is false by default, which means every route is served to every caller,
/api/v1/system/* included, and the broker has no HTTPS listener at all. Terminate TLS in front of
it and turn authentication on before it reaches a routable address.
Every variable the broker reads, with the default the code applies, is in the configuration reference.
Where the rest lives
PostgreSQL
Version floor, privileges, pooling, and how to size the database that is the whole system.
Kubernetes
A reference manifest, with probes that do not restart brokers when the database blips.
Operations
Retention, backup, upgrades, logs and metrics, and surviving a database outage.
High availability
Replicas against one PostgreSQL, what the mesh carries, and the port that must be firewalled.
Security
The trust boundaries: authentication, TLS in front, TLS to PostgreSQL, payloads at rest.
Multi-tenant
queen_proxy in front: tenants, API keys, quotas, metering and isolation.
Dashboard
The operator UI the binary already serves on the port you opened.
The per-mechanism detail is reference material: JWT and JWKS, payload encryption, PostgreSQL TLS, tenant endpoints, the CLI, the metrics and the limits.
One binary, one database, one port. Everything past that is something you chose to switch on.