KubeMQ
Client SDKsJavaHow-to guidesQueues

Auto Ack

Automatically acknowledge received KubeMQ Queue messages with the Java SDK to simplify at-most-once processing.

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 autoAckMessages(true) on the QueuesPollRequest passed to receiveQueueMessages. With it enabled, delivery and acknowledgment happen as one atomic step on the broker side, so there's no separate msg.ack() call and no in-flight "pending" state for the message to sit in.

Gotchas: if your consumer crashes or throws after receiveQueueMessages 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. 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, pollMaxMessages and pollWaitTimeoutInSeconds are your only throttles — there's no visibility-timeout window to tune.

Prerequisites

  • KubeMQ server running on localhost:50000
  • Java SDK installed (implementation 'io.kubemq.sdk:kubemq-sdk-Java:3.1.1' (Gradle) or Maven dependency from Getting Started)

Code

AutoAckExample.java
package io.kubemq.example.queuesstream;

import io.kubemq.sdk.queues.*;
import java.util.UUID;

/**
 * AutoAckExample for Queues Stream
 */
public class AutoAckExample {
    private static final String ADDRESS = "localhost:50000";
    private static final String CLIENT_ID = "java-queues-auto-ack-client";
    private static final String CHANNEL = "java-queues.auto-ack";

    public static void main(String[] args) {
        // Create a client connected to the KubeMQ server
        try (QueuesClient client = QueuesClient.builder().address(ADDRESS).clientId(CLIENT_ID).build()) {
            // Create the queue channel
            client.createQueuesChannel(CHANNEL);

            // Send messages to the queue
            for (int i = 1; i <= 3; i++) {
                client.sendQueueMessage(QueueMessage.builder()
                        .channel(CHANNEL).body(("Auto-ack msg " + i).getBytes()).build());
            }

            // Poll with auto-ack enabled (messages acknowledged automatically)
            System.out.println("Polling with autoAckMessages=true...\n");
            QueuesPollResponse response = client.receiveQueueMessages(QueuesPollRequest.builder()
                    .channel(CHANNEL).pollMaxMessages(10).pollWaitTimeoutInSeconds(5)
                    .autoAckMessages(true).build());

            response.getMessages().forEach(msg ->
                System.out.println("  Received (auto-acked): " + new String(msg.getBody())));
            System.out.println("\n" + response.getMessages().size() + " messages auto-acknowledged.");

            // Clean up resources
            client.deleteQueuesChannel(CHANNEL);
        } catch (Exception e) {
            System.err.println("Error: " + e.getMessage());
        }
    }
}

How It Works

  • autoAckMessages(true) in QueuesPollRequest instructs the broker to acknowledge each message immediately upon delivery; no explicit msg.ack() call is needed.
  • This is the lowest-effort receive pattern but provides at-most-once delivery — if the consumer crashes after receiving but before processing, the message is lost.
  • Use autoAckMessages(false) (the default) for at-least-once guarantees where you call msg.ack() only after successful processing.

Was this page helpful?

On this page