> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Cloud PubSub Acknowledgement

> Explains Google Cloud Pub/Sub acknowledgement mechanisms, deadlines, ack/nack behaviors, and Python examples for reliable at least once message processing

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.

<Callout icon="lightbulb" color="#1CB2FE">
  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.
</Callout>

## 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

| Concept            | Description                                           | Notes / Example                                                |
| ------------------ | ----------------------------------------------------- | -------------------------------------------------------------- |
| Ack ID             | Unique identifier for a delivered message (pull-mode) | Required when calling `acknowledge()` or `modifyAckDeadline()` |
| Ack deadline       | Time window for ack (default 10s)                     | Per-subscription default; adjustable up to 600s                |
| ModifyAckDeadline  | Extend/shorten per-message lease                      | Use to prevent premature redelivery while processing           |
| Delivery guarantee | Default is at-least-once                              | Implement idempotency or dedupe logic to handle duplicates     |

## Acknowledgement types and behaviors

| Type                            | Behavior                                                                                                                                                                                                                         | When 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 deadline | Extend 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-acknowledgement            | In 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 expiry             | If 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. |

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/cOLw078gFDjw8fZP/images/Google-Cloud-Professional-Data-Engineer-Certification/Data-Ingestion-Options/Cloud-PubSub-Acknowledgement/acknowledgment-types-five-boxes.jpg?fit=max&auto=format&n=cOLw078gFDjw8fZP&q=85&s=5f7f2396de6757e476106e73fc2f2da2" alt="A presentation slide titled &#x22;Acknowledgment&#x22; 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)." width="1920" height="1080" data-path="images/Google-Cloud-Professional-Data-Engineer-Certification/Data-Ingestion-Options/Cloud-PubSub-Acknowledgement/acknowledgment-types-five-boxes.jpg" />
</Frame>

## Practical examples (Python client library)

Synchronous pull: explicitly acknowledge messages

```python theme={null}
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

```python theme={null}
# 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

```python theme={null}
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.

<Callout icon="warning" color="#FF6B6B">
  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.
</Callout>

## 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.

## Links and references

* [Pub/Sub documentation - Subscriber best practices](https://cloud.google.com/pubsub/docs/subscriber)
* [Pub/Sub Python client library](https://googleapis.dev/python/pubsub/latest/index.html)

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/google-cloud-professional-data-engineer-certification/module/55ff91cf-92cb-4d54-932a-f95075fd3f68/lesson/fa7afdf0-da07-4adf-87a3-2ba02ce25ce3" />
</CardGroup>
