# Queen MQ, complete summary > A message queue on the PostgreSQL you already run: one ordered FIFO lane per entity, consumer groups, replay, a dead-letter queue and a dashboard, in one binary. This is the whole product in one document, for an agent that has a question about Queen MQ rather than about one page of its documentation. Every figure carries the conditions it was measured under, in the same sentence, because a figure without them is not a fact about this system. Canonical site: https://queenmq.com/ Index of every documentation page: https://queenmq.com/llms.txt Every page collated into one document: https://queenmq.com/llms-full.txt That file is roughly fifty times the size of this summary, above the input ceiling of most fetch pipelines, which truncate it without reporting that they did. Prefer this summary, or the per-section indexes linked below. ## Start Here Section index: https://queenmq.com/start/llms.txt ### Overview Queen MQ is high-performance transactional messaging for applications that need an ordered stream per entity: a Rust broker keeping all state in PostgreSQL 15 or newer, with no extensions and no migrations. Its defining abstraction is one logical ordered partition per application entity, created by the first push that names it, giving per-entity FIFO ordering with no head-of-line blocking. One call can acknowledge input, write application state, push output and schedule a timer in one PostgreSQL transaction. The three scaling axes are distinct: partitions scale application cardinality, brokers scale serving capacity inside a cell (three replicas the ceiling), cells scale the deployment. A cell is PostgreSQL plus stateless brokers, optionally fronted by the queen_proxy gateway, and is both the scaling and the failure boundary. Apache 2.0, ghcr.io/queen-mq/queen. Source: https://queenmq.com/start/ ### Quickstart A broker from nothing in four commands, needing only Docker: `docker network create queen`; then `docker run -d --name queen-pg --network queen -e POSTGRES_PASSWORD=postgres postgres:16`; then `docker run -d --name queen --restart on-failure:10 --network queen -p 6632:6632 -e PG_HOST=queen-pg -e PG_PORT=5432 -e PG_PASSWORD=postgres ghcr.io/queen-mq/queen:latest`; then `curl -s http://localhost:6632/health`, which takes a pooled connection and does a real database round-trip, so a healthy answer proves both processes. The restart policy matters on the first run: the broker refuses to start against a database it cannot reach, and PostgreSQL is still initialising for the first seconds after step 2. PG_USER and PG_DATABASE both default to postgres and PG_PORT to 5432, so host and password are usually the whole configuration. Adding `-v queen-spool:/var/lib/queen/buffers` persists the outage spool. Nothing is installed into PostgreSQL and there is no migration to run. The same binary serves its dashboard on the same port. Source: https://queenmq.com/start/quickstart/ ### Comparison Per-entity ordering is the axis these systems differ on. Queen MQ makes a partition a row created by the first push that names it, so lanes are unbounded, nothing is preallocated and nothing rebalances. Kafka hash-mods a changing key set onto a partition count fixed in advance, so entities that collide block each other. RabbitMQ and pgmq both need one live queue per entity. Amazon SQS FIFO's message group id is structurally the same idea as a Queen MQ partition. Where the other systems are better, stated plainly: Kafka replicates itself while Queen MQ delegates durability and failover to one PostgreSQL, which is therefore one failure domain; content-based routing is RabbitMQ's real strength and Queen MQ has no exchanges, no bindings and no header matching; Amazon SQS has no server to operate at all; pgmq needs no broker process and is insensitive to lane count. Kafka is also the cheapest of the four on CPU in every measured shape. Source: https://queenmq.com/start/compare/ ## Use Queen Section index: https://queenmq.com/use/llms.txt ### Overview The surface is push, pop and acknowledge plus one container, `POST /api/v1/transaction`, which commits any number of pushes and acks across any number of queues, partitions and consumer groups in one PostgreSQL transaction. Two optional top-level arrays ride that same commit, and every broker serves them: `kv`, a transactional key/value store where every write carries an expiry, and `timers`, a message promised now and delivered later, cancellable until it fires and with no recurrence. The queue and partition are created by the push that names them, so nothing is provisioned first. An acknowledgement commits a position, not one message, so acking the last message of a batch completes the batch. A consumer group holds at most one leased batch per partition, so parallelism comes from partitions, not from more consumers on one. It is all HTTP: curl is a client and the SDKs are convenience over it. Packages: JavaScript `npm i queen-mq`, Python `pip install queen-mq`, Go `go get github.com/smartpricing/queen/clients/client-go`, Rust crate `queen-mq`, PHP `composer require smartpricing/queen-mq`, CLI `make -C clients/client-cli build`, C++ one header `clients/client-cpp/queen_client.hpp`. Source: https://queenmq.com/use/ ### Model A queue is a named container with a configuration and a partition is an ordered lane inside it, and neither is declared before use: the push that names them creates both in the transaction that stores the message. A partition costs one row plus one row per consumer group that reads it, so tens of thousands of lanes are ordinary and one million has been served at 200,000 messages a second, while a partition per message is not a supported shape. A consumer group is a name holding one cursor per partition, so two groups read the same stored copy at their own pace; omitting the group places the caller in the implicit __QUEUE_MODE__ competing-consumers group. Where a named group starts is decided on its first contact with the queue and stored: mode `new`, the default, skips the backlog and `all` delivers everything retained, and passing the mode later changes nothing. An ack is an offset commit, so acking one message completes every earlier unacked message in that partition for that group. Source: https://queenmq.com/use/model/ ### Streams A windowed query reads a queue, folds its messages into time buckets and pushes each closed window onto a sink queue, one ordinary message per window and per key; open windows are readable through `POST /streams/v1/state/get`. The chain runs in your process; state is rows in the same PostgreSQL. Windows are `windowTumbling`, `windowSliding`, `windowSession` and `windowCron`. Bucketing uses commit time unless an `eventTime` extractor switches the runtime to watermarks, `allowedLateness` and `onLate`. One cycle commits state writes, sink pushes and the leased batch's ack in one PostgreSQL transaction, all or none. `foreach` acks after the function returns, so an effect outside PostgreSQL is at-least-once. `.gate()` replaces the window and reducer with a per-message allow or deny that keeps the denied tail leased and in order. Inside a stream the state primitive is `state_ops`, not the KV, and a cycle carries no KV or timer operations. Retention never touches stream state. Source: https://queenmq.com/use/streams/ ### Examples A first push provisions the queue, its partition and its configuration in the transaction that writes it. Fan-out is one group name per consumer: no exchange, binding or create-group call, bytes written once, one cursor row per partition per group, free on the write side; reads scale with groups. In a transaction a duplicate push or rejected ack rolls back the batch, not per item. Dedup is exact, scoped to one partition, writes nothing on a duplicate; the window is `dedupWindowSeconds`, 3600 by default, and outside it the same id is new. A seek releases the live lease, resets retry counters and lands on a segment, not a message. A new group seeds at each partition's end unless `subscriptionMode('all')` seeds it just below the oldest retained offset. A nack charges one retry; at `retryLimit`, 3 by default, the message is snapshotted to the DLQ. An expired lease charges nothing, so a hung handler redelivers forever, never reaching it. Source: https://queenmq.com/use/examples/ ## Deploy Queen Section index: https://queenmq.com/deploy/llms.txt ### Overview A deployment is one process and one database. The broker is a single stateless Rust binary serving HTTP on port 6632 that keeps every byte of state in PostgreSQL: no data directory to back up, no coordination service, no sidecar, no message file format on disk. The optional parts are a node-local disk spool and the separate queen_proxy multi-tenant gateway. Brokers are stateless and scale horizontally as one to three identical replicas; the database does not scale, and it is simultaneously the durability story, the coordination substrate, the throughput ceiling and the single point of failure, so high availability means PostgreSQL high availability. 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, no version table and no extension. Source: https://queenmq.com/deploy/ ### PostgreSQL PostgreSQL 15 or newer, and no extensions. The floor is one unique index declared NULLS NOT DISTINCT, which PostgreSQL 14 does not have; the test matrix runs against PostgreSQL 16. PostgreSQL is the storage engine rather than a dependency, so sizing PostgreSQL is sizing Queen, and every queue semantic runs in stored procedures inside the database. A pooler in transaction or statement mode breaks the session advisory locks the boot-time schema apply and the maintenance leader election hold, and the prepared statements the hot paths prepare once per connection; PgBouncer in session mode is supported. DB_POOL_SIZE defaults to 160 per broker, so replicas times DB_POOL_SIZE plus superuser_reserved_connections plus tooling has to stay under max_connections: three brokers at the default want 480 connections where a stock PostgreSQL allows 100, and the mismatch answers 500 with an error of pool. Source: https://queenmq.com/deploy/postgres/ ### Docker Compose One Compose file brings up PostgreSQL, two meshed brokers and `queen_proxy` against published images. Three secrets are generated first and passed in through `.env`: `CELL_JWT_SECRET` is the broker's `JWT_SECRET` and also signs the cell token the proxy presents, `MESH_SECRET` is `QUEEN_SYNC_SECRET` and must be byte-identical on both brokers, `SESSION_SECRET` signs proxy sessions. Each broker needs a distinct `QUEEN_SERVER_ID` and its own spool volume, never shared. Brokers gate on `depends_on: condition: service_healthy`, which is what keeps them from racing PostgreSQL's first boot. The proxy has no route until the control plane has rows: insert one `queen_proxy.cells` row carrying an HS256 token signed with `CELL_JWT_SECRET`, then call `queen_proxy.bootstrap_tenant(...)`, which returns a plaintext `api_key` shown exactly once. Requests then carry that key as a bearer token and a `Host` whose first DNS label is the cluster slug. Both brokers sit behind one `queen` network alias, which is standby and not load spreading: the proxy pins to whichever it resolves and moves to the other when that one goes away. One PostgreSQL means this survives losing a broker, not losing the database. Source: https://queenmq.com/deploy/compose/ ### High availability Replicas are copies of one binary on one PostgreSQL, and messages, offsets, leases, deduplication, queue configuration and the dead-letter queue are rows: nothing replicates between brokers, no quorum, no serving leader, no split-brain. They cover a broker dying, a rolling restart, one node's network, not PostgreSQL, the failure domain. Three brokers is the designed ceiling: replicas × `DB_POOL_SIZE` must fit `max_connections`. Every replica serves every route, so a pop from one broker is acked to another. Leader election is an advisory lock: retention sweep and statistics reconciler run on one replica per cycle. `QUEEN_MESH_PORT` carries hints only. While PostgreSQL is unreachable a push spools to disk, answered `201` with `status: "buffered"` per item; pops, acks and `POST /api/v1/transaction` fail. The spool is node-local, drained only by its broker, uncapped in size and age: a long outage fills the disk and pushes report `failed`. Source: https://queenmq.com/deploy/ha/ ### Security One plaintext listener on `0.0.0.0:PORT` serves the HTTP API and dashboard; no TLS listener, no CORS layer. `JWT_ENABLED` is `false` by default; off, every route answers any caller, `DELETE /api/v1/resources/queues/:queue` included, dashboard as full admin. `/metrics/prometheus` is public, no switch; its per-queue series carry no tenant label. `PG_USE_SSL` is `false` by default; on, most managed PostgreSQL fails the binary's Mozilla-root validation, and `PG_SSL_REJECT_UNAUTHORIZED=false` encrypts without verifying the server. Encryption needs `QUEEN_ENCRYPTION_KEY` plus the queue's `encryptionEnabled`; one alone stores plaintext, no error. On `QUEEN_MESH_PORT`, frames after the replayable HMAC `HELLO` handshake are unauthenticated JSON; firewalling is mandatory. `002_streams_schema.sql` grants `queen_streams.queries` and `queen_streams.state` to `PUBLIC`. With native tenancy on, `x-queen-tenant` is checked for shape, never authority, and `QUEEN_TENANCY_HEADER=1` refuses to boot unless `QUEEN_KV_TRUSTED_PROXY=1` is set with it. Source: https://queenmq.com/deploy/security/ ## Reference Section index: https://queenmq.com/reference/llms.txt ### HTTP API conventions One HTTP API version, v1, the path itself being the version, with no negotiation. The broker binds 0.0.0.0 on PORT, default 6632, so a local base URL is http://localhost:6632. It has no TLS listener and no CORS layer, so 6632 must sit behind something that terminates TLS and must never face a browser or the internet. On the message plane the broker never returns 429: its adaptive admission arbiter makes a request wait for a slot rather than rejecting it, and 429 comes from the multi-tenant gateway. The kv and timer routes are the exception, with a per-tenant rate limiter in the broker itself. Retry safety differs per route: a push is safe to retry blindly only when the caller sends its own transactionId, in which case the retry returns a status of duplicate and writes nothing; ack and lease extend are safe, and an ack landing below the cursor is reported as a noop rather than double-committing; a transaction is safe only with deterministic transactionIds; a pop never is, because a retry is a new claim rather than a repeat; and a kv incr never is, because it has no precondition and counts twice. Every 204 has no body at all, deliberately. Source: https://queenmq.com/reference/http/ ### POST /api/v1/push `POST /api/v1/push`, access level `write-only`, writes messages to one or more queues. Body `{"items":[...]}`; per item, `queue` and `payload` are required, `partition` defaults to `"Default"`, `transactionId` to the minted message id, and `data` without `payload` gives 400. Success is `201 Created` plus a top-level array of `index`, `message_id`, `transaction_id`, `queueName`, `status`, one per item in request order. `status`: `queued`, `duplicate`, `buffered` (on-disk spool, drained later) or `failed` (exists nowhere, retry); both still return 201, so the code alone cannot detect loss. Also 400 non-JSON or missing `items`/`queue`/`payload`, 403 auth on and no writer role, 413 over 64 MiB, 500 maintenance mode plus a failed spool write. Commits are per `(queue, partition)` group, not per request. Dedup: on by default, exact, per partition, keyed on `transactionId` within the queue's `dedupWindowSeconds` (default 3600, `0` disables). Source: https://queenmq.com/reference/http/push/ ### Limits and non-goals The non-goals of today's build. Ordering granularity is the partition key, so in-group parallelism equals the partition count. A bare broker enforces no per-caller quota; queen_proxy enforces a per-cluster plan. Retention is opt-in and deletes whole segments, so removing one message is not an operation. A transaction is one PostgreSQL transaction, not end-to-end exactly-once. Timers and KV state are on every broker and have their own limits: every KV write carries an expiry, deliverAt is a floor and not an appointment, there is no recurrence, and a cancel after the fire answers absent, meaning no longer pending and never not delivered. Source: https://queenmq.com/reference/limits/ ### The pop routes A pop claims a leased batch and removes nothing, but a queue-scoped pop creates a missing queue's `queen.queues` row. Read-write `GET` routes: `/api/v1/pop/queue/:queue`, that path + `/partition/:partition`, and `/api/v1/pop` discovery (needs `namespace`/`task`). Defaults: `batch` 200 (call-wide budget), `partitions` 1, `autoAck` and `wait` false, `timeout` 30000 ms (needs `wait=true`), `consumerGroup` `__QUEUE_MODE__`, `subscriptionMode` `new` (seeds absent cursors, never in queue mode), `leaseSeconds` the queue's `leaseTime`, else 60. 200 gives `leaseId`, `messages` of `id`, `transactionId`, `data`, `partitionId`, no offset/attempt count; ack per-message `partitionId`. A bare `204` covers idle, `delayedProcessing`/`windowBuffer` holdback, pop maintenance, procedure errors, `wait=true` timeouts. One live leased batch per `(partition, group)` caps parallelism at the partition count; expiry redelivers, `autoAck=true` is at-most-once. Source: https://queenmq.com/reference/http/pop/ ### POST /api/v1/ack and /ack/batch An ack commits a cursor per `(partition, group)`, not a per-message delete: earlier unacked ones complete. `POST /api/v1/ack` takes `transactionId`, `partitionId`, `leaseId`, `error`, `status` (default `completed`), `consumerGroup` (default `__QUEUE_MODE__`); `POST /api/v1/ack/batch` puts items in `acknowledgments`, `consumerGroup` top-level only. Both are read-write; 200 gives per-item `success`, `leaseReleased`, `dlq`, `noop`. `status` is case-sensitive: absent/null, `completed`, `success`, `acked`, `ok` complete; `retry` is budget-free; `dlq` dead-letters at once; anything else, `nack` included, silently becomes `failed`, charging its `(partition, group)` budget `retryLimit` (default 3); exhaustion dead-letters by default. A lease-less ack skips validation and commits. At or below the cursor `completed` is `noop: true`, `failed`/`retry`/`dlq` fail as `already committed`, an unresolvable `transactionId` fails, redelivering if leased. Source: https://queenmq.com/reference/http/ack/ ### Environment variables Most of the configuration table is measured engine tuning that should be left alone. In practice a deployment sets: PG_HOST, PG_PORT, PG_PASSWORD, PG_USER and PG_DATABASE to reach PostgreSQL, where PG_USER and PG_DATABASE both default to postgres, PG_PORT to 5432 and PG_HOST to localhost; DB_POOL_SIZE, default 160, with QUEEN_STMT_TIMEOUT_MS; PG_USE_SSL and PG_SSL_REJECT_UNAUTHORIZED; PORT, default 6632; the JWT_ variables, with JWT_ENABLED false by default so the middleware passes every request through; QUEEN_MESH_PORT, default 6633, with QUEEN_MESH_PEERS and QUEEN_SYNC_SECRET; FILE_BUFFER_DIR, default /var/lib/queen/buffers; RETENTION_INTERVAL, default 5000 milliseconds; QUEEN_MAX_BODY_BYTES, default 67108864, which is 64 MiB and returns 413 above it; QUEEN_ENCRYPTION_KEY, which must be 64 hexadecimal characters, because a malformed or wrong-length key logs one warning, disables encryption and then stores plaintext on queues flagged for it; LOG_LEVEL, default info, accepting EnvFilter syntax and overridden by RUST_LOG; DEFAULT_SUBSCRIPTION_MODE, default new; QUEEN_APPLY_SCHEMA, default true; and QUEEN_TENANCY_HEADER. Source: https://queenmq.com/reference/config/ ### Streams routes `/streams/v1` is three JSON POSTs and a public versioned contract, not an SDK internal. `POST /streams/v1/queries` registers a query by `name` and returns its `query_id`, answering 409 when `config_hash` differs from the stored one and `reset` is absent. `POST /streams/v1/state/get` reads state rows for one `query_id` and `partition_id`, filtered by `keys`, `key_prefix` or `ripe_at_or_before`, at read-only access level. `POST /streams/v1/cycle` commits `state_ops`, `push_items` and the source ack in one PostgreSQL transaction, at read-write. Source: https://queenmq.com/reference/http/streams/ ### Status codes and error bodies Most broker failures are `{"error":"..."}`, `application/json`, with no `code`, enum or request id: match on status. Exceptions: 413, `/health` (its own document at 200, and at 503 when the DB round trip fails), and unmatched `/api/` paths, 404 with `{"error":"Not Found","code":"no_such_route"}`. Codes: 200 reads, management, acks, transactions; 201 `POST /api/v1/push`; 204 empty pop or any pop under pop maintenance, no body: no `{"messages":[]}`, no `paused`; 413 over `QUEEN_MAX_BODY_BYTES` (64 MiB default). Never 429: the broker makes a request wait for an admission slot instead of refusing it. Never 502 or 504. Procedure error text with `not found` (case-insensitive) maps to 404, else 500. 2xx is not success: push item status is `queued`, `duplicate`, `error`, `buffered` or `failed` (spooled still 201); ack and transaction report `success:false` at 200. Failed transactions carry a closed-taxonomy `reason`: branch on it, never on `error`. `kv_precondition` is a lost idempotency gate at 200, not a failure to retry. The proxy adds `code` and `Retry-After` in seconds on 429; SDKs retry only 429. Source: https://queenmq.com/reference/errors/ ### Versions and compatibility A release is one broker binary plus client SDKs at the same version for JavaScript, Python, Go, Rust, PHP with Laravel and C++, plus the Go command-line client. There is no Java or .NET SDK; those languages use HTTP directly. The deployment model is always-virgin: the broker embeds schema.sql and 25 stored-procedure files numbered 001 to 025, applies all of them in lexical order at every boot under a session advisory lock before serving a request, with no migration engine, no version table and nothing to run by hand. Every statement is idempotent, and any DDL error aborts the boot naming the failing file, except a deadlock against live traffic, retried up to five attempts. Pointing a newer build at a database created by a different build is unsupported, and a downgrade means restoring a dump into a fresh database. QUEEN_APPLY_SCHEMA=0 skips the apply, moving DDL and ordering responsibility to the operator: a broker that skips it and finds an older schema fails on the first request needing a missing object, not at boot. Source: https://queenmq.com/reference/compatibility/ ### Queue options `POST /api/v1/configure` is a full replace, not a patch: every omitted key resets to its default. Integer seconds: `leaseTime` 300 from `/configure`, 60 for a push-created queue, `delayedProcessing` 0, `windowBuffer` 0, `retentionSeconds` 0, `completedRetentionSeconds` 0, `maxWaitTimeSeconds` 0, `dedupWindowSeconds` 3600 (off only at `0`). `minPopWaitTime` 0 ms, clamped 0 to 60000. `retryLimit` 3 (a count), charged only by explicit `failed` acks. Strings `namespace`, `task` `""` from `/configure`, derived from the queue name by a push. Booleans: `deadLetterQueue` and `dlqAfterMaxRetries` `true`, OR-ed, so both must be `false` to disable dead-lettering, an exhausted message then dropped; `retentionEnabled` `false`, required by both retention windows; `encryptionEnabled` `false`, storing plaintext without a valid `QUEEN_ENCRYPTION_KEY`. `maxWaitTimeSeconds` deletes whole segments including in-flight leases, ignoring `retentionEnabled`. Source: https://queenmq.com/reference/queue-options/ ### queenctl A single static Go binary; the only documented install is a repository-checkout build: `make -C clients/client-cli build` writes `clients/client-cli/bin/queenctl`, `make install` runs `go install` into `$GOBIN` (or `$HOME/go/bin`). Target: `--server`/`$QUEEN_SERVER`, `--token`/`$QUEEN_TOKEN`, `~/.queen/config.yaml`. Core commands: `push`, `pop`, `tail`, `ack`, `apply -f`, `status`, `ping`. `pop` and `tail` always emit NDJSON; `-o` is `table` on a TTY, `json` on a pipe. Exit codes: `0` success, `1` user error, `2` server error or unreachable, `3` auth, `4` no-op (an empty pop). `pop --auto-ack` commits inside the pop transaction, so messages lost after the pop are never redelivered. `tail` without `--cg` advances the real `queenctl-tail` group. `queue configure` drops zero-valued flags, so `--dlq=false` cannot disable dead-lettering; `/configure` is a full replace. `dlq drain` deletes; no command wraps the DLQ retry route; `partition seek` is end only. Source: https://queenmq.com/reference/queenctl/ ### Cluster console API The proxy serves a cluster console API at `/api/console`, eight routes on four paths: `/overview`, `/usage`, `/keys` and `/members`. Every route requires a human session, and a `qk_` cluster API key is refused with `403`. Every route except `/overview` and `/usage` also requires the `admin` cluster role. The console creates no tenant, cluster or user: those stay SQL functions on pxdb. `GET /overview` reports the cluster's live push-block reason, so a tenant reads the same cause the broker's `403` carries. Source: https://queenmq.com/reference/multi-tenant/console/ ## Benchmark Section index: https://queenmq.com/benchmarks/llms.txt ### Benchmarks The two headline figures, each with the conditions that make it true. Sustained throughput: 86,369,975,300 messages in 24 hours, about 1,000,000 msg/s per side, 0 restarts and broker resident memory flat near 4.1 GB, on Queen 1.0.0 with explicit acks on leased pops, deduplication on with a 60 second window, 200 partitions, 600 consumers, push batch 100 and 256-byte payloads, broker and PostgreSQL 18 co-located on one 32 vCPU / 62 GiB machine, loaders on separate hosts, fdatasync about 70 microseconds. Cardinality: 1,000,000 ordered partitions in one queue, created during the run at 1,000 a second, serving 200,000 msg/s with zero push, pop or ack errors, on the same machine with retention on at RETENTION_PARALLELISM=16, deduplication off, 300 consumers, over one hour. Both are single-shape runs, and neither is a claim about a shape that was not measured. Source: https://queenmq.com/benchmarks/ ### Throughput 24h 1M 24 hours, one broker against one PostgreSQL 18, both on a 32 vCPU / 62 GiB machine, Queen 1.0.0: 86,369,975,300 messages accepted at about 1,000,000 msg/s per side with 0 restarts. Broker CPU averaged 10.92 cores of 32 and PostgreSQL 11.54. Broker resident memory held flat near 4.1 GB for the whole run, and database size plateaued between 29.6 and 31.4 GB, which is retention working rather than a leak. WAL was 83 MB/s, or 83 bytes per message including the envelope. Conditions: leased pops with explicit acks, deduplication on with a 60 second window, 200 partitions, 600 consumers, push batch 100, 256-byte payloads, loaders on three separate 16 vCPU machines, fdatasync about 70 microseconds. The page states its own caveats: one workload shape, and a compressible payload. Source: https://queenmq.com/benchmarks/soak-24h/ ### A million ordered partitions 1,000,000 ordered partitions in a single queue, created during the run at 1,000 a second, serving 200,000 msg/s with zero push, pop or ack errors, on one 32 vCPU / 62 GiB machine over one hour, of which 43 minutes ran against the completed space. Conditions: leased pops with explicit acks, deduplication off, retention on with RETENTION_PARALLELISM=16, 300 consumers, push batch 100, 256-byte payloads. Without synthetic consumer work this shape held p50 27.5 ms and p99 115 ms. Storage grew 235 MB a minute, 19.6 bytes per message. Source: https://queenmq.com/benchmarks/cardinality-1m/ ### Cross-broker comparison Queen MQ, Kafka, RabbitMQ and pgmq on one 32 vCPU / 62 GB machine, Intel Xeon Platinum 8358 at 2.60 GHz with NVMe, matched at CM_CPUS=32 and CM_MEM=56g, PostgreSQL left at synchronous_commit = on and fsync = on, the same twelve-stage ordered pipeline carrying 10 to 30 ms of simulated work per message, 256-byte payloads, one run per system except Queen MQ's dense figure, which is a median of eight. Sparse, 1,000 ordered lanes at 2 messages per lane per second: all four served the full rate, and pgmq won on latency with p50 55.1 ms against Queen MQ's 71.5 ms, RabbitMQ's 92.7 ms and Kafka's 142.9 ms. Dense, the same 1,000 lanes at 12 messages per lane per second: Queen MQ served 96 percent of the offered rate at p50 680 ms and Kafka 89 percent at 2,287 ms, while pgmq served 63 percent and shed 104,780 messages and RabbitMQ served 27 percent and shed 363,942. That reversal between the two shapes is the finding. Kafka was the cheapest of the four on CPU and on disk in every shape, using 2.2 cores against Queen MQ's 7.4 on sparse and 3.9 against 16.0 on dense, which is partly a durability difference rather than pure efficiency: Kafka at its defaults pays no real fsync per commit and Queen MQ and pgmq both do. pgmq is insensitive to cardinality, returning identical percentiles across a twentyfold change in lane count, and at 20,000 properties it beat Queen MQ roughly threefold on both tail percentiles. The page states that each of these systems would go faster run by someone who operates it daily, and that for three of the four that is not its authors. Source: https://queenmq.com/benchmarks/comparison/ ### Conformance Queen MQ's conformance evidence is `test/run.sh`: six client suites (JavaScript, Python, Go, Rust, C++ and the queenctl CLI) on three topologies each, plus the broker's unit tests, an HA mesh assertion and a two-tenant isolation suite, every cell its own throwaway Docker stack. The `tenanted` lane reruns each client suite against a broker with tenant scoping on and no tenant header, and any divergence from the flag-off lane fails the run either way. The recorded isolation run is 45 assertions, 0 failures. The PHP SDK has no suite in the matrix. Source: https://queenmq.com/benchmarks/conformance/ ## What this summary does not cover Per-language SDK reference, the HTTP route reference, the SQL schema, the internals of the storage and maintenance engines, and the full configuration reference are not summarised here. Reach them from the section indexes above or from https://queenmq.com/llms.txt.