Pub/Sub Messaging Model | Topics, Fan-out, and Ordering Keys

The Pub/Sub overview covers what topics and subscriptions are and why the service exists. This page goes deeper into how messages actually flow: fan-out mechanics across multiple subscriptions, ordering keys for per-entity sequencing, server-side attribute filters to reduce unnecessary delivery, and when exactly-once delivery is worth its trade-offs. These are the details that determine whether a Pub/Sub-based system behaves correctly under real-world conditions.

Why these mechanics matter

Pub/Sub is simple to get started with but has important nuances that affect system correctness. Ordering is opt-in and only guaranteed within an ordering key. Exactly-once delivery is opt-in, costs more, and is usually the wrong choice. Fan-out means each subscription accumulates backlog independently. Getting these details wrong causes subtle bugs: out-of-order processing, unexpected duplicates, or subscribers falling behind without visibility.

Fan-out: how multiple subscriptions work

When you attach multiple subscriptions to a topic, Pub/Sub delivers every published message to every subscription independently. Each subscription has its own message queue, its own delivery cursor, and its own ack state. Acknowledging a message in subscription A has no effect on subscription B.

This means you can attach an analytics pipeline, an audit logging service, and a notification service to the same topic, each receiving every message independently with no coordination required between them. Each can fall behind or catch up at its own pace without affecting the others.

Analogy

Publishing to a topic is like sending a company-wide email. Every person with access to that mailing list (subscription) receives their own copy. One person archiving their copy has no effect on anyone else’s inbox.

Creating topics and subscriptions

Topics and subscriptions are created and managed with the gcloud pubsub command group.

# Create a topic
gcloud pubsub topics create order-events --project=my-app-prod

# Create a pull subscription with a 60-second ack deadline
gcloud pubsub subscriptions create order-processor \
  --topic=order-events \
  --ack-deadline=60 \
  --project=my-app-prod

# Publish a test message
gcloud pubsub topics publish order-events \
  --message='{"order_id": "ord-123", "status": "placed"}' \
  --project=my-app-prod

Message attributes and server-side filtering

Messages carry optional attributes: key-value pairs of strings attached alongside the data payload. Attributes are useful for routing metadata (event type, source service, schema version, environment) without embedding them in the data itself.

Subscriptions support server-side filtering based on attribute values. A subscription with a filter like attributes.event_type = “purchase” only delivers messages where that attribute matches. Other messages are discarded at the Pub/Sub layer before reaching your consumer. This reduces delivery cost and processing overhead when a topic carries multiple event types and a consumer only cares about a subset.

Note

Server-side filtering is set on the subscription, not on the topic. A filtered subscription still receives all messages for evaluation; it discards non-matching ones before delivery. All messages count against the topic’s retention period regardless of filters.

Ordering keys: per-entity message ordering

By default, Pub/Sub makes no ordering guarantees. Messages may arrive out of the order they were published, particularly across regions or under high load. For many use cases this is acceptable.

Ordering keys solve cases where order matters. When a publisher attaches an ordering key to a message, Pub/Sub guarantees that all messages with the same ordering key are delivered in publish order to a given subscriber. Messages with different keys may still be delivered out of order relative to each other.

Enable ordering keys on the subscription with —enable-message-ordering. Messages with an ordering key are delivered sequentially to one subscriber at a time for that key, which limits parallelism per key. For high-throughput scenarios with ordering requirements, use many distinct keys (one per user, one per device, one per order) rather than one shared key. One shared key for all messages drops effective throughput to what one subscriber can process.

Exactly-once delivery: rarely the right choice

Standard Pub/Sub delivery is at-least-once. A message may be delivered more than once. The standard solution is to make consumers idempotent: processing the same message twice produces the same result as processing it once.

Pub/Sub offers exactly-once delivery as an opt-in on individual subscriptions. With it enabled, the service tracks ack IDs and guarantees each message is processed exactly once, provided the consumer uses the exactly-once ack token correctly.

Exactly-once delivery has higher latency, lower throughput, and costs more. Use it selectively, only when idempotency is genuinely impractical, not as a default safety net. It is also only available in specific regions.

Common beginner mistakes

  1. Assuming messages arrive in order by default. Without ordering keys, Pub/Sub makes no ordering guarantees. If your consumer logic depends on processing events in sequence for a specific entity, you must use ordering keys. Assuming default ordering produces incorrect results under load.
  2. Using one ordering key for all messages in a high-throughput topic. For a given key, Pub/Sub delivers messages sequentially to one subscriber. If all messages share one key, effective throughput drops to what one subscriber can process. Use per-entity keys (per user, per device, per order) to maintain parallelism while preserving ordering within each entity.
  3. Not using server-side filtering when only a subset of events is needed. If a topic carries ten event types and your consumer cares about one, configure a subscription filter. Without it, your consumer receives all ten types and discards nine in application code, paying delivery cost for messages it throws away immediately.
  4. Enabling exactly-once delivery as the default “safe” choice. It is not free. Higher latency, lower throughput, and higher cost make it the wrong default. Build idempotent consumers instead: cheaper, more resilient, and compatible with standard at-least-once delivery.

Frequently asked questions

How does Pub/Sub fan-out work?

When a message is published to a topic, Pub/Sub delivers a copy to every subscription independently. Each subscription has its own message queue and ack state. A slow or backlogged subscription does not affect delivery to other subscriptions. Acknowledging a message in one subscription has no effect on any other subscription.

What are ordering keys and when should I use them?

Ordering keys are string values attached to messages at publish time. Messages sharing the same ordering key are delivered in publish order to a given subscriber. Use ordering keys when processing must respect sequence for a specific entity: updates to a user record, events from a specific IoT device, or changes to a specific order.

When is exactly-once delivery worth the cost?

Exactly-once delivery guarantees no duplicates, but has higher latency, lower throughput, and higher cost. The better default is to build idempotent consumers that handle at-least-once delivery. Reserve exactly-once delivery for cases where building idempotent consumers is genuinely impractical, not as a general-purpose safety net.

What is server-side subscription filtering?

A subscription can include a filter expression based on message attributes. Only messages where the attribute matches are delivered to that subscription. Other messages are discarded at the Pub/Sub layer before reaching your consumer. This reduces delivery cost when a topic carries multiple event types and a consumer only cares about a subset.

Last verified: 19 March 2026 Cloud services change frequently. Verify details against official documentation before making infrastructure decisions.