Skip to content

Acknowledgement Policies

rabbitkit supports four acknowledgement policies, selected per subscriber via ack_policy=.

AUTO (default)

rabbitkit manages settlement automatically based on handler outcome.

Handler result Action
Returns normally basic.ack
Raises transient exception retry or basic.nack(requeue=False)
Raises permanent exception basic.reject → DLQ
@broker.subscriber(queue="orders")  # ack_policy=AckPolicy.AUTO is the default
async def handle(body: dict) -> None:
    process(body)  # ack on success, nack/retry on exception

Use AUTO for most consumers. Combine with RetryConfig for transient failures.

MANUAL

The handler receives the raw RabbitMessage and settles it explicitly. rabbitkit never auto-acks.

from rabbitkit import AckPolicy, RabbitMessage

@broker.subscriber(queue="payments", ack_policy=AckPolicy.MANUAL)
async def handle(msg: RabbitMessage) -> None:
    try:
        result = await charge(msg.body)
        await msg.ack_async()
    except TransientError:
        await msg.nack_async(requeue=True)
    except PermanentError:
        await msg.reject_async(requeue=False)

Use MANUAL when the handler needs full settlement control — for example, when settlement depends on an external confirmation or a two-phase commit.

Warning: If you forget to ack/nack, the message stays unacked until the connection closes.

NACK_ON_ERROR

Successful handlers are auto-acked. Failed handlers are nacked with requeue=False.

@broker.subscriber(queue="events", ack_policy=AckPolicy.NACK_ON_ERROR)
async def handle(body: bytes) -> None:
    process(body)  # nack (no requeue) on any exception

Use when you want errors to go straight to the DLQ without retry. Do not combine with RetryConfig.

ACK_FIRST

The message is acknowledged before the handler runs.

@broker.subscriber(queue="logs", ack_policy=AckPolicy.ACK_FIRST)
async def handle(body: bytes) -> None:
    write_log(body)  # message already acked — loss is possible if this fails

Warning: If the handler fails after the ack, the message is lost permanently. Use only when message loss is acceptable — for example, best-effort audit logging.

Never use ACK_FIRST for financial transactions, order processing, or any flow where at-least-once delivery is required.

Message Safety

For AUTO and MANUAL policies, rabbitkit follows this guarantee:

The original message is never acknowledged before the retry or DLQ publish is confirmed by the broker.

If retry publishing fails, the original message is not acked. It remains unacked and will be redelivered after the connection recovers or the channel times out.

See Message Safety for the full guarantee and failure-case analysis.

Choosing a policy

Scenario Recommended policy
Standard consumer with retries AUTO + RetryConfig
Handler needs external confirmation before ack MANUAL
No retries, failed messages go straight to DLQ NACK_ON_ERROR
Best-effort processing, loss acceptable ACK_FIRST