Skip to main content
Welcome back. This lesson explains how acknowledgements (acks) work in Google Cloud Pub/Sub, where they fit in the message lifecycle, the different acknowledgement behaviors, and practical code examples using the Python client library. Proper acknowledgement handling is essential for reliability, avoiding duplicate processing, and designing robust subscriber systems.
Acknowledgements let Pub/Sub know whether a delivered message was processed successfully. If Pub/Sub doesn’t receive an ack, it will assume the message failed and will re-deliver it. Design your subscribers to handle at-least-once delivery semantics.

Message lifecycle and where acknowledgements fit

  1. A topic is created and publishers send messages to it.
  2. A subscription is created for the topic; subscribers either pull messages or receive pushed messages from the subscription.
  3. Pub/Sub delivers a message to the subscriber (push or pull).
  4. The subscriber must acknowledge the message to signal successful processing.
  5. If Pub/Sub does not receive an ack before the ack deadline expires, or if the subscriber explicitly nacks the message, the message becomes eligible for redelivery.

Key implementation details

ConceptDescriptionNotes / Example
Ack IDUnique identifier for a delivered message (pull-mode)Required when calling acknowledge() or modifyAckDeadline()
Ack deadlineTime window for ack (default 10s)Per-subscription default; adjustable up to 600s
ModifyAckDeadlineExtend/shorten per-message leaseUse to prevent premature redelivery while processing
Delivery guaranteeDefault is at-least-onceImplement idempotency or dedupe logic to handle duplicates

Acknowledgement types and behaviors

TypeBehaviorWhen to use
Negative acknowledgement (nack)Subscriber explicitly indicates failure; in pull-mode you can call modifyAckDeadline(..., ack_deadline_seconds=0) or use message.nack() where supported. Pub/Sub will immediately make the message available for redelivery.Use when processing definitively failed and you want immediate retry.
Explicit acknowledgement (ack)Subscriber signals successful processing by calling acknowledge() or message.ack(). Pub/Sub will not redeliver the message.Use after processing succeeds.
Modify acknowledgement deadlineExtend or shorten the lease on the message using modifyAckDeadline() to avoid premature redelivery while processing continues.Use for long-running work or when processing time is variable.
Auto-acknowledgementIn push subscriptions, any HTTP 2xx response is treated as an ack. Some client libraries provide options to auto-ack when the message callback returns.Use with caution—auto-ack can cause lost retries if processing fails after ack.
Ack deadline expiryIf no ack or modifyAckDeadline() arrives before expiry, the message becomes eligible for redelivery (common source of duplicates).Avoid by extending the deadline when necessary and by designing idempotent handlers.
A presentation slide titled "Acknowledgment" showing five colored boxes that summarize different message-acknowledgment types: Negative Acknowledgment (Nack), Explicit Acknowledgment, Modify Acknowledgment Deadline, Auto Acknowledgment, and Ack Deadline Expiry. Each box includes short bullet points explaining the behavior (nack/ack calls, modifyAckDeadline usage, auto-ack risks, and redelivery on deadline expiry).

Practical examples (Python client library)

Synchronous pull: explicitly acknowledge messages
from google.cloud import pubsub_v1

subscriber = pubsub_v1.SubscriberClient()
subscription_path = subscriber.subscription_path("my-project", "my-subscription")

# Pull messages
response = subscriber.pull(subscription=subscription_path, max_messages=1)

for received in response.received_messages:
    data = received.message.data
    print("Received:", data)
    ack_id = received.ack_id

    # Acknowledge the message so it won't be redelivered
    subscriber.acknowledge(subscription=subscription_path, ack_ids=[ack_id])
Modify ack deadline (extend lease) for a pulled message
# Extend the ack deadline for this ack_id to 60 seconds
subscriber.modify_ack_deadline(
    subscription=subscription_path,
    ack_ids=[ack_id],
    ack_deadline_seconds=60,
)
Streaming pull with callback: automatic lease management with explicit ack/nack
from google.cloud import pubsub_v1

subscriber = pubsub_v1.SubscriberClient()
subscription_path = subscriber.subscription_path("my-project", "my-subscription")

def callback(message):
    print("Received:", message.data)
    try:
        # Process the message...
        message.ack()  # Explicit acknowledgement
    except Exception:
        # Signal failure; many client libraries support message.nack()
        message.nack()

subscriber.subscribe(subscription_path, callback=callback)

# Keep the main thread alive to allow background threads to process messages
import time
while True:
    time.sleep(60)

Notes on system design and subscriber behavior

  • Subscriber processing times vary. For short, predictable tasks, short ack deadlines may suffice. For long-running tasks, extend the ack deadline per message or increase the subscription default.
  • At-least-once delivery requires idempotency or deduplication. If your processing can’t be made idempotent, use dedupe strategies (unique message IDs, external dedupe stores, etc.).
  • For push endpoints, only return HTTP 2xx when processing actually succeeded. Returning 2xx will stop retries and is treated as an acknowledgement by Pub/Sub.
  • Use modifyAckDeadline() responsibly to avoid holding messages indefinitely and to ensure fair redelivery behavior.
Be careful with auto-ack behavior. If messages are auto-acknowledged before processing completes (or if a push endpoint returns 2xx while processing actually failed), you may lose the ability to retry and risk data loss or missed processing.

Quick exam pointers

  • Pub/Sub uses ack IDs and ack deadlines to manage delivery and retries.
  • The typical exam concept is “at-least-once delivery”: messages may be delivered more than once unless you implement deduplication or enable exactly-once features where supported.

Watch Video