lilydocs
HTTP APIWebSocketConsumer
Reference5 min read

Limits and guarantees

Understand delivery, transaction, metadata and shutdown limits with their exact guarantee boundaries.

Consumer owns application lifecycle and delivery-resource management. It does not turn every operation across the broker, database and external systems into one distributed transaction. The selected guarantee mode, bounded policies and observed terminal result together determine what the application can rely on.

Delivery guarantees#

Behavior Provided guarantee Application responsibility
At-least-once ACK uncertainty or redelivery can run the handler again. Make business side effects idempotent.
Transactional inbox A retained completed record skips the business pipeline for the same handler/event. Use the same database transaction context and an appropriate retention window.
Transactional outbox Business data and the outgoing record commit atomically; the relay tracks confirmation. Downstream deduplication and destination provisioning.
Retry/DLQ handoff Original ACK is ordered after successful confirmed handoff. DLQ monitoring, triage and controlled replay.

Retry counts, queue retention/TTL, operator deletion and broker durability settings affect the window in which a message can be processed. At-least-once is not unlimited retention or a promise that every business operation will eventually succeed. Headerless messages have no V1/JSON fallback; the canonical envelope is an admission requirement.

Transaction boundaries and replay#

Inbox completion, business writes through the same transaction context and outbox records are atomic within the selected database. Broker ACK, relay publication, another database or cell, Redis, HTTP and file operations are outside that boundary. There is no broker–database 2PC or end-to-end exactly-once guarantee. Transactional inbox and outbox describe the crash windows.

A MongoDB transient-transaction retry can replay the entire pipeline in a fresh scope, while commit-result reconciliation repeats the same commit. PostgreSQL concurrent duplicates use the normal application retry/DLQ path. Inbox deduplication is bounded by retention and can be affected by handler-identity renaming.

Plan and pipeline limits#

Resource Limit
Configured physical queues 256
Linked handlers 512
Trace cells 256
Consumer descriptor / aggregate plan 1024 bytes / 256 KiB
Effective middleware / guard plan At most 64 each
Handler parameters At most 16 excluding &self; at most one terminal payload extractor
Handler concurrency 1–1024 permits per queue
Prefetch / local buffer Prefetch at most 4096; buffer at most prefetch
Retry buckets 32 per queue; 4096 across the topology

These values bound different resources. concurrency = 8 does not request eight processes or eight broker subscriptions; it sets handler-admission permits. Prefetch bounds unacknowledged broker deliveries. Total memory use also depends on payload sizes, buffers, active handlers and application allocations.

Payload and metadata limits#

Field Limit
Queue delivery body Default 1 MiB; absolute maximum 16 MiB
Outbox body Default policy 8 MiB; absolute maximum 16 MiB; additional MongoDB BSON overhead
Queue/exchange/routing identities 1–200 UTF-8 bytes, including derived names
Content kind At most 64 bytes and a canonical content format
AMQP header count / key 64 entries / 128 bytes per key
AMQP value / aggregate metadata 8 KiB / 32 KiB
Nested AMQP metadata Depth 4; at most 256 elements
W3C traceparent / tracestate 55 bytes / 512 bytes

The framework also reserves room for retry, failure and trace handoff metadata. Filling application headers to the theoretical total can leave no space for republication; the accepted footprint accounts for fields the framework will add. A byte limit is not a character count: multibyte UTF-8 content reaches it with fewer characters.

Lifecycle, deadlines and settlement#

The normal pipeline uses a shared delivery cutoff. Cancellation is signaled first, and execution is dropped if necessary after a bounded cooperation window. The start of forced drain and final settlement-authority revocation are distinct moments. A healthy channel can settle during the cooperative window; a lost transport generation cannot retain authority through its old channel.

Consumer’s runtime supervisor owns cleanup. Dropping or aborting a run / run_with_cancellation waiter or the managed startup waiter requests shutdown; the owner retains responsibility for cleaning up resources. Dropping a ManagedConsumer::wait() observer future does not initiate shutdown. Once polled, ManagedConsumer::shutdown() requests shutdown; dropping that waiter future does not cancel the supervisor. The Tokio runtime running asynchronous fallback must remain alive for that fallback to finish. The parent owner remains responsible for disposing of a caller-owned container and external tracing.

A shutdown report distinguishes an action returning successfully, confirmed dependency termination and success of the overall shutdown. Unresolved settlement is not reported as a successful ACK. Graceful shutdown does not guarantee an empty outbox or completion of every external side effect.

Observability and out-of-scope surfaces#

ManagedConsumer::snapshot() gives bounded aggregate state without payloads, event IDs, routing keys, broker endpoints or credentials. The separate delivery_terminal_observations() diagnostic API retains at most 4096 observations and may include event IDs; do not extend the snapshot privacy contract to that separate API. Neither is a complete transactional audit history.

Consumer does not create automatic HTTP health/metrics routes, CORS, CSRF, cookies, multipart endpoints or a dashboard. RawDelivery is not a raw Lapin channel or manual ACK handle. Private provider SPIs and qualification helpers are not public application extension points. See settlement, operational snapshots and AsyncAPI for the supported public paths.

Sources for this page v0.1.0

This guide is based on the reviewed framework commit.

QUICK START
Documentation
Source code