# Auto Ack (/sdks/ruby/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 `QueuePollRequest` passed to the downstream receiver's `poll`. With it enabled, delivery and acknowledgment happen as one atomic step on the broker side, so there's no separate `ack` call and no in-flight "pending" state for the message to sit in.

**Gotchas:** if your consumer crashes or raises after `poll` 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/ruby/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`
* Ruby SDK installed (`gem install kubemq`)

## Code [#code]

```ruby title="main.rb"
require 'kubemq'

address = ENV.fetch('KUBEMQ_ADDRESS', 'localhost:50000')
channel = 'ruby-queues.auto-ack'

begin
  client = KubeMQ::QueuesClient.new(address: address, client_id: 'qstream-autoack-example')
  puts "Connected to #{address}"

  3.times do |i|
    msg = KubeMQ::Queues::QueueMessage.new(channel: channel, metadata: "item-#{i}", body: "data-#{i}")
    client.send_queue_message(msg)
  end
  puts 'Pre-sent 3 messages'

  receiver = client.create_downstream_receiver
  request = KubeMQ::Queues::QueuePollRequest.new(
    channel: channel,
    max_items: 5,
    wait_timeout: 5,
    auto_ack: true
  )
  response = receiver.poll(request)

  puts "Polled #{response.messages.size} messages (auto-acked):"
  response.messages.each { |m| puts "  #{m.metadata}: #{m.body}" }
rescue KubeMQ::Error => e
  puts "KubeMQ error: #{e.message}"
ensure
  receiver&.close
  client&.close
  puts 'Done'
end
```

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

* Setting `auto_ack: true` on `QueuePollRequest` automatically acknowledges messages on receipt.
* No need to call `ack` on individual messages — useful for fire-and-forget processing.
* Review timeouts, channel names, and client IDs before running against shared environments.

## Related [#related]

* [Pattern overview](/learn/queues/getting-started)
* [Ruby SDK Reference](/sdks/ruby/reference)
* [Ack/Reject](/sdks/ruby/how-to/queues/ack-reject)
* [Stream Receive](/sdks/ruby/how-to/queues/stream-receive)
