A default reaches a message through one of three layers, and the layers are resolved in a fixed order:
- Request parameter: a query parameter or body field on one call.
- Queue configuration: a column on the queue’s
queen.queuesrow, written byPOST /api/v1/configureor created implicitly by the first push. - Environment: process-wide, read once at boot.
Where the same setting exists at two layers, the more specific one wins, but only
when it is present and positive. That qualifier matters: a pop asking for
leaseSeconds=0 does not get a zero-second lease, it falls through to the queue’s
value.
Values where two numbers circulate
These four are the ones worth memorising, because a plausible-looking wrong number exists for each.
| Setting | Effective default | The other number, and why |
|---|---|---|
| Lease time | 60 s on a queue created implicitly by a push; 300 s after an explicit /configure |
One column, two writers. queen.queues.lease_time has a column default of 60, which is what an implicitly created queue gets; /configure computes leaseTime with a default of 300 and writes it explicitly into that same column. So the value depends on how the queue came into existence, and what the config display shows is what the pop path leases with. |
| Deduplication window | 3600 s, on | Deduplication is not opt-in. queen.queues.dedup_window_seconds defaults to 3600 and /configure re-applies 3600 whenever dedupWindowSeconds is omitted. Only an explicit 0 disables it. |
RETENTION_INTERVAL |
5000 ms | 300000 was the retired engine’s monolithic five-minute sweep. The log engine runs bounded autocommitting steps, so the cadence is 5 s. |
| Pop long-poll timeout | 30000 ms | Read from DEFAULT_TIMEOUT first, then POP_DEFAULT_TIMEOUT_MS, then 30000. Both names exist; DEFAULT_TIMEOUT takes precedence, so setting only POP_DEFAULT_TIMEOUT_MS while DEFAULT_TIMEOUT is also set has no effect. |
One more that is often assumed off: QUEEN_HOTLIST defaults to on. The
broker selects wildcard-pop candidates in memory rather than by scanning
PostgreSQL. QUEEN_HOTLIST=0 reverts to the SQL candidate scan.
And one that is often assumed to be a flag and is not: the key/value and timer
surfaces have no boot switch. Every broker registers those routes and exposes
their metrics, exactly as it does for push and pop. Pausing a live surface is a
runtime call on POST /api/v1/system/kv-timers, which answers 503, never 404.
QUEEN_KV_REQUIRE_GRANT is derived from QUEEN_TENANCY_HEADER rather than
defaulted independently. With tenancy on, a tenant with no quota row is a
denial; with tenancy off, a self-hosted operator, who is their own customer,
configures nothing.
Environment defaults that shape behaviour
The full list, with every variable, is in
Environment variables. These are the ones whose default
changes what a client observes. The QUEEN_ADMISSION_* defaults in particular
are the settled output of a measured control loop rather than round numbers:
flow control explains what the loop measures and why
each of them sits where it does.
| Variable | Default | Effect of the default |
|---|---|---|
PORT |
6632 |
The one port the HTTP listener serves. |
QUEEN_BIND_ADDR |
0.0.0.0 |
Every interface. A host or IP only: a value carrying its own port is a fatal boot error rather than a silent bind somewhere else. It also becomes the mesh listener’s address unless QUEEN_MESH_BIND_ADDR overrides it. |
QUEEN_MAX_BODY_BYTES |
67108864 (64 MiB) |
Larger request bodies are rejected with 413 before any handler runs. |
DB_POOL_SIZE |
160 |
Upper bound on concurrent PostgreSQL work. A request that cannot get a pooled connection at all answers 500 with {"error":"pool"}. |
QUEEN_STMT_TIMEOUT_MS |
30000 |
A statement past this is abandoned, cancelled server-side, and its pooled connection is quarantined. |
QUEEN_ADMISSION_MIN |
96 on the default pool |
Floor on the admitted-write-transaction budget. It is derived, not a constant: two thirds of (DB_POOL_SIZE minus QUEEN_ADMISSION_POOL_RESERVE), never below 8, which is 96 at DB_POOL_SIZE=160 with reserve 16. Shrink the pool and the floor shrinks with it. A fixed floor larger than the pool would admit more concurrent transactions than there are connections. |
QUEEN_ADMISSION_MAX |
128 |
Ceiling on the same budget, itself capped at DB_POOL_SIZE - QUEEN_ADMISSION_POOL_RESERVE, so a pool smaller than 144 lowers the effective ceiling without any change here. |
QUEEN_ADMISSION_POOL_RESERVE |
16 |
Pooled connections held back from the admission budget so admitted work never queues on the pool and unmetered admin writes cannot deadlock behind metered ones. |
QUEEN_ADMISSION_SHARE_PUSH / _POP / _ACK / _MAINT |
0.25 / 0.40 / 0.30 / 0.05 |
Guaranteed lane shares of the budget. They order the wake queue when the budget is exhausted (ack, then pop, then push, then maint); they are not slot reservations and not a floor on a lane’s own concurrency cap. |
QUEEN_POP_FUSION |
false |
Off. Each pop claim commits on its own. Set it and N claim legs share one transaction and one commit, and the Pop lane takes one admission slot per fused flush instead of one per claim. |
DEFAULT_TIMEOUT / POP_DEFAULT_TIMEOUT_MS |
30000 |
How long a wait=true pop parks when the client sends no timeout. |
DEFAULT_SUBSCRIPTION_MODE |
new |
Where a consumer group starts when its first pop sends no subscriptionMode: new at the partition’s tail, all at the oldest retained offset. Only consulted on a group’s first contact, and ignored entirely by group-less pops, which are always all. |
POP_WAIT_INITIAL_INTERVAL_MS |
100 |
First re-query interval of a parked pop; grows past POP_WAIT_BACKOFF_THRESHOLD (3) by POP_WAIT_BACKOFF_MULTIPLIER (2.0) up to POP_WAIT_MAX_INTERVAL_MS (1000). A push-wake resets it. |
QUEEN_POP_PENDING_GATE |
on | Parked re-polls on the single-partition and discovery pop routes probe a cheap pending check and skip the full pop procedure when nothing is deliverable. Kill switch only; the wildcard route’s gate is unconditional. |
RETENTION_INTERVAL |
5000 |
Maintenance cycle cadence. Scheduled through the queen.maintenance_leases claim row, so the value is the true cluster cadence: exactly one instance sweeps per period, whatever the replica count. |
RETENTION_BATCH_SIZE |
1000 |
Maximum segment rows deleted per bounded step, and partitions deleted per cleanup batch. |
RETENTION_PARALLELISM |
1 |
Concurrent per-partition step workers in retention phases 1 to 3, clamped to 16. 1 is the historical serial cycle, so an upgrade changes nothing until you raise it. Each worker holds one maintenance-lane admission slot and one pooled connection while it runs, so raise QUEEN_ADMISSION_SHARE_MAINT with it. |
PARTITION_CLEANUP_DAYS |
30 |
How long a partition must be empty and idle before the cleanup phase deletes the row. QUEEN_PARTITION_CLEANUP_ENABLED=false keeps every partition forever. |
METRICS_FLUSH_MS |
60000 |
How often per-queue counters reach PostgreSQL, and therefore how stale a per-queue Prometheus series can be. |
STATS_INTERVAL_MS |
10000 |
Cadence of the stats reconciler that feeds the dashboard’s pending and total counts. A true cluster cadence: scheduled through the queen.maintenance_leases claim row, one refresh per period. |
RETAINED_BYTES_INTERVAL_MS |
600000 |
Cadence of the retained-bytes lane, the one log_segments scan in the stats family; feeds the retainedBytes gauge the proxy storage quota reads. Scheduled through the claim row like the two above. |
QUEEN_CACHE_REFRESH_INTERVAL_MS |
60000 |
How long a lost peer notification can leave a stale per-queue cache in place. |
QUEEN_HOTLIST |
on | Broker-side candidate selection for wildcard pops. |
QUEEN_HOTLIST_RESEED_FULL_MS |
300000 |
How often a ring is re-derived from every partition of its queue instead of only the recently written ones. It bounds how long a partition wrongly missing from a ring can stay missing. 0 is the kill switch: every reseed is a full walk again, and the repair paths that exist only because a windowed pass cannot see a cursor move are switched off with it. |
QUEEN_ACK_FUSION |
on | Coalesces full-batch acks into one commit per flush. |
QUEEN_DEDUP_CACHE |
on, 512 MB |
Broker-side dedup cache. Correctness never depends on it; disabled, SQL probes the full window. |
JWT_ENABLED |
false |
No authentication. Every route is open, including admin ones. |
QUEEN_TENANCY_HEADER |
false |
Every request resolves to the default tenant 00000000-0000-0000-0000-000000000001. |
QUEEN_SWEEPER |
true |
Spawned on every broker, because the surfaces it serves are on every broker. Off, expired keys are never pruned and timers never fire: nothing is lost, it waits. This decides whether a background task exists, not whether a surface does. |
QUEEN_KV_POOL_SIZE |
16 on the default pool |
The key/value routes take their connections from a pool of their own, DB_POOL_SIZE / 10 clamped to 4..32, so a slow database costs them their throughput instead of costing the message path its connections. Derived, like the admission floor: shrink the pool and this shrinks with it. |
QUEEN_TIMERS_MAX_HORIZON_S |
7776000 (90 days) |
Finite on purpose, and not “0 means unlimited”. A finite horizon is what keeps the pending-timer quota cyclic: with an infinite one a tenant fills it once and never frees it. |
QUEEN_SWEEPER_LEASE_MS |
30000 |
How long a broker holds a claimed timer, and therefore the longest a cancel can answer too_late after that broker dies. |
QUEEN_APPLY_SCHEMA |
true |
The broker applies the schema and all stored procedures on every boot. |
QUEEN_SYNC_ENABLED |
true |
Enabled, but inert with no QUEEN_MESH_PEERS: a single broker binds nothing. |
QUEEN_ENCRYPTION_KEY |
unset | At-rest payload encryption is off, and a queue flagged encryptionEnabled stores plaintext. |
FILE_BUFFER_DIR |
/var/lib/queen/buffers |
Where pushes spool during a database outage. Must be writable and persistent, or the durability spool silently has nowhere to go. |
LOG_LEVEL |
info |
RUST_LOG overrides it; both accept full filter syntax. |
Queue option defaults
Applied by POST /api/v1/configure, and by the column defaults for a queue
created implicitly by a push. Since 1.6.0 /configure merges: on an edit an
omitted key keeps the value the queue already has, and the value in this table
is what a create lands on, what an explicit null restores, and what
"mode": "replace" puts back for every key the body omits. See
Queue options for what each one does.
| Option | Default | Note |
|---|---|---|
namespace |
"" |
For a push-created queue, derived from the queue name before the first .. |
task |
"" |
For a push-created queue, derived from the name between the first and second .. |
priority |
0 |
Stored and echoed; no pop, ack or maintenance path reads it. |
leaseTime |
300 (configure) / 60 (push-created) |
Seconds. |
retryLimit |
3 |
Explicit failed acks charged before dead-lettering. |
maxSize |
0 |
Stored and echoed; there is no queue-depth cap behind it. |
deadLetterQueue |
true |
Dead-lettering is on for an unconfigured queue. |
dlqAfterMaxRetries |
true |
Combined with the previous flag by OR. Both must be false to disable dead-lettering. |
delayedProcessing |
0 |
Seconds of visibility delay; 0 is off. |
windowBuffer |
0 |
Seconds of quiet before a partition is delivered; 0 is off. |
retentionEnabled |
false |
Retention is opt-in. |
retentionSeconds |
0 |
Needs retentionEnabled and a positive value to do anything. |
completedRetentionSeconds |
0 |
Same gate. |
maxWaitTimeSeconds |
0 |
Age eviction. Runs whether or not retentionEnabled is set. |
minPopWaitTime |
0 |
Milliseconds a non-empty under-full pop may wait to fatten. Clamped to 0–60000. |
encryptionEnabled |
false |
Requires a valid QUEEN_ENCRYPTION_KEY to have any effect. |
dedupWindowSeconds |
3600 |
Stored on queen.queues like every other option, and echoed in the /configure response. |
Request parameter defaults
| Endpoint | Parameter | Default |
|---|---|---|
GET /api/v1/pop/queue/:queue |
batch |
200, unless the request delegated it with autopilot |
partitions |
1, unless the request delegated it with autopilot |
|
autopilot |
absent; true asks the broker to size the knobs the request did not send, per parameter |
|
autoAck |
false |
|
wait |
false |
|
timeout |
the configured pop timeout (30000 ms) | |
consumerGroup |
__QUEUE_MODE__ |
|
subscriptionMode |
new (DEFAULT_SUBSCRIPTION_MODE); always all when consumerGroup is absent |
|
conflation |
false; only the group’s FIRST registration stores it, and the stored value wins afterwards |
|
leaseSeconds |
queue leaseTime, else 60 |
|
GET /api/v1/pop/queue/:queue/partition/:partition |
same, except partitions |
ignored (a specific pop is one partition) |
GET /api/v1/pop (discovery) |
namespace / task |
none (a call with neither is a 400) |
POST /api/v1/lease/:leaseId/extend |
seconds |
60, also for an empty body |
POST /api/v1/ack, /ack/batch |
consumerGroup |
__QUEUE_MODE__ |
status |
completed when absent; an unrecognised value is treated as failed |
|
GET /api/v1/messages |
limit / offset |
200 / 0 |
GET /api/v1/dlq |
limit / offset |
100 / 0 |
GET /api/v1/status/queues |
limit / offset |
100 / 0 |
GET /api/v1/traces/by-name/:traceName |
limit / offset |
100 / 0 |
GET /api/v1/traces/names |
limit / offset |
50 / 0 |
GET /api/v1/consumer-groups/lagging |
minLagSeconds |
3600 |
DELETE /api/v1/consumer-groups/:group |
deleteMetadata |
true |
POST …/queues/:queue/partitions/:partition/seek |
body | an empty body means toEnd: true |
POST …/queues/:queue/seek |
body | required (toEnd: true or a timestamp), else 400 |
POST /api/v1/kv, a getPrefix op |
limit |
100, clamped to QUEEN_KV_PREFIX_LIMIT (1000) and never rejected |
keysOnly |
false |
|
PUT /api/v1/kv/:ns/*key |
ttlSeconds or forever |
no default: exactly one of the two is mandatory, and a put never inherits the previous key’s expiry |
GET /api/v1/timers/:queue |
limit / after |
100 clamped to 1000 / none |
POST /api/v1/timers |
partition |
Default |
Fixed values that are not configurable
| Value | What it is |
|---|---|
Default |
The partition name used when a push names none. |
__QUEUE_MODE__ |
The consumer group used when a pop or ack names none. Its cursor is real state, like any other group’s. |
00000000-0000-0000-0000-000000000001 |
The default tenant. Used for every request when QUEEN_TENANCY_HEADER is off, and when it is on but the header is absent or empty. |
60 s |
The lease floor used when the queue’s configuration row cannot be read (the lookup could not reach the database, or the row is somehow absent). It equals the queen.queues.lease_time column default on purpose. |
30 s |
How long the broker caches a queue’s delayedProcessing, windowBuffer and minPopWaitTime for its in-memory scheduler, so a /configure change to those three takes effect within that window rather than instantly. |
737001 |
The advisory lock inside the retention cycle. Belt, not scheduler: cadence comes from the retention row in queen.maintenance_leases, and the lock only excludes overlap against instances that predate the claim row. |
737002 |
Same role for the stats reconciler (stats_refresh row); also excludes the manual refresh route. |
737003 |
Same role for the retained-bytes lane (retained_bytes row). |
778120010 |
The advisory lock that serialises the boot-time schema apply across instances. |