Carlquist is designed for reliable delivery across unreliable legacy systems and networks. We provide at-least-once delivery with idempotency controls, configurable retries, and dead-letter handling so integrations can be made deterministic and debuggable.
Carlquist provides at-least-once delivery. Every event that enters the pipeline will be delivered to the configured target at least once. Duplicate delivery is possible during retries; use idempotency keys to make processing effectively-once.
Every event carries an X-Carlquist-Idempotency-Key header containing a UUID. The key is scoped per-stream, per-target. Consumers should use this key to deduplicate events on their end.
Carlquist tracks delivery acknowledgment per idempotency key. If the target returns a 2xx response, the event is marked as delivered and will not be retried.
POST /hooks/orders HTTP/1.1
Host: your-app.com
Content-Type: application/json
X-Carlquist-Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
X-Carlquist-Stream: orders.created
X-Request-Id: req_7f3a9b2c
{ "order_id": "ORD-12345", "status": "created", ... }
The default retry policy uses exponential backoff with jitter. The schedule progresses as follows:
Attempt 1: 1 second
Attempt 2: 5 seconds
Attempt 3: 30 seconds
Attempt 4: 2 minutes
Attempt 5: 10 minutes
Attempt 6: 1 hour
Attempt 7: 6 hours
Total window: ~7.5 hours across 7 attempts
Retry behavior is configurable per stream:
carlquist stream update orders.created \
--max-retries 10 \
--initial-delay 2s \
--max-delay 30m \
--backoff-multiplier 3
Responses with 4xx status codes (except 429 Too Many Requests) are considered permanent failures. They are not retried and go directly to the dead-letter queue with the response body attached for debugging.
Events that exhaust all retry attempts are moved to the dead-letter queue. Each DLQ entry includes:
DLQ entries are retained for 7 days by default. Enterprise plans support extended retention: 14, 30, or 90 days.
Individual events or bulk batches can be replayed from the DLQ via the CLI or dashboard:
# Replay a single event
carlquist dlq replay --stream orders --id evt_xxx
# Replay all failed events from a time range
carlquist dlq replay --stream orders \
--from 2026-02-20 --to 2026-02-25
# Replay with a filter
carlquist dlq replay --stream orders \
--status-code 503
DLQ depth is exposed as a Prometheus-compatible metric:
carlquist_dlq_depth{stream="orders.created"} 12
If the target returns 429 Too Many Requests or is consistently slow (p99 latency exceeding 10 seconds), Carlquist automatically reduces the delivery rate. Rate recovery follows an AIMD (Additive Increase / Multiplicative Decrease) algorithm — rate drops quickly on overload and recovers gradually.
Backpressure events are logged and visible in the dashboard under the stream's health panel.
Events from a single adapter are delivered in order within a single stream. Cross-stream ordering is not guaranteed. If strict ordering is required across multiple event types, route them through a single stream per logical sequence.
Only successful deliveries (2xx response from target) count as billable events. The following are not billed:
Fanout billing: If one source event is delivered to N targets (fanout), it counts as N billable events. For example, an order.created event delivered to 3 webhooks counts as 3 billable events.