Configuration reference
Defaults and limits for Consumer connections, topology, delivery, inbox/outbox and lifecycle settings.
This reference describes the lilyrs 0.1.0 Consumer contract. Duration units are included in field names; do not confuse _millis and _secs. Unknown typed configuration fields are rejected. Successful TOML deserialization does not mean every runtime contract has passed; topology and connection plans are validated as well.
Section map#
| Section | Responsibility |
|---|---|
[rabbitmq.consumer] |
Consumer connection and recovery profile |
[[rabbitmq.topology.queues]] |
Physical queue, binding and delivery policy |
[rabbitmq.topology.queues.retention] |
Six required limits for the main queue, retry buckets and DLQ |
[rabbitmq.topology.queues.transactional_inbox] |
Database binding and inbox/outbox policy, with its feature enabled |
[queue_client] / [[queue_client.cells]] |
Ordinary publisher connections, separate from the Consumer connection |
[postgresql] / [database] / [cache] |
PostgreSQL / MongoDB / Redis integrations respectively |
[lifecycle] |
Application shutdown budget |
The topology section is credential-free: do not use ${secret:...} or ${file:...} in identity fields. Connection secrets are resolved in their connection section. Follow configuration and secrets for file discovery, environment overrides and resolver selection.
Consumer connection#
| Field | Default | Rule |
|---|---|---|
connection_string |
None | URI form; cannot be combined with separate username/password/hostname/port/vhost fields. |
username, password, hostname |
None | Non-empty values are required when no URI is supplied. |
port |
AMQP: 5672; AMQPS: 5671 | Port used when constructing a connection from separate fields. |
vhost |
/ | Default for separate-field mode; a decoded URI vhost is at most 255 UTF-8 bytes. |
use_tls |
None | Explicit true/false required; must agree with the URI scheme. |
pool_size |
5 | 1–32; connection count, not handler concurrency. |
connection_timeout_secs |
10 | 1–120 seconds. |
confirm_timeout_secs |
10 | 1–300 seconds. |
heartbeat_secs |
30 | 5–600 seconds. |
max_reconnect_attempts |
5 | 1–100 connection/reconnect attempts. |
reconnect_backoff_millis |
250 | 50–30,000 ms. |
persistence_enabled |
true | Carried into connection options. Consumer retry/DLQ preserves the incoming message properties; transactional outbox always publishes persistently. The regular publisher preference belongs under [queue_client]. |
connection_string does not support a query or fragment; use typed fields for heartbeat and timeouts. The URI must contain a host, username and password. use_tls = true requires amqps://, while false requires amqp://. Do not confuse the separate-field default / vhost with the empty-vhost meaning of an explicit trailing slash in a URI.
TLS and mTLS material#
[rabbitmq.consumer.tls] field |
Rule |
|---|---|
additional_ca_bundle |
Optional absolute PEM path; extends the platform trust store; at most 4 MiB. |
client_certificate_chain |
Optional absolute PEM path; at most 1 MiB. |
client_private_key |
Optional absolute path to an unencrypted PEM private key; at most 128 KiB. |
Supply the client certificate and private key together; a missing counterpart is rejected before connection. Do not provide TLS material with use_tls = false. Publisher single profiles and factory cells use the same TLS contract in their own tls tables. See transport security for setup details.
Queue identity and topology#
| Field | Default | Rule |
|---|---|---|
name, exchange_name, routing_key |
Required | 1–200 UTF-8 bytes; no empty value, surrounding whitespace or control characters. |
exchange_kind |
direct | The supported exchange kind. |
queue_type |
classic | classic or quorum. |
topology_ownership |
framework_managed | framework_managed or external. |
durable |
true | Must be true for quorum. |
exclusive |
false | true is unsupported. |
auto_delete |
false | true is rejected for quorum. |
single_active_consumer |
false | Active-consumer election; does not set process count or handler concurrency. |
max_priority |
None | Optional 1–16 for classic; omit for quorum. |
message_ttl_ms |
None | If supplied, a positive u32; main-queue message TTL. |
dead_letter_exchange |
{exchange_name}.dlx.v2 | Must be explicit for external ownership. |
dead_letter_routing_key |
Queue name | Must be explicit for external ownership. |
Derived retry/DLQ names must also fit the 200-byte identity limit; a long base name may be valid by itself but produce an oversized derived name. The DLQ is named {queue_name}.dlq.v2. Operators provision externally owned resources; Lily’s passive checks do not amount to a complete management-API audit of every broker policy.
Delivery, concurrency and retries#
| Field | Default | Rule |
|---|---|---|
concurrency |
1 | 1–1024 handler permits. |
prefetch_count |
10 | 1–4096 unacknowledged deliveries. |
delivery_buffer_capacity |
prefetch_count | 1–prefetch_count; bounded local buffer. |
max_message_size_bytes |
1048576 | 1–16777216 bytes; applied before decoding or cloning. |
retry_attempts |
0 | 0–100; additional attempts after the initial delivery. |
retry_backoff_millis |
1000 | 100–300000 ms. |
max_retry_backoff_millis |
60000 | Initial backoff–900000 ms. |
retry_jitter_ratio |
0.0 | Finite 0.0–0.5. |
delivery_execution_timeout_millis |
30000 | 100–900000 ms; aggregate delivery budget for the pipeline and cleanup. |
settlement_timeout_millis |
5000 | 1–60000 ms; for one original ACK/NACK operation. |
DeliveryDeadline is the shared cutoff for normal before/guard/extractor/handler/after work. It does not start a fresh timeout for every stage or a second reserve for normal after callbacks. Jitter deterministically selects among fixed queue-level TTL buckets instead of creating unlimited per-message delay queues. At most 32 retry buckets are accepted per logical queue and 4096 per topology.
Six required retention fields#
| Field | Meaning |
|---|---|
main_max_messages |
Main-queue message count |
main_max_bytes |
Main-queue body-byte total |
retry_bucket_max_messages |
Message count for each retry bucket |
retry_bucket_max_bytes |
Body-byte total for each retry bucket |
dead_letter_max_messages |
DLQ message count |
dead_letter_max_bytes |
DLQ body-byte total |
Provide all six under [rabbitmq.topology.queues.retention]; they have no defaults. Every value is in 1..=i64::MAX. These are broker retention bounds, not a total application heap budget or database inbox-retention period. The typed retention contract still applies when retry_attempts = 0.
Transactional inbox and outbox#
This table covers [rabbitmq.topology.queues.transactional_inbox]. Its corresponding facade feature must be enabled. backend is required and must be postgresql or mongodb. database_cell is required in factory mode and forbidden in single mode; if supplied, it must contain 1–128 trimmed, control-free UTF-8 bytes.
| Field | Default | Rule |
|---|---|---|
inbox_lock_timeout_millis |
30000 | 1–60000; minimum 1000 for MongoDB. |
outbox_claim_lease_millis |
30000 | 1–900000; cannot be shorter than the publication timeout. |
relay_batch_size |
100 | 1–1000 records. |
relay_max_in_flight_bytes |
8388608 | 1–268435456; an additional absolute limit of 16 MiB applies to each message. |
relay_poll_interval_millis |
250 | 1–60000. |
relay_publish_timeout_millis |
10000 | 1–60000. |
relay_max_publish_attempts |
5 | 1–100; includes the first publication. |
relay_retry_initial_backoff_millis |
250 | 1–60000. |
relay_retry_max_backoff_millis |
30000 | 1–900000; cannot be smaller than the initial backoff. |
inbox_retention_secs |
604800 | 1–31536000; completed inbox records. |
outbox_retention_secs |
604800 | 1–31536000; delivered outbox records. |
cleanup_interval_secs |
3600 | 1–86400; cannot exceed either retention horizon. |
shutdown_drain_timeout_millis |
30000 | 1–300000; does not extend the outer shutdown deadline. |
inbox_lock_timeout_millis is not the maximum execution time of an application transaction. Work is separately bounded by delivery and host budgets. Queues sharing a backend/cell must have identical complete transactional configurations. Programmatic configuration does not bypass these relational rules.
MongoDB transaction retry policy#
These fields belong under [rabbitmq.topology.queues.transactional_inbox.mongodb]. Omitting the table uses the default policy; supplying it for a PostgreSQL binding is an error.
| Field | Default | Rule |
|---|---|---|
max_transaction_attempts |
3 | 1–100; includes the initial body execution. |
retry_initial_backoff_millis |
10 | 1–60000. |
retry_max_backoff_millis |
1000 | 1–900000; cannot be less than the initial backoff. |
commit_retry_timeout_millis |
10000 | 1–60000; also capped by the existing work deadline. |
Body replay, commit reconciliation and lease contention are separate paths. Do not treat them as one counter with the queue’s retry_attempts value. MongoDB transactions explains when the pipeline runs again.
Lifecycle and builder choices#
| Choice | Default / limit |
|---|---|
[lifecycle].shutdown_timeout_secs |
30 seconds; 1–3153600000. One aggregate shutdown budget. |
.pipeline_initialization_timeout(Duration) |
30 seconds; greater than zero, at most 300 seconds. Shared by all pipeline constructors. |
| Tracing | Disabled; explicitly select owned config/path or external tracing. |
| AsyncAPI | Opt-in through consumer-asyncapi and one .asyncapi(config) call. |
| Container | Consumer-owned, or explicit .container(Arc<ApplicationContainer>). |
These upper bounds are not recommended production timeout values. Shutdown does not restart a timer for every substage; pending DI rollback is also bounded by the Consumer attempt root. The corrected meanings of older source-document deadline and rollback statements are recorded in troubleshooting.
Where the publisher profile belongs#
[queue_client] has its own mode = "single" or "factory" choice. Single-mode connection fields belong in that table; factory connections belong under [[queue_client.cells]] with a required name. Do not rename sections to use the Consumer connection as a publisher connection. Publisher fields share the typed TLS/timeout contract above; an omitted factory-cell pool_size has a runtime default of 1, while the deserialized single-profile default is 5.
Publisher-only topology bootstrap is explicit and uses the credential-free [rabbitmq.topology] plan. See publishing for the facade features, envelope and confirmation flow needed to send messages. Database and Redis fields have their own backend validation rules; they are not Consumer queue-policy fields.
Sources for this page v0.1.0
This guide is based on the reviewed framework commit.