Pub/Sub
01 / 02

Topics, Subscriptions & Delivery

Topics, Subscriptions & Delivery

Publishing & Subscribing

const { PubSub } = require('@google-cloud/pubsub');
const pubsub = new PubSub();

// Publisher — knows only the topic name, nothing about subscribers
const topic = pubsub.topic('order-events');
await topic.publishMessage({
  data: Buffer.from(JSON.stringify({ orderId: '123' })),
  attributes: { eventType: 'order_placed' },  // metadata for filtering
});

// Pull subscriber — fetches and processes at its own pace
const subscription = pubsub.subscription('inventory-sub');
subscription.on('message', (message) => {
  const idempotencyCheck = alreadyProcessed(message.id);
  if (!idempotencyCheck) {
    processOrder(JSON.parse(message.data.toString()));
  }
  message.ack();  // won't be redelivered after this
});

// Push subscription (e.g. to a Cloud Run endpoint) instead delivers via
// HTTP POST — good fit for scale-to-zero serverless consumers.

CLI

gcloud pubsub topics create order-events
gcloud pubsub subscriptions create inventory-sub --topic=order-events
gcloud pubsub subscriptions create billing-sub --topic=order-events
# Both subscriptions get their OWN independent copy of every message
# published to order-events — fan-out to multiple independent consumers.

Delivery Guarantees & Idempotency

Pub/Sub's default guarantee is at-least-once — a message may occasionally be redelivered (e.g. if it isn't acknowledged within the subscription's ack deadline). Even with exactly-once delivery enabled, treat idempotency as defense-in-depth rather than relying solely on the platform guarantee — a subscriber crashing after processing but before its ack is recorded is a scenario worth protecting against regardless.

Ordering & Filtering

// Ordering key — preserves relative order for messages sharing the key,
// NOT a global topic-wide order guarantee
await topic.publishMessage({
  data: Buffer.from(JSON.stringify(event)),
  orderingKey: `order-${orderId}`,
});

// Subscription-level filter — only delivers matching messages, so this
// subscriber never even receives (or has to process/discard) irrelevant ones
// gcloud pubsub subscriptions create billing-sub --topic=order-events \
//   --filter='attributes.eventType="order_placed"'

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free