# Auto Ack (/sdks/elixir/how-to/queues/auto-ack)



## Overview [#overview]

**Auto-ack** is the fire-and-forget receive mode for queues: the broker marks a message as consumed the instant it hands it to your client, instead of waiting for your code to settle it. Reach for it when the work is idempotent, low-value, or cheap to lose — a metrics ping, a cache warm, a best-effort notification — and you'd rather not carry the bookkeeping of explicit acknowledgment for every message.

It works by setting `auto_ack: true` on the options passed to `KubeMQ.Client.poll_queue/2`. With it enabled, delivery and acknowledgment happen as one atomic step on the broker side, so there's no separate `PollResponse.ack_all/1` call and no in-flight "pending" state for the message to sit in.

**Gotchas:** if your consumer crashes after `poll_queue/2` returns but before it finishes processing, that message is gone for good — auto-ack gives you no chance to nack or requeue it, unlike [Ack & Reject](/sdks/elixir/how-to/queues/ack-reject). It's an at-most-once model, so never use it for messages where losing one silently would matter. And because acknowledgment happens on delivery, `max_items` and `wait_timeout` are your only throttles — there's no visibility-timeout window to tune.

## Prerequisites [#prerequisites]

* KubeMQ server running on `localhost:50000`
* Elixir SDK installed (`{:kubemq, "~> 1.0"}` in mix.exs)

## Code [#code]

```elixir title="main.exs"
channel = "elixir-queues.auto-ack"
{:ok, client} = KubeMQ.Client.start_link(address: "localhost:50000", client_id: "elixir-qs-autoack")

for i <- 1..3 do
  {:ok, _} = KubeMQ.Client.send_queue_message(client,
    KubeMQ.QueueMessage.new(channel: channel, body: "Auto-ack msg #{i}"))
end

IO.puts("Sent 3 messages")

case KubeMQ.Client.poll_queue(client,
       channel: channel,
       max_items: 10,
       wait_timeout: 5_000,
       auto_ack: true
     ) do
  {:ok, poll} ->
    IO.puts("Received #{length(poll.messages)} messages (auto-acked)")

    Enum.each(poll.messages, fn msg ->
      IO.puts("  #{msg.body}")
    end)

    IO.puts("No manual ack needed — server handled it")

  {:error, err} ->
    IO.puts("Poll failed: #{err.message}")
end

case KubeMQ.Client.receive_queue_messages(client, channel,
       max_messages: 10,
       wait_timeout: 2_000
     ) do
  {:ok, result} ->
    IO.puts("Remaining messages: #{result.messages_received}")

  {:error, _} ->
    IO.puts("Queue empty (confirmed)")
end

KubeMQ.Client.close(client)
```

## How It Works [#how-it-works]

* `auto_ack: true` tells the server to acknowledge messages immediately when delivered
* No manual `PollResponse.ack_all/1` call is needed
* Best for scenarios where message processing is guaranteed to succeed

## Related [#related]

* [Ack/Reject](/sdks/elixir/how-to/queues/ack-reject)
* [Stream Receive](/sdks/elixir/how-to/queues/stream-receive)
