Pub/Sub in Google Cloud: The Message Highway Connecting Every Part of Your System
A thorough, plain-English guide to Google's managed messaging service, covering topics and subscriptions, pull, push, and direct-to-storage delivery, acknowledgments and retries, ordering, exactly-once delivery, dead letter topics, schemas, security, monitoring, cost, and the design habits that keep event-driven systems calm.
Imagine a large city post office. Thousands of people drop letters into a slot all day long, and they never need to know who will read them or when. Behind the counter, the post office sorts every letter into boxes, one box for each interested reader. Some readers collect their mail when they are ready. Others have it delivered to their door. If a reader is on holiday, the letters simply wait safely in the box. If a letter cannot be delivered after many tries, it is set aside for a clerk to inspect. Nobody who writes letters has to wait for readers, and no reader has to chase writers. Pub/Sub is that post office for software. One part of a system publishes messages, other parts receive them, and Google makes sure messages are stored safely, delivered reliably, and scaled to whatever volume arrives. This guide explains how the post office is organized, why each feature exists, and how to use it wisely.
1What Pub/Sub Really Is
Before diving into details, we need a clear picture of the problem messaging solves and what Pub/Sub delivers.
The problem of tightly connected systems
When one program needs to tell another program something, the simplest approach is a direct call: program A contacts program B and waits for an answer. This works for small systems, but it becomes fragile as systems grow. If program B is slow, program A is slow. If program B is down, program A fails. If ten other programs also want to know the same news, program A must contact all ten, and adding an eleventh means changing program A. Everything becomes tangled together, and a problem in one place spreads to many.
Messaging breaks these chains. Instead of calling each other directly, programs hand messages to an intermediary. The sender does not know or care who reads the message, and readers do not need the sender to be available at the moment they read. This idea is called decoupling, and it is one of the most important ideas in building large, reliable systems.
What the service gives you
Pub/Sub is a fully managed, global messaging and event streaming service on Google Cloud. Publishers send messages to a named channel called a topic. Subscribers receive those messages through subscriptions attached to the topic. The service stores messages durably, delivers them at least once by default, scales automatically to very high volumes, and works across regions without you running any servers or brokers. It is used for event-driven architectures, streaming data pipelines, asynchronous work queues, log and telemetry collection, and integration between systems.
Think of a radio station. The station broadcasts to a frequency without knowing who is listening. Any radio tuned to that frequency can receive the broadcast, and a radio that was switched off simply misses nothing important if the station also records its shows for later. Pub/Sub is a radio station that also records, so listeners can catch up.
An older, lower-cost variant of the service called Pub/Sub Lite existed for a time, but it has been retired, with reports placing its shutdown on June 30, 2026. If you meet older material that mentions it, treat that guidance as obsolete and confirm current status in the official documentation.
2Core Concepts and Vocabulary
Every messaging system has its own words. These are the ones you will hear in nearly every Pub/Sub conversation.
Message
The unit of data sent through the service: a payload plus optional attributes and a few system-assigned details.
Topic
A named channel that publishers send messages to. A topic holds no readers itself, it simply receives and stores.
Subscription
A named attachment to a topic that represents one stream of messages for one group of readers.
Publisher
Any program that sends messages to a topic. It does not know who will read them.
Subscriber
Any program that receives messages through a subscription and processes them.
Acknowledgment
A signal from the subscriber saying “I processed this message.” Until it arrives, the service assumes delivery may have failed.
Ack Deadline
The time the service waits for an acknowledgment before sending the message again.
Attributes
Small key and value labels attached to a message, useful for routing, filtering, and describing the payload.
Ordering Key
A label that groups messages which must be delivered in the order they were published.
Dead Letter Topic
A holding topic for messages that repeatedly fail delivery, so they can be inspected instead of retried forever.
How the words fit together
A publisher sends a message to a topic. The topic delivers a copy of that message to every subscription attached to it. Each subscription keeps its own record of which messages have been delivered and acknowledged. Subscribers read from a subscription, process each message, and acknowledge it. If several subscribers share one subscription, they split the messages among them, which spreads the work. If several different subscriptions are attached to the same topic, each gets every message, which spreads the news.
Think of a newspaper. The topic is the publication. Each subscription is a household’s subscription, and each household gets its own copy of every edition. Inside one household, family members share that copy and each reads different sections, which is like several subscribers sharing one subscription.
Subscribers read from subscriptions, not directly from topics. If a topic has no subscriptions when a message is published, that message is not delivered to anyone, because there was nobody attached to receive it. Create subscriptions before you start publishing.
3Architecture and Message Flow
Now let us follow a message from the moment it is published to the moment it is acknowledged.
The shape of the system
Pub/Sub is a global service with a shared control plane and regional data handling. Publishers connect to a nearby endpoint, and the service stores each message durably in more than one zone before confirming to the publisher that the message was accepted. That confirmation is important: once a publisher receives it, the message is safe even if a data center fails a moment later. You do not manage brokers, partitions, or capacity. The service scales on its own as publish and subscribe traffic grows.
flowchart LR
P1["Publisher A"] --> T["Topic"]
P2["Publisher B"] --> T
T --> S1["Subscription 1"]
T --> S2["Subscription 2"]
T --> S3["Subscription 3"]
S1 --> R1["Order service workers"]
S2 --> R2["Analytics pipeline"]
S3 --> R3["Audit archive"]
The life of a message
Publish
A publisher sends a message to a topic. The service stores it durably and confirms success to the publisher.
Fan out
The message becomes available in every subscription attached to the topic, each tracking it separately.
Deliver
The service delivers the message to a subscriber, by pull or by push, depending on the subscription type.
Process
The subscriber does its work, such as updating a database or calling another service.
Acknowledge
The subscriber tells the service the work is done. The message is then marked complete for that subscription.
Retry or retire
If no acknowledgment arrives in time, the message is delivered again. If it keeps failing, it can be sent to a dead letter topic.
sequenceDiagram
participant P as Publisher
participant T as Topic
participant S as Subscription
participant W as Subscriber
P->>T: Publish message
T-->>P: Confirm stored
T->>S: Make available
S->>W: Deliver message
W->>W: Process
W-->>S: Acknowledge
S->>S: Mark complete
A courier collects a parcel and gives the sender a receipt, which is the publish confirmation. The parcel then travels to the recipient, who signs for it, which is the acknowledgment. If nobody signs within a set time, the courier tries again.
The publish confirmation only means the message was stored. It does not mean any subscriber has processed it. Never treat a successful publish as proof that downstream work is done.
4Subscription Types: Pull, Push, and Direct-to-Storage
The type of subscription decides how messages reach your code and who is in control of the pace.
Pull subscriptions
With a pull subscription, your subscriber asks the service for messages when it is ready. The subscriber controls the pace: it can take a few messages, process them, and ask for more. This makes pull ideal for work that varies in speed, for batch processing, and for any case where you want to apply backpressure, meaning slowing down when the consumer is overwhelmed. The popular way to pull is a streaming connection that keeps messages flowing with low delay, while a simpler request-based pull is available when you want direct control.
Push subscriptions
With a push subscription, the service sends each message to an HTTPS address you provide, as a web request. Your endpoint processes the message and replies with a success code to acknowledge it. Push is convenient because your code needs no special client library and can live behind a normal web address, which suits serverless services and webhooks. The trade-off is that the service sets the pace, so your endpoint must handle the incoming rate, and it responds to failures with retries and backoff.
Direct-to-storage subscriptions
Some subscriptions deliver messages straight into a destination without any code of your own. A BigQuery subscription writes each message as a row in a table in the data warehouse. A Cloud Storage subscription writes messages into files in a bucket. A Bigtable subscription writes into a wide-column table. These remove the need to build and run a pipeline just to land data, and they are excellent for ingestion and archiving.
Pull
Subscriber fetches messages at its own pace. Best for controlled parallelism, batch work, and backpressure.
Push
Service sends messages to an HTTPS endpoint. Best for serverless handlers and webhooks at low to moderate volume.
BigQuery
Messages are written directly as table rows for analytics, with no pipeline code to run.
Cloud Storage
Messages are batched into files in a bucket, ideal for archiving and later batch processing.
Bigtable
Messages are written into a Bigtable table for low-latency serving of event-derived data.
Choosing between them
| Situation | Better choice | Why |
|---|---|---|
| High throughput worker fleet you control | Pull | You decide how many messages to take and when |
| Serverless function triggered by events | Push | No client library needed, scales with requests |
| Land events in the data warehouse | BigQuery subscription | No code, schema-aware writes |
| Archive raw events cheaply | Cloud Storage subscription | Batched files, simple retention |
| Messages that must stay in order per key | Pull | Better suited to ordered processing |
| Consumer that cannot import a client library | Push | Plain HTTPS is enough |
flowchart TD
T["Topic"] --> A["Pull subscription"]
T --> B["Push subscription"]
T --> C["BigQuery subscription"]
T --> D["Cloud Storage subscription"]
A --> A1["Worker asks for messages"]
B --> B1["Service posts to HTTPS endpoint"]
C --> C1["Rows in warehouse table"]
D --> D1["Files in bucket"]
Pull is like going to the mailbox when you have time. Push is like having the mail carried to your door and handed over. A direct-to-storage subscription is like having the mail automatically filed into your cabinet without you touching it.
Available subscription types, destinations, and their settings are expanded over time. Confirm the current list and each type’s limits in the official documentation before designing around one.
5Delivery Guarantees: Acknowledgments, Retries, and Duplicates
The most important behavior to understand is what the service promises about delivery, and what it deliberately does not.
At-least-once delivery
By default, Pub/Sub guarantees that every message is delivered at least once. That means a message will not be silently lost, but it may be delivered more than once. Duplicates can happen for several reasons: an acknowledgment was lost on the network, a subscriber took too long and the deadline expired, or the service retried to be safe. This is a deliberate trade-off. It is much easier to make a system that never loses messages and sometimes repeats them than one that never repeats and sometimes loses.
The acknowledgment deadline
When a message is delivered, the service starts a timer called the acknowledgment deadline. If the subscriber acknowledges before the timer ends, the message is done. If not, the service assumes the delivery failed and sends the message again, possibly to a different subscriber. For slow work, client libraries automatically extend the deadline while the message is being processed, which is called lease management. For very long tasks, you may need to tune this or move the heavy work out of the message handler.
Message delivered
The service hands the message to a subscriber and starts the deadline timer.
Subscriber works
The client library may extend the deadline while processing continues.
Ack or nack
The subscriber acknowledges on success, or sends a negative acknowledgment to ask for quick redelivery.
Timeout leads to redelivery
If neither arrives before the deadline, the message is delivered again.
Retry policy
When a message is redelivered, the subscription can use a retry policy that waits between attempts. With exponential backoff, the delay grows with each failed attempt, between a minimum and a maximum you set. This prevents a struggling downstream service from being hammered with immediate retries. Without a retry policy, the service redelivers as soon as it can, which can make an overload worse.
Idempotency: your safety net
Since duplicates are possible, the subscriber should produce the same final result whether it processes a message once or several times. This property is called idempotency. A handler that adds a row, charges a card, or sends an email is not naturally idempotent, and must be made so. The usual approach is to use a unique identifier carried by the message, or a business key, and record in a durable store that it was already handled. If the same identifier appears again, the handler skips the work and acknowledges.
flowchart TD
M["Message arrives"] --> C{"Already processed this id?"}
C -->|"Yes"| A1["Acknowledge and skip"]
C -->|"No"| W["Do the work"]
W --> OK{"Succeeded?"}
OK -->|"Yes"| R["Record id and acknowledge"]
OK -->|"Temporary failure"| N["Negative acknowledge for retry"]
OK -->|"Permanent failure"| D["Let it reach dead letter handling"]
Imagine a pharmacy that checks the prescription number before filling it. If the same prescription arrives twice because of a paperwork mix-up, the pharmacist sees it was already filled and does not hand out a second batch of medicine. The prescription number is the idempotency key.
Designing a handler that breaks when it sees the same message twice is the most common cause of subtle data errors in event-driven systems. Always assume repeats can happen, unless you have enabled and understand stronger guarantees.
6Dead Letter Topics and Failure Handling
Some messages can never succeed. A good design decides in advance where such messages go.
The poison message problem
A poison message is one that always fails when processed, for example because its data is malformed or because it triggers a bug. Without protection, the service keeps redelivering it, the subscriber keeps failing, and this wastes capacity and can block other messages, especially when ordering is used. Worse, the failure can hide among normal noise, so nobody notices real problems.
Dead letter topics
A dead letter topic is a separate topic where the subscription forwards messages that have failed too many times. You set the maximum number of delivery attempts. After that number is reached, the message is moved to the dead letter topic and removed from the main flow. A person or a repair process can then inspect it, fix the cause, and resubmit it if appropriate. The dead letter topic needs its own subscription so the forwarded messages are actually retained, and the service needs permission to publish to it.
flowchart LR
TP["Main topic"] --> SUB["Main subscription"]
SUB --> WK["Subscriber"]
WK -->|"Failure"| SUB
SUB -->|"Attempts exceed limit"| DLT["Dead letter topic"]
DLT --> DLS["Dead letter subscription"]
DLS --> REV["Review and repair process"]
REV -->|"Fixed message"| TP
A post office keeps a special shelf for undeliverable letters. After several failed delivery attempts, a letter goes on that shelf where a clerk can read it, find the right address, and send it again. The main delivery routes keep running smoothly in the meantime.
Designing the failure path
Choose a sensible attempt limit
Pick enough attempts to survive temporary glitches, but not so many that a poison message loops for hours.
Use backoff between attempts
Add a retry delay so transient downstream problems have time to clear.
Give the dead letter topic a subscription
Without one, forwarded messages are not retained and are effectively lost.
Alert on its size
Messages piling up in the dead letter topic mean real work is failing and needs attention.
Have a repair routine
Decide who reviews dead messages, how they are fixed, and how they are replayed safely.
The service’s own identity must be allowed to publish to the dead letter topic and to acknowledge messages on the source subscription. A dead letter setup that lacks these permissions silently fails to move messages.
Distinguish temporary errors from permanent ones in your handler. Retrying a temporary failure is wise. Retrying a permanently malformed message is pointless. Let permanent failures reach the dead letter path quickly.
7Ordering and Exactly-Once Delivery
Two optional features give stronger guarantees. Each comes with trade-offs you should understand before enabling it.
Message ordering
By default, messages may arrive in a different order from the one in which they were published, because the service spreads work across many machines for scale. When order matters, such as a sequence of updates to the same customer record, you can attach an ordering key to each message. Messages that share an ordering key are delivered in the order they were published, while messages with different keys are processed independently and in parallel. Ordering must also be enabled on the subscription, and messages must be acknowledged in order.
flowchart LR
P["Publisher"] -->|"key A: update 1"| T["Topic with ordering"]
P -->|"key A: update 2"| T
P -->|"key B: update 1"| T
T --> S["Subscription with ordering enabled"]
S --> W1["Worker handling key A in order"]
S --> W2["Worker handling key B in order"]
Costs of ordering
Advantages
- Preserves the sequence of related events
- Different keys still process in parallel
- Removes the need for custom resequencing logic
- Simplifies state updates that must apply in order
Disadvantages / Trade-offs
- Throughput per key is limited, so use many distinct keys
- A failing message can block later messages for the same key
- Push delivery suits ordering poorly, pull is generally preferred
- Requires careful acknowledgment handling in order
Think of supermarket checkout lanes. Each customer’s items must be scanned in sequence within their own lane, but many lanes operate at the same time. An ordering key is the lane number: strict order inside a lane, full speed across lanes.
Exactly-once delivery
For workloads where duplicates cause real harm, a subscription can enable exactly-once delivery. When enabled, the service gives stronger guarantees: once a message has been successfully acknowledged, it will not be redelivered, and acknowledgment results are reported accurately to the client so the subscriber knows whether the acknowledgment truly succeeded. It relies on cooperation with the client libraries and has constraints, such as applying to pull style subscriptions and to messages handled within a region, and it can slightly raise latency. It also does not remove the need to think about what your own handler does with side effects outside the service.
| Feature | What it adds | What it costs |
|---|---|---|
| Default at-least-once | Highest simplicity and throughput | Handlers must tolerate duplicates |
| Ordering keys | Sequence within a key | Lower throughput per key, blocking on failures |
| Exactly-once delivery | No redelivery after confirmed acknowledgment | Some extra latency and usage constraints |
Even with exactly-once delivery, your handler may fail halfway and repeat side effects in other systems. Keep designing handlers to be safe to repeat, and treat stronger delivery guarantees as an extra safeguard, not a replacement.
8Schemas, Filtering, and Message Transforms
As more teams share topics, agreeing on the shape of messages and routing the right ones to the right readers becomes essential.
Schemas
A schema describes the structure a message must follow, such as which fields exist and what types they have. Attaching a schema to a topic makes the service reject messages that do not match, which stops malformed data at the door instead of letting it poison every subscriber. Schemas also act as a contract between publishers and subscribers, so teams can evolve independently while still understanding each other. Plan evolution from the beginning: prefer optional fields, avoid breaking changes, and version schemas deliberately.
Message filtering
A subscription can carry a filter that looks at message attributes and delivers only matching messages. Messages that do not match are simply not delivered to that subscription and are treated as acknowledged for it. This lets one topic serve many different consumers, each interested in a slice, without creating a topic for every combination. Because the filter works on attributes, publishers should set meaningful attributes such as event type or region, so consumers can select precisely what they need.
Route by event type
One topic carries order events, and each subscription filters to created, shipped, or cancelled.
Route by region
Regional services receive only messages tagged for their own region.
Separate priority levels
Urgent messages go to a fast-path subscription while routine ones go elsewhere.
Reduce wasted work
Subscribers avoid receiving and discarding messages they never needed.
Single message transforms
The service also supports lightweight transformations applied to individual messages as they are published or delivered, such as reshaping or masking fields, so simple adjustments do not require a separate processing service. These are suited to small, stateless changes. Larger transformations, enrichment from other data sources, or aggregation across messages are better handled by a processing pipeline.
A schema is like a form with required boxes: the post office refuses letters that do not use it. A filter is like a mailbox that accepts only mail marked with a certain label. A transform is like a clerk who quickly redacts a line on each letter before it is delivered.
Decide on a small standard set of attributes for all messages, such as event type, version, and source. Consistent attributes make filtering, debugging, and monitoring far easier across teams.
Some subscription settings, including filters, can be hard to modify after creation. Test the filter on a copy first and confirm the current rules about what can be changed.
9Retention, Replay, and Importing from Other Sources
Messages do not have to vanish the instant they are processed. You can keep them, replay them, and even bring in streams from elsewhere.
Message retention
An unacknowledged message is retained by a subscription for a limited period, so a subscriber that is down for a while can catch up when it returns. You can configure how long messages are kept, within allowed limits. A topic can also retain messages itself, independent of subscriptions, which lets new subscriptions be created later and still read recent history. Longer retention improves resilience and flexibility but adds storage cost.
Replay
Subscriptions can be configured to keep acknowledged messages for a time as well, and you can then rewind the subscription to an earlier point in time or to a saved marker called a snapshot, so that messages are delivered again. This is invaluable when a bug in your subscriber corrupted data, or when you need to rebuild a downstream system from scratch. Replay turns a message stream from a one-shot delivery into something closer to a recoverable log.
Enable retention of acknowledged messages
Configure the subscription to keep processed messages for the replay window you need.
Detect the problem
Find that a bad deployment or bug produced wrong results over some time range.
Fix the subscriber
Deploy the corrected code, ideally with idempotent handling so repeated work is safe.
Seek back in time
Rewind the subscription to just before the problem began so those messages are delivered again.
Verify the result
Confirm that downstream data is now correct and that the subscription has caught up.
Importing streams from other platforms
The service offers import topics that pull data from certain external streaming platforms into Pub/Sub, including streams from other clouds and from popular streaming systems. This helps teams consolidate event data in one place or migrate gradually without rewriting every producer at once. The availability of specific sources and their setup requirements evolve, so confirm the current list.
Replay is like a security camera with a recording. If something goes wrong at three o’clock, you can rewind the tape to two fifty-nine and watch it again, instead of guessing what happened. Retention decides how long the tape is.
Rewinding delivers old messages again to your subscribers. If your handlers are not idempotent, replay can double-charge customers or re-send emails. Plan and test replay before you need it in an emergency.
Set retention to match your recovery needs, not a default. A subscriber that may be down for a long weekend needs retention that spans the weekend, with some margin.
10Scaling, Throughput, and Flow Control
Pub/Sub scales on its own, but your publishers and subscribers must be designed to keep up and to protect themselves.
The service scales, your code must too
The service absorbs very high publish rates and spreads delivery across many machines without any capacity planning from you. The limits you feel are usually in your own code: how fast publishers can batch and send, how many messages your subscribers can process at once, and how quickly the systems behind your subscribers can respond. Understanding where the true bottleneck is saves a lot of wasted effort.
Publishing efficiently
Publisher client libraries batch many small messages into fewer requests, which greatly improves throughput and reduces cost. You can tune batch size and wait time to trade a little latency for much higher efficiency. Publishing each message in a separate blocking call is one of the slowest possible patterns. Keep messages reasonably small and place large payloads in object storage, sending only a reference in the message.
Subscribing efficiently
Scale out subscribers
Run more subscriber instances on the same subscription. They share the messages and raise total throughput.
Use flow control
Limit how many messages or bytes a subscriber holds at once, so it never takes more than it can process.
Keep handlers fast
Do only the necessary work in the handler and hand long jobs to another system, to avoid deadline problems.
Match concurrency to downstream
Set parallelism according to what databases and services behind you can safely handle.
Autoscale on backlog
Scale subscriber instances based on the number and age of unacknowledged messages.
flowchart TD
B["Backlog grows on subscription"] --> C{"Is processing slow or the downstream limited?"}
C -->|"Subscribers too few"| S["Add subscriber instances"]
C -->|"Handler too slow"| H["Optimize handler or move heavy work out"]
C -->|"Downstream limited"| D["Reduce concurrency and protect downstream"]
S --> R["Backlog drains"]
H --> R
D --> R
A highway can carry a huge number of cars, but if the exit ramp to a small town is narrow, a queue forms on the highway. Pub/Sub is the highway. Your subscriber and the systems behind it are the exit ramp. Widening the highway does not help if the ramp is the problem.
Push delivery and rate
For push subscriptions, the service decides how fast to send requests, adapting to how quickly your endpoint responds. A slow or failing endpoint causes the service to slow down and back off, but a fast endpoint may receive a heavy stream. Make sure your endpoint can scale, and set limits on concurrency where available, so it is not overwhelmed during bursts.
Massively parallel subscribers can overwhelm a database that was sized for modest traffic. Cap concurrency, use connection pooling, and place a buffer in front of fragile systems.
11Security, Identity, and Compliance
Messages often carry business data. Securing who can publish, who can subscribe, and how data is protected is essential.
Access control
Access is governed by Google Cloud identity and access management. You grant roles on a topic or subscription, separating the ability to publish from the ability to subscribe and from administrative rights. Give each application its own service account with only the roles it needs. A service that only publishes order events should not be able to read them, and a service that only consumes should not be able to publish.
Publisher and subscriber roles
Grant publish and subscribe permissions separately, on the specific topics and subscriptions involved.
Service accounts per application
Use a dedicated identity for each application, so access can be traced and revoked independently.
Authenticated push
For push subscriptions, the service can attach a signed identity token to each request so your endpoint can verify the sender.
Encryption in transit and at rest
Messages are encrypted in transit and at rest, with the option to use customer-managed keys where policy requires.
Private connectivity and perimeters
Private access paths and service perimeters reduce exposure to the public internet.
Audit logging
Administrative and data access actions can be recorded for review and compliance evidence.
Securing push endpoints
A push endpoint is a web address that accepts messages, so it must verify that requests really come from Pub/Sub. With authentication enabled, each request carries a signed token tied to a service account and an intended audience. Your endpoint validates the token before trusting the message. Without verification, anyone who discovers the address could send forged messages. Also keep the endpoint private to the extent possible, using ingress restrictions on the receiving service.
A mailroom that accepts parcels at a side door should check a courier’s company badge before taking delivery. Authenticated push is that badge check, performed on every parcel.
Protecting sensitive data in messages
Treat message contents as data that may be stored, retained, replayed, and copied to several subscriptions. Avoid placing secrets such as passwords or private keys in messages. For personal or regulated data, minimize what is included, consider encrypting sensitive fields at the application level, and remember that retention and replay mean data lives longer than a single delivery. Choose topic locations carefully, because they affect where data is stored, which matters for residency rules.
One published message may be copied into many subscriptions, dead letter topics, archives, and warehouse tables. Sensitive data in a message therefore spreads widely, so decide what truly needs to be in the message before publishing.
12Monitoring, Logging, and Troubleshooting
An asynchronous system hides problems unless you watch the right signals. A few metrics tell you almost everything.
The signals that matter
Unacknowledged messages
The backlog on a subscription. A steadily growing backlog means subscribers are not keeping up.
Oldest unacknowledged message age
How long the oldest message has waited. This reflects real delay experienced by the business.
Delivery and ack rates
How many messages are delivered and acknowledged per second, showing throughput and trends.
Redelivery and expired acks
High numbers suggest slow handlers, deadlines too short, or recurring failures.
Dead letter topic size
Growth means messages are failing permanently and need attention.
Publish latency and errors
Slow or failing publishes affect upstream applications and need quick investigation.
Diagnosing a growing backlog
Check the age, not only the count
A large backlog that is shrinking may be fine. A small backlog with a very old message may signal a stuck message.
Look at subscriber health
Confirm subscribers are running, connected, and not crashing or stalling.
Check handler duration
Handlers that take longer than the deadline cause expiry and redelivery, which makes the backlog worse.
Inspect downstream systems
A slow database or service behind the subscriber is a common hidden cause.
Look for poison messages
Repeated redelivery of the same message, especially with ordering, can block progress.
Imagine a queue at a bank counter. The number of people waiting matters, but even more important is how long the person at the front of the line has been waiting. If one customer has waited an hour, something is stuck at the counter even if the line looks short.
Alerts worth setting
| Alert | Why it matters |
|---|---|
| Oldest unacknowledged message age above a threshold | Directly measures how late processing is |
| Backlog growing for a sustained time | Subscribers cannot keep up with publishers |
| Dead letter topic receiving messages | Real work is failing permanently |
| Rise in expired acknowledgments | Deadlines are too short or handlers too slow |
| Publish error rate rising | Upstream applications may be losing events |
Copy a correlation identifier into message attributes and into logs at every step. Following one business event across publisher, topic, subscriber, and downstream systems becomes simple instead of painful.
13Cost, Limits, and Trade-offs
Understanding what drives the bill and where the service has limits keeps designs honest.
What you pay for
Pricing is based mainly on the volume of data published and delivered, with a monthly free allowance for small workloads. Additional charges can apply for features such as retaining messages beyond defaults, storing messages on topics, snapshots, replay, and data transfer across regions. Direct-to-storage subscriptions may have their own charges in addition to the costs of the destination service. Because every subscription receives its own copy of each message, delivery volume grows with the number of subscriptions, so fan-out increases cost. Exact rates change, so use the official pricing page and calculator.
Publish volume
The amount of data published into topics, which is often the largest base charge.
Delivery volume
Each subscription’s deliveries count, so many subscriptions multiply delivered data.
Retention and storage
Keeping messages longer, on topics or subscriptions, adds storage cost.
Cross-region transfer
Moving messages between regions can add network charges.
Destination costs
Warehouse storage, bucket storage, and compute used by subscribers are billed separately.
Advantages and trade-offs
Advantages
- Fully managed, with no brokers or capacity planning
- Decouples systems so failures stay local
- Scales to very high throughput automatically
- Flexible delivery: pull, push, and direct-to-storage
- Optional ordering, exactly-once, filtering, and dead letter handling
- Deep integration with other Google Cloud services
Disadvantages / Trade-offs
- At-least-once delivery means handlers must handle duplicates
- Asynchronous flows are harder to trace and debug
- Ordering and exactly-once bring throughput and usage constraints
- Fan-out raises delivered data and cost
- Not a database, and not suited to request-reply calls needing instant answers
Where Pub/Sub sits among options
| Option | Best for | Main difference |
|---|---|---|
| Pub/Sub | Event distribution, streaming ingestion, decoupling | Managed, global, elastic messaging |
| Cloud Tasks | Controlled dispatch of individual tasks to a specific handler | Targeted rate and schedule control per task |
| Eventarc | Routing events from Google Cloud sources to services | Event routing layer, often delivered through Pub/Sub underneath |
| Self-managed Kafka | Very high control and ecosystem compatibility | You run and scale the brokers |
| Direct API calls | Simple synchronous request and response | Tight coupling, immediate answer |
Quotas, message size limits, retention ranges, and prices are updated by Google Cloud over time. Confirm them on the official quotas and pricing pages before finalizing a design.
14Design Patterns and Anti-patterns
Good patterns make event-driven systems feel calm. Anti-patterns make them feel haunted.
Patterns worth adopting
Fan-out for independent consumers
Publish a business event once, and attach a separate subscription for each team that cares, so each consumer evolves, fails, and scales independently.
Work queue with competing consumers
Many workers share one subscription, splitting messages among themselves, which smooths bursts and lets you add workers to increase throughput.
Event-carried reference
Keep messages small by carrying an identifier or a storage location, and let the subscriber fetch the large data itself.
Landing zone for analytics
Use a direct warehouse or storage subscription to land raw events with no code, then process them later with batch or streaming jobs.
Idempotent consumers with dead letter handling
Make every subscriber safe to repeat, and attach a dead letter topic with alerts and a repair routine for messages that cannot succeed.
Anti-patterns to avoid
Problem
Subscribers assume each message arrives exactly once and perform non-repeatable actions directly.
Why It’s Harmful
Duplicates cause double charges, repeated emails, and corrupted counters, usually discovered long after the damage is done.
Correct Approach
Make handlers idempotent using message or business identifiers and a durable record of what was processed.
Problem
No dead letter topic is configured, and the retry limit is unlimited by default behavior.
Why It’s Harmful
A poison message loops forever, wasting capacity, hiding real problems, and blocking ordered streams.
Correct Approach
Configure a dead letter topic with a sensible attempt limit, a subscription to retain failures, and alerts on its size.
Problem
Large payloads, such as full documents or images, are placed directly in messages.
Why It’s Harmful
Costs rise, limits are hit, copies multiply across subscriptions, and sensitive data spreads widely.
Correct Approach
Store large data in object storage and publish only a reference, with access controlled at the storage layer.
Problem
One ordering key is used for all messages to get global ordering.
Why It’s Harmful
All traffic serializes through one key, limiting throughput, and one failing message blocks everything behind it.
Correct Approach
Use ordering only where required, with many distinct keys such as customer or entity identifiers.
Problem
Long-running work is done inside the message handler, with a short acknowledgment deadline.
Why It’s Harmful
Deadlines expire, messages are redelivered while the first attempt is still running, and duplicate work piles up.
Correct Approach
Keep handlers short, extend leases where appropriate, or hand heavy work to a job system and acknowledge once it is safely queued.
Problem
Publishers wait on subscribers’ results, treating the topic like a request and response call.
Why It’s Harmful
It reintroduces tight coupling and latency, defeating the purpose of messaging, and complicates failure handling.
Correct Approach
Use messaging for asynchronous events. For immediate answers, use direct calls, or design a clear asynchronous reply flow.
15Best Practices and Common Mistakes
A checklist of habits that experienced teams build into every Pub/Sub deployment, and the traps that catch newcomers.
Best practices
Create subscriptions before publishing
Make sure every consumer has a subscription in place so no early messages are missed.
Choose the right subscription type
Use pull for controlled throughput and ordering, push for simple serverless handlers, and direct-to-storage for no-code ingestion.
Design idempotent handlers
Assume repeats can happen and make repeated processing harmless.
Always add a dead letter path
Set an attempt limit, a retained dead letter subscription, alerts, and a repair routine.
Use schemas and consistent attributes
Define message contracts and standard attributes so teams can evolve safely and filter precisely.
Batch publishes and use flow control
Let client libraries batch, and cap how much each subscriber holds at once.
Secure each identity narrowly
Use separate service accounts with least-privilege roles, and authenticate push requests.
Monitor age and backlog
Alert on oldest unacknowledged message age, backlog growth, dead letter size, and expired acknowledgments.
Plan retention and replay
Match retention to recovery needs and rehearse a replay so it is safe when you need it.
Common mistakes
Expecting messages to be waiting later. Without subscriptions at publish time, the messages are not retained for future consumers unless topic retention is configured.
Acknowledging immediately for speed, then crashing during processing. The message is gone and the work is lost. Acknowledge after the work succeeds, or after it is safely handed off.
Setting a deadline shorter than typical processing time, causing endless redelivery and duplicate work.
Not watching age and backlog metrics. By the time the business notices delays, the queue may be hours deep.
Accepting any request that reaches the endpoint. Verify the signed token so forged messages are rejected.
Discovering during an incident that rewinding a subscription double-processes data. Rehearse replay in a safe environment first.
A short pre-launch review
| Question | What a good answer looks like |
|---|---|
| Can our handlers safely see a message twice? | Yes, through idempotent processing with a durable record |
| What happens to a message that always fails? | It reaches a dead letter topic with alerts and a repair routine |
| Who can publish and who can subscribe? | Separate, least-privilege identities per application |
| What if a subscriber is down for hours? | Retention covers the outage and backlog alerts fire |
| How do we recover from a bad deployment? | Tested replay with idempotent handlers |
| Will downstream systems survive a burst? | Concurrency caps and flow control protect them |
16Real-World and Industry Scenarios
These illustrative scenarios, drawn from common industry patterns, show how the ideas combine in practice.
An e-commerce platform publishing order events
Every order change is published once as an event with attributes for type and region. Separate subscriptions feed the warehouse system, the email service, the fraud team, and the analytics warehouse. A direct warehouse subscription lands raw events for reporting. Each consumer fails and scales independently, and a dead letter topic catches malformed orders for review.
A ride-hailing company streaming location updates
Vehicles publish positions continuously, with the vehicle identifier as the ordering key so each vehicle’s updates stay in sequence while millions of vehicles run in parallel. Pull subscribers update a low-latency serving store, while a storage subscription archives raw data cheaply for later analysis.
A bank processing payment notifications
A payment network sends notifications that are published to a topic with a schema. Subscribers use exactly-once delivery as an extra safeguard and idempotent handlers with durable records as the primary protection. Retention and replay allow recovery from faulty releases, and strict identities and private connectivity satisfy security reviews.
A media company collecting application logs
Services publish structured log events to a topic. A streaming pipeline subscription enriches and aggregates them, while a storage subscription keeps raw copies for compliance. Backlog and age alerts make sure delays are noticed quickly, and filters route security events to a dedicated team.
An internet-of-things platform ingesting sensor data
Gateways publish readings from thousands of devices. A BigQuery subscription writes readings straight into a table for analytics with no pipeline code, and a separate pull subscription feeds a real-time alerting service that watches for abnormal values.
What these scenarios share
Each team published events once and let many consumers subscribe independently. Each kept messages small and meaningful, made handlers safe to repeat, attached dead letter handling, secured identities narrowly, and watched backlog age. None treated the topic as a synchronous call or assumed messages arrive exactly once without proof.
17Frequently Asked Questions
Short, direct answers to questions that come up again and again.
A topic is the channel publishers send messages to. A subscription is an attachment to a topic that represents one stream of messages for a group of readers. Subscribers read from subscriptions.
Use pull when you want control over pace, high throughput, or ordered processing. Use push for simple serverless handlers or webhooks at low to moderate volume. Direct-to-storage subscriptions need no code at all.
Yes. The default guarantee is at-least-once delivery. Design handlers to be idempotent, and consider exactly-once delivery for workloads where duplicates are especially harmful.
It is the time the service waits for a subscriber to acknowledge a message before sending it again. Client libraries can extend it while work continues.
Configure a dead letter topic with a maximum number of delivery attempts, give it its own subscription so failures are retained, set alerts on its size, and decide who repairs and replays those messages.
Publish with an ordering key, enable ordering on the subscription, and acknowledge in order. Use many distinct keys so different entities still process in parallel.
Yes. Create one subscription per service on the same topic, and each receives its own copy. Multiple subscribers on one subscription instead share the messages.
Yes, with a BigQuery subscription that writes messages as rows, and similar subscriptions exist for Cloud Storage and Bigtable. These remove the need to write pipeline code for simple ingestion.
Unacknowledged messages are retained for a configurable period, and you can also retain acknowledged messages or store messages on the topic. Check current limits and costs in the official documentation.
Yes, if you retain acknowledged messages. You can seek a subscription to a time or a snapshot so messages are delivered again, but make sure your handlers can safely process repeats.
Enable authentication so each request carries a signed token tied to a service account, verify the token and audience in your endpoint, and restrict who can reach the endpoint.
The age of the oldest unacknowledged message and the backlog size on each subscription, plus the size of any dead letter topic and the rate of expired acknowledgments.
Usually not. It is designed for asynchronous messaging and events. For immediate answers, use direct calls or a clearly designed asynchronous reply flow.
18Summary and Key Takeaways
Pub/Sub is Google Cloud’s fully managed, global messaging service for decoupling the parts of a system. Publishers send messages to topics, subscriptions attached to the topic each receive their own copy, and subscribers process and acknowledge messages. Subscriptions can deliver by pull for controlled pace, by push to an HTTPS endpoint, or directly into BigQuery, Cloud Storage, or Bigtable with no code. The default guarantee is at-least-once delivery, so duplicates are possible, and idempotent handlers are the foundation of correctness. Acknowledgment deadlines, retry policies with backoff, and dead letter topics handle slow and failing consumers, while ordering keys and exactly-once delivery add stronger guarantees at a cost. Schemas, attributes, filters, and transforms keep shared topics orderly. Retention and replay turn the stream into something recoverable, and import topics bring in data from other platforms. Scaling depends on batching publishers, flow-controlled and scalable subscribers, and protected downstream systems. Security rests on narrow identities per application, authenticated push, encryption, and careful handling of sensitive data that may be copied widely. Monitoring the age of the oldest message, the backlog, expired acknowledgments, and dead letter size reveals trouble early. Teams that publish small events, tolerate duplicates, plan the failure path, and watch their queues build systems that stay calm under pressure.
Key Takeaways
- Decouple with topics and subscriptions — publishers send to topics, each subscription gets its own copy, and subscribers on one subscription share the work.
- Pick the right delivery type — pull for control and ordering, push for simple serverless handlers, and direct-to-storage subscriptions for no-code ingestion.
- Expect duplicates — at-least-once delivery is the default, so make handlers idempotent, and treat exactly-once delivery as an extra safeguard.
- Plan the failure path — use retry backoff, a dead letter topic with its own subscription, alerts on its size, and a repair routine.
- Use ordering carefully — ordering keys preserve sequence within a key, so use many distinct keys and avoid forcing global order.
- Secure and minimize — use narrow service accounts, authenticated push, and keep sensitive data and large payloads out of messages, since messages are copied widely.
- Watch the age of the oldest message — monitor backlog, expired acknowledgments, and dead letter growth, retain enough history to replay, and rehearse recovery before you need it.