Pub/Sub Delivery Guarantees: At-Least-Once vs Exactly-Once

This guide explains the two delivery guarantee options in Google Cloud Pub/Sub: at-least-once and exactly-once delivery, helping you choose the right approach for reliable messaging.

When building data pipelines and event-driven architectures on Google Cloud, understanding Pub/Sub delivery guarantees is essential for ensuring message reliability. This topic appears frequently on the Professional Data Engineer certification exam because choosing the right delivery semantic directly impacts data integrity, system complexity, and operational costs. The exam tests your ability to select appropriate messaging patterns based on business requirements and understand the tradeoffs between different delivery models.

Pub/Sub delivery guarantees define how the messaging system ensures that published messages reach their intended subscribers. These guarantees determine whether messages might be delivered multiple times, whether any messages could be lost, and what complexity your application needs to handle. Getting this right is fundamental to building reliable data systems in GCP.

What Are Pub/Sub Delivery Guarantees

Delivery guarantees, also called delivery semantics, specify the contract between the messaging system and your application about how many times each message will be delivered. Google Cloud Pub/Sub offers two distinct delivery guarantee models that balance reliability, performance, and application complexity.

The first model is at-least-once delivery, which guarantees that every published message will be delivered to subscribers at least one time. This means no messages are lost, but the same message might arrive multiple times. This happens because Pub/Sub will retry message delivery until it receives an acknowledgment, and network issues or processing delays can cause duplicate deliveries.

The second model is exactly-once delivery, which provides a stronger guarantee: every message is delivered exactly one time. No messages are lost, and no duplicates are created. This semantic removes the burden of deduplication from your application but requires additional infrastructure coordination within Pub/Sub.

At-least-once delivery is the default behavior in Pub/Sub. Exactly-once delivery is an optional feature that must be explicitly enabled when you create a subscription. This design reflects that at-least-once delivery meets the needs of many workloads while keeping the system simpler and more cost-effective.

How Pub/Sub Delivery Guarantees Work

Understanding how these delivery guarantees function requires looking at the message acknowledgment process. When a subscriber receives a message from a Pub/Sub subscription, it must send an acknowledgment (ack) back to Pub/Sub to confirm successful processing. If Pub/Sub does not receive this acknowledgment within a configurable deadline, it assumes the message was not processed and makes it available for redelivery.

With at-least-once delivery, the following sequence occurs. A publisher sends a message to a topic, and Pub/Sub stores the message durably. When a subscriber pulls or receives the message, Pub/Sub tracks that the message has been delivered but keeps it in the subscription until acknowledgment. If the subscriber sends an ack, Pub/Sub removes the message from the subscription. If the ack deadline expires without receiving an acknowledgment, Pub/Sub redelivers the message.

This retry mechanism ensures no messages are lost, even if subscribers crash or network connections fail. However, it creates scenarios where duplicates occur. Consider a payment processor that receives a transaction message, processes the payment successfully, but experiences a network failure before sending the acknowledgment. Pub/Sub will redeliver the message, potentially causing a duplicate charge unless the application implements deduplication logic.

With exactly-once delivery, Google Cloud Pub/Sub adds additional coordination to prevent duplicates. The system assigns each message a unique identifier and tracks which messages have been successfully processed by each subscription. Even if a message is redelivered due to acknowledgment failures, Pub/Sub ensures the subscriber only processes it once. The service handles the complexity of distributed deduplication internally, using persistent state and coordination across the messaging infrastructure.

When exactly-once delivery is enabled, Pub/Sub guarantees that each message will be delivered to a subscription exactly one time, regardless of retries, acknowledgment failures, or other transient issues. This works transparently for your application, though it requires additional processing overhead within the Pub/Sub service itself.

Key Characteristics of Each Delivery Guarantee

At-least-once delivery offers several important characteristics. It provides the highest throughput and lowest latency because the system doesn't need to coordinate deduplication state. The implementation is simpler within Pub/Sub, which translates to more predictable performance. However, your application code must handle duplicate messages gracefully. This typically means implementing idempotent processing, where processing the same message multiple times produces the same result as processing it once.

For a streaming analytics platform that counts user clicks, duplicate messages could inflate metrics. The application might need to deduplicate based on click IDs before aggregating counts. This adds complexity to your data pipeline code but gives you flexibility in how deduplication is implemented.

Exactly-once delivery provides different tradeoffs. The primary benefit is eliminating duplicates, which simplifies application logic considerably. You don't need to implement deduplication, check for duplicate IDs, or ensure idempotent processing. The message you receive will be processed exactly once, guaranteed by the platform.

The tradeoffs include slightly higher latency due to the coordination required for deduplication tracking. There's also a cost consideration, as exactly-once delivery requires additional infrastructure resources. Additionally, exactly-once delivery is only available for subscriptions that meet certain requirements. For example, it works with both pull and push subscriptions, but your application must still handle acknowledgments correctly.

Why Pub/Sub Delivery Guarantees Matter

Choosing the appropriate delivery guarantee directly impacts data accuracy, system complexity, and operational costs. Different workloads have different tolerance for duplicates and different requirements for processing guarantees.

Consider a hospital network processing lab results. When test results are published to a Pub/Sub topic and delivered to multiple systems (electronic health records, notification services, billing systems), exactly-once delivery ensures that no result is recorded twice or triggers duplicate notifications. A duplicate lab result appearing in patient records could cause confusion or lead to incorrect treatment decisions. The cost and latency overhead of exactly-once delivery is justified by the critical nature of healthcare data integrity.

In contrast, a solar farm monitoring system collecting sensor readings every few seconds from thousands of panels might use at-least-once delivery. If a temperature reading is occasionally duplicated, the time series database can handle it through standard deduplication based on timestamps and sensor IDs. The high volume of messages makes the throughput advantage of at-least-once delivery valuable, and the application already has natural deduplication keys built into the data.

A mobile game studio processing in-game purchases faces a critical scenario. If a player buys virtual currency, exactly-once delivery ensures they're charged once and receive the currency once. Duplicate processing could either overcharge the player or grant duplicate currency, both of which damage player trust. The financial implications and regulatory requirements around payment processing make exactly-once delivery essential.

For a climate modeling research system that processes simulation outputs, at-least-once delivery with application-level deduplication might be preferable. The processing jobs are idempotent by design, and the research team wants maximum control over how duplicate data is detected and handled. They prefer lower latency and can implement sophisticated deduplication logic specific to their simulation parameters.

When to Use Each Delivery Guarantee

Select at-least-once delivery when your application can implement idempotent processing or when your use case naturally handles duplicates. This includes scenarios where downstream systems deduplicate data (like databases with unique constraints), where approximate results are acceptable (like monitoring and metrics), or where you want maximum throughput and minimum latency.

A freight company tracking shipment events might use at-least-once delivery because their tracking database uses shipment IDs and timestamps as a compound key. Duplicate events are automatically ignored by the database constraint. The application benefits from the simplicity and performance of at-least-once delivery while still achieving accurate tracking.

Use exactly-once delivery when duplicate processing could cause incorrect behavior, financial loss, or data corruption. This includes financial transactions, inventory updates, account modifications, or any workflow where processing a message twice produces different results than processing it once.

A telehealth platform processing prescription orders needs exactly-once delivery. When a doctor submits a prescription through the app, it's published to Pub/Sub for processing by the pharmacy system, insurance verification service, and patient notification service. Duplicate processing could result in duplicate prescriptions being sent to the pharmacy, potentially causing medication errors. Exactly-once delivery eliminates this risk without requiring complex deduplication logic in multiple downstream systems.

Avoid exactly-once delivery when you need maximum throughput for high-volume streams where duplicates are acceptable. The coordination overhead, while small, can become significant at very high message rates. Also consider that exactly-once delivery adds cost, so if you can achieve the same correctness guarantees with application-level deduplication at lower cost, that might be preferable.

Implementation Considerations for Pub/Sub Delivery Guarantees

To use at-least-once delivery, simply create a standard Pub/Sub subscription. This is the default behavior and requires no special configuration. Your application code should implement logic to handle duplicate messages. Common approaches include maintaining a cache of recently processed message IDs, using database constraints to prevent duplicate inserts, or designing processing logic to be naturally idempotent.

Here's an example of creating a standard subscription using gcloud:

gcloud pubsub subscriptions create my-subscription \
  --topic=my-topic \
  --ack-deadline=60

This creates a subscription with at-least-once delivery semantics. Your subscriber code needs to handle potential duplicates:

from google.cloud import pubsub_v1

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

processed_ids = set()

def callback(message):
    message_id = message.attributes.get('unique_id')
    
    if message_id in processed_ids:
        print(f"Skipping duplicate message: {message_id}")
        message.ack()
        return
    
    # Process the message
    process_data(message.data)
    processed_ids.add(message_id)
    message.ack()

streaming_pull_future = subscriber.subscribe(subscription_path, callback=callback)
streaming_pull_future.result()

To enable exactly-once delivery, you must specify this when creating the subscription. The subscription must be in a region that supports exactly-once delivery, and you need to handle acknowledgments properly in your code:

gcloud pubsub subscriptions create my-exactly-once-subscription \
  --topic=my-topic \
  --enable-exactly-once-delivery \
  --ack-deadline=60

With exactly-once delivery enabled, your subscriber code is simpler because you don't need deduplication logic:

from google.cloud import pubsub_v1

subscriber = pubsub_v1.SubscriberClient()
subscription_path = subscriber.subscription_path('my-project', 'my-exactly-once-subscription')

def callback(message):
    # Process the message without worrying about duplicates
    process_data(message.data)
    message.ack()

streaming_pull_future = subscriber.subscribe(subscription_path, callback=callback)
streaming_pull_future.result()

Important considerations include acknowledgment deadlines. Set your ack deadline longer than your maximum expected processing time to avoid unnecessary redeliveries. With exactly-once delivery, failed acknowledgments don't cause duplicate processing, but they do cause the message to be redelivered, which adds latency.

For both delivery semantics, implement proper error handling. If processing fails, don't acknowledge the message. Let the ack deadline expire so Pub/Sub will redeliver it. This ensures messages aren't lost even when processing errors occur.

Be aware of quota and cost implications. Exactly-once delivery incurs additional charges beyond standard message delivery costs. Review the GCP pricing documentation to understand the cost difference for your expected message volume.

Integration with Other Google Cloud Services

Pub/Sub delivery guarantees interact meaningfully with other GCP services in data processing pipelines. Understanding these integrations helps you design reliable end-to-end architectures.

When using Dataflow with Pub/Sub, you can use Pub/Sub delivery guarantees as part of your stream processing pipeline. A Dataflow pipeline consuming from a Pub/Sub subscription with at-least-once delivery should implement deduplication windows or use stateful processing to handle duplicates. Dataflow provides built-in support for windowing and state management that makes this practical. With exactly-once delivery, your Dataflow pipeline can simplify its logic because incoming messages are already deduplicated.

For integration with BigQuery, consider a subscription box service that publishes customer events to Pub/Sub and uses a Dataflow pipeline to load them into BigQuery for analysis. With at-least-once delivery, the pipeline needs to deduplicate based on event IDs before inserting into BigQuery, or rely on BigQuery merge operations to handle duplicates. With exactly-once delivery, the pipeline can directly insert events knowing each will arrive once.

Cloud Functions triggered by Pub/Sub messages inherit the delivery guarantee of the subscription. A function processing order confirmations from an ecommerce platform will receive each message according to the subscription's delivery semantic. If the function sends confirmation emails, exactly-once delivery ensures customers receive exactly one email per order, while at-least-once delivery requires the function to track sent emails to avoid duplicates.

When writing to Cloud Storage, consider that duplicate messages with at-least-once delivery could result in duplicate files or overwritten data. A podcast network storing episode analytics might use message attributes as part of the Cloud Storage object name to naturally deduplicate, or use exactly-once delivery to avoid the issue entirely.

Integration with Cloud SQL or other databases often involves transactional logic. A trading platform processing stock transactions might use exactly-once delivery to ensure each trade is recorded once, or implement database transactions with duplicate checking for at-least-once delivery. The choice depends on performance requirements and where you want the deduplication logic to reside.

Understanding the Right Choice for Your Workload

Pub/Sub delivery guarantees give you control over the reliability and complexity tradeoffs in your messaging architecture. At-least-once delivery provides excellent performance and simplicity while requiring your application to handle duplicates. Exactly-once delivery eliminates duplicates at the platform level, simplifying application code at the cost of slightly higher latency and additional charges.

The choice between these delivery semantics depends on your specific requirements around data integrity, processing complexity, performance needs, and cost constraints. Many workloads thrive with at-least-once delivery and straightforward deduplication logic. Critical workflows involving financial transactions, healthcare data, or other scenarios where duplicates cause serious problems benefit from exactly-once delivery.

Understanding these concepts is essential for the Professional Data Engineer exam and for building production data systems on Google Cloud. The exam tests your ability to choose appropriate delivery guarantees based on requirements, understand the implementation differences, and recognize when the additional cost and complexity of exactly-once delivery is justified. For comprehensive exam preparation covering Pub/Sub delivery guarantees and other essential GCP data engineering concepts, check out the Professional Data Engineer course.