Fun with Learning Technology
LearnCoursesQuestionsTracksToolsNewsExplorePractice
Fun with Learning Technology

A new problem, explained clearly, every day.

Subscribe
Learn
  • Lessons
  • Topics
  • News
  • Tools
  • Courses
  • Career tracks
  • Everything
Site
  • About
  • Contact
  • Support
  • Privacy
  • Terms
Get the daily one

One email per new problem. No spam.

Request a tutorial

Requests shape what gets made next.

© 2026 Fun with Learning TechnologyRSS
Home›Courses›Google Cloud (GCP)›Pub/Sub — Event Messaging

Data and Analytics

Pub/Sub — Event Messaging

Pub/Sub is a fully managed, global, asynchronous messaging service that decouples senders and receivers of data streams. It acts as the backbone for distributed systems, allowing services to communicate reliably without needing to know about each other's state or existence. You reach for Pub/Sub whenever you need to handle massive event ingestion, build event-driven microservices, or integrate disparate data pipelines that require high availability and horizontal scaling.

The Core Concept of Decoupling

At the heart of Pub/Sub lies the concept of decoupling through topics and subscriptions. A publisher sends messages to a topic, which acts as a logical entry point, without any awareness of who or what will consume that data. Conversely, a subscriber listens to a subscription attached to that topic. This separation is fundamental for engineering resilient systems because it allows the producer and consumer to operate at entirely different speeds and scales. If a backend service experiences a traffic spike or a temporary failure, the publisher can continue to drop messages into the queue without interruption. The subscriber processes them at its own pace when it recovers. This architectural pattern eliminates the tight coupling inherent in direct service-to-service API calls, ensuring that one failing component does not cause a cascading failure throughout your entire infrastructure. Understanding this separation is essential for designing fault-tolerant systems in the cloud.

from google.cloud import pubsub_v1

# Initialize the publisher client
publisher = pubsub_v1.PublisherClient()
topic_path = publisher.topic_path("my-project", "my-topic")

# Publish a message; the publisher does not know who reads this
data = "User login event".encode("utf-8")
future = publisher.publish(topic_path, data, origin="web-app")
print(f"Published message ID: {future.result()}")

Synchronous vs. Asynchronous Consumption

While Pub/Sub is inherently asynchronous in its delivery model, developers must choose between different consumption patterns: pull and push. Pull subscriptions require the client application to actively request messages from the service. This is ideal for scenarios where the subscriber has varying capacity or needs to control the flow of incoming data to prevent overload, acting as a natural buffer. Push subscriptions, on the other hand, behave like a webhook; the service initiates an HTTP POST request to a pre-configured endpoint whenever a message is available. Push is excellent for serverless architectures because it automatically triggers your code upon arrival of events. By understanding these two paradigms, you can effectively match your messaging infrastructure to the scaling profile of your downstream processing logic. Choosing the right method ensures that your system remains responsive and cost-effective under varying workloads.

from google.cloud import pubsub_v1

# A simple pull-based subscriber pattern
subscriber = pubsub_v1.SubscriberClient()
subscription_path = subscriber.subscription_path("my-project", "my-sub")

# This callback processes messages as they arrive in the pull loop
def callback(message):
    print(f"Received: {message.data}")
    message.ack() # Signal successful processing

streaming_pull_future = subscriber.subscribe(subscription_path, callback=callback)
print("Listening for messages...")

Message Reliability and Acknowledgment

Reliability in messaging systems is defined by the guarantee that a message is delivered and processed exactly as intended. Pub/Sub provides this through an acknowledgement mechanism. When a subscriber receives a message, it has a specified amount of time—the ack deadline—to process the event and send an acknowledgment back to the service. If the deadline expires without an acknowledgment, Pub/Sub assumes the processing failed and will redeliver the message. This makes the system robust against transient errors, such as network timeouts or temporary server crashes. Designing your subscriber to be idempotent is critical here, because the exact-once delivery guarantee ensures that messages are delivered at least once, but duplicate deliveries can occur in distributed environments. By tracking message IDs or using unique keys, you ensure that your business logic remains consistent even if a specific task is executed more than once during a retry cycle.

# Extending the ack deadline if processing takes longer
def long_running_callback(message):
    # If the task takes longer than the default 10s, modify the ack deadline
    message.modify_ack_deadline(60)
    # Logic follows...
    message.ack()

Scalability and Global Performance

Pub/Sub is designed to handle global data streams without requiring the developer to manage shards or partitions manually. Unlike many traditional messaging systems that force you to provision storage or compute capacity upfront, Pub/Sub scales horizontally and dynamically. It naturally handles regional traffic bursts because it automatically spreads ingestion across Google's global infrastructure. This geographic distribution is vital for global applications that need to ingest telemetry from users in different continents. By using a single global topic, your publishers connect to the closest regional endpoint, minimizing latency during the ingestion phase. This eliminates the operational overhead of managing clusters or manually redistributing loads as your traffic grows. Understanding that the service manages the underlying partitioning logic allows you to focus on your application logic rather than the plumbing of a distributed messaging platform, which is a major advantage for high-growth services.

# Publishing globally requires no complex regional config
publisher = pubsub_v1.PublisherClient()
# The client handles routing to the nearest regional endpoint
topic_path = "projects/my-project/topics/global-ingestion"
publisher.publish(topic_path, b"Global telemetry data")

Filtering and Delivery Policies

Advanced messaging scenarios often require selective consumption, where specific subscribers only care about a subset of the total event stream. Instead of creating a subscription for every possible message type, Pub/Sub allows you to apply filters based on message attributes. This drastically reduces the compute resources consumed by subscribers, as they only wake up or process events that meet specific criteria. Furthermore, delivery policies, such as retry policies with exponential backoff, allow you to control how the system behaves when a subscriber fails to process an event. You can define exactly how long the service should wait before attempting a redelivery, which prevents 'poison pill' messages from overwhelming your infrastructure. These features represent the maturity of the messaging platform, allowing you to build sophisticated, efficient, and cost-optimized architectures that perform well even under complex business requirements and high-pressure operational environments.

# Creating a subscription with a filter on an attribute
from google.cloud import pubsub_v1

subscriber = pubsub_v1.SubscriberClient()
# Only receive messages where 'env' is 'prod'
filter_str = 'attributes.env = "prod"'

# This is typically configured via the API or command line
# Subscription created with filtering enabled...

Key points

  • Pub/Sub decouples message producers and consumers using topics and subscriptions.
  • The service provides reliable message delivery through an explicit acknowledgment mechanism.
  • Pull subscriptions allow clients to control processing rates while push subscriptions trigger endpoint logic.
  • Every message is subject to an ack deadline which must be managed by the subscriber code.
  • Idempotency is a required design pattern to handle potential duplicate message deliveries.
  • The platform scales horizontally across regions automatically without manual partition management.
  • Filtering allows subscribers to process only relevant subsets of data, improving overall system efficiency.
  • Retry policies with exponential backoff prevent cascading failures during message processing errors.

Common mistakes

  • Mistake: Configuring Pub/Sub to order messages globally by default. Why it's wrong: Pub/Sub is inherently distributed and parallel; global ordering introduces massive latency. Fix: Use ordering keys within specific message attributes to ensure ordering only for a subset of messages.
  • Mistake: Assuming Pub/Sub is a database for long-term storage. Why it's wrong: Pub/Sub is a messaging buffer, not a persistent data store, and it deletes messages after acknowledgement or retention expiration. Fix: Use BigQuery or Cloud Storage for persistent storage of event data.
  • Mistake: Manually polling for new messages in an application. Why it's wrong: This is inefficient and incurs unnecessary API costs. Fix: Use the client library's streaming pull mechanism, which maintains a persistent connection for efficient message delivery.
  • Mistake: Failing to set an appropriate acknowledgement deadline. Why it's wrong: If the deadline is too short, messages are redelivered, leading to duplicate processing. Fix: Monitor processing time and configure the 'ackDeadline' based on the actual time required to process a message.
  • Mistake: Relying on exact-once delivery for every use case without consideration. Why it's wrong: Exact-once delivery adds performance overhead and is not required for idempotent operations. Fix: Use at-least-once delivery with idempotent application logic whenever possible to maximize throughput.

Interview questions

What is the primary function of Google Cloud Pub/Sub and why is it considered a foundational component of modern cloud architecture?

Google Cloud Pub/Sub is a fully managed, scalable, and asynchronous messaging service designed for event-driven systems. Its primary function is to decouple the services that produce events from the services that process them. It is foundational because it allows components to communicate without being directly connected, enabling independent scaling. By acting as a buffer, Pub/Sub ensures that if a downstream service experiences a traffic spike or temporary failure, the messages remain safely queued, preventing data loss and enhancing system resilience.

Can you explain the difference between a Pub/Sub topic and a subscription, and how they interact in the Google Cloud environment?

A topic is a named resource that represents a feed of messages where publishers send their data. A subscription, on the other hand, represents the interest of an application in receiving messages from that specific topic. When a message is published to a topic, Pub/Sub forwards it to every attached subscription. This architecture is vital because it enables fan-out patterns; one message can trigger multiple independent actions, such as saving to BigQuery and updating a dashboard simultaneously, simply by attaching multiple subscriptions.

How does Google Cloud Pub/Sub guarantee message delivery, and what mechanisms are in place to handle processing failures?

Pub/Sub provides 'at-least-once' delivery, meaning every message is guaranteed to reach at least one subscriber. To handle processing failures, Pub/Sub uses 'acknowledgments' (ACKs). When a subscriber receives a message, it has a specified deadline to acknowledge it; if the deadline passes without an ACK, or if the subscriber sends a 'nack', the system automatically redelivers the message. This ensures that even if an instance crashes during processing, the message remains in the queue for another instance to complete the task.

Compare the 'Push' versus 'Pull' delivery methods in Google Cloud Pub/Sub. When would you choose one over the other?

The 'Pull' model requires your subscriber application to actively request messages from the queue, which is ideal for high-throughput batch processing and scenarios where you need fine-grained control over flow rates. The 'Push' model, conversely, has Pub/Sub initiate HTTP requests to a webhook endpoint. Choose 'Push' for serverless architectures like Cloud Functions, where you want to minimize operational overhead and scale automatically based on incoming traffic without maintaining a persistent long-polling connection.

What is a Dead Letter Topic in Google Cloud Pub/Sub, and why is it a critical feature for production-grade pipelines?

A Dead Letter Topic is a secondary topic that acts as a destination for messages that fail to be processed after a configured number of delivery attempts. It is critical for production environments because it prevents 'poison pill' messages—data that is malformed or causes application crashes—from blocking your entire pipeline. By isolating these problematic messages, you can preserve the health of the primary stream while later inspecting the dead-lettered messages to debug and fix the root cause of the processing failures.

How would you implement message ordering in Google Cloud Pub/Sub, and what are the architectural trade-offs involved when enabling this feature?

To implement ordering, you must enable the 'ordering key' property on your publisher. When a publisher includes an ordering key, Pub/Sub guarantees that messages with the same key are delivered in the order they were published to that specific subscription. The trade-off is performance and availability; because messages are strictly ordered, a single blocked message can hold up the rest of the sequence for that key, and you lose some of the massive parallel throughput benefits provided by standard, unordered Pub/Sub deliveries.

All Google Cloud (GCP) interview questions →

Check yourself

1. An application requires that messages published with the same 'user_id' are processed in the order they were published. What must be configured?

  • A.Set the delivery type to synchronous
  • B.Enable ordering keys on the topic and include the user_id
  • C.Use a FIFO-enabled Cloud Function trigger
  • D.Set the acknowledgement deadline to zero
Show answer

B. Enable ordering keys on the topic and include the user_id
Ordering keys are required for message sequencing within a partition. Option 0 is not a standard Pub/Sub configuration, Option 2 is not a built-in feature of Cloud Functions, and Option 3 would cause immediate redelivery, not ordering.

2. A system is experiencing high costs due to repeated message redelivery. What is the most effective way to resolve this?

  • A.Increase the max retention duration of the topic
  • B.Use push subscriptions instead of pull
  • C.Ensure the consumer acknowledges the message before the ack deadline expires
  • D.Reduce the batch size of incoming publishers
Show answer

C. Ensure the consumer acknowledges the message before the ack deadline expires
Redelivery happens if the consumer fails to acknowledge in time. Increasing retention (Option 0) keeps messages longer but does not solve redelivery. Push vs Pull (Option 1) doesn't change the need for acknowledgement, and batch size (Option 3) affects throughput, not the acknowledgement lifecycle.

3. When should you prefer a 'Push' subscription over a 'Pull' subscription?

  • A.When the subscriber is a serverless application like Cloud Run
  • B.When you need to control the exact flow of incoming traffic
  • C.When the subscriber is not accessible via a public HTTPS endpoint
  • D.When you require the highest possible throughput and manual batching
Show answer

A. When the subscriber is a serverless application like Cloud Run
Push subscriptions are ideal for webhooks and serverless endpoints. Pull is better for controlling flow (Option 1) and high throughput (Option 3). Push requires a reachable endpoint (Option 2).

4. What is the primary function of a Dead Letter Topic (DLT) in Pub/Sub?

  • A.To archive all messages for long-term audit purposes
  • B.To hold messages that have failed to be processed after multiple attempts
  • C.To store messages that have exceeded their 7-day retention period
  • D.To act as a load balancer for primary topics
Show answer

B. To hold messages that have failed to be processed after multiple attempts
DLTs are specifically for handling 'poison pills' or failed messages. They are not for archiving (Option 0), standard retention expiry (Option 2), or load balancing (Option 3).

5. If your application logic is idempotent, which delivery configuration provides the best performance?

  • A.Exactly-once delivery
  • B.At-least-once delivery
  • C.Synchronous batch delivery
  • D.Ordered delivery
Show answer

B. At-least-once delivery
At-least-once is the default and most performant. Exactly-once (Option 0) requires extra overhead, Synchronous (Option 2) isn't a performance optimization, and Ordered delivery (Option 3) limits parallelism.

Take the full Google Cloud (GCP) quiz →

← PreviousDataproc — Managed Spark and HadoopNext →Cloud SQL and Cloud Spanner

Google Cloud (GCP)

20 lessons, free to read.

All lessons →

Track your progress

Sign in to mark lessons done, score quizzes and keep notes.

Open in the app