delivery.timeout.ms
deliverydefault: 120000 (2 minutes)
type: long (milliseconds)
delivery.timeout.ms is the upper bound on the total time a producer will wait for a record to be successfully sent, including retries and queuing. If the record cannot be delivered within this window, the producer reports failure. It must be >= linger.ms + request.timeout.ms. Combined with retries=Integer.MAX_VALUE, delivery.timeout.ms is the primary way to bound delivery attempts.
Details
delivery.timeout.ms provides a single knob to control overall delivery time bound. It supersedes the older combination of retries * retry.backoff.ms for timeout control.
Delivery timeline: Record produced → queues in batch (up to linger.ms) Batch sent → waits for ack (up to request.timeout.ms = 30s default) If no ack → retry after retry.backoff.ms (default 100ms) Loop until success or delivery.timeout.ms expires
Key relationships: delivery.timeout.ms >= linger.ms + request.timeout.ms retries=Integer.MAX_VALUE (let delivery.timeout.ms control total time) retry.backoff.ms=100–1000 (exponential backoff between retries)
With enable.idempotence=true: Retries are deduplicated by sequence number. Increasing retries does not risk duplicates. Set retries=Integer.MAX_VALUE and let delivery.timeout.ms be the sole control.
Failed delivery handling: If delivery.timeout.ms expires, the producer calls the callback or throws TimeoutException. The application must decide: dead-letter queue, local storage, metric+alert, or drop. For critical records (payments, orders): dead-letter to a separate topic or durable local store.
With transactions: delivery.timeout.ms must be < transaction.timeout.ms (default 60s) or transactions may abort before delivery completes.
Recommended values
| Scenario | Value |
|---|---|
| Critical data (payments, orders) | delivery.timeout.ms=120000 with dead-letter on failure |
| Latency-sensitive with fast fail | delivery.timeout.ms=10000 |
| Transactional producers | delivery.timeout.ms < transaction.timeout.ms |