Skip to content
Learni
View all tutorials
Cloud Infrastructure

How to Master Cloud Pub/Sub on GCP in 2026

Lire en français

Introduction

Google Cloud Pub/Sub is the leading asynchronous messaging service for modern event-driven architectures. It decouples producers and consumers at scale while guaranteeing message delivery. In 2026, resilience, ordering, and latency requirements demand deep mastery of advanced features like dead-letter queues, exactly-once delivery, and Avro schemas. This tutorial guides you step by step toward a production-ready implementation.

Prerequisites

  • Google Cloud account with billing enabled
  • Google Cloud CLI SDK installed and authenticated
  • Strong knowledge of TypeScript and Node.js 20+
  • Understanding of event-driven patterns and SLAs

Project Setup and Authentication

setup.sh
#!/bin/bash
PROJECT_ID="mon-projet-pubsub-2026"
gcloud config set project $PROJECT_ID
gcloud services enable pubsub.googleapis.com
npm install @google-cloud/pubsub typescript @types/node

This command enables the Pub/Sub API and installs the official client. Ensure the service account has Pub/Sub Publisher and Subscriber roles.

Creating a Topic with Advanced Retention

create-topic.ts
import { PubSub } from '@google-cloud/pubsub';

const pubsub = new PubSub();

async function createAdvancedTopic() {
  const topicName = 'orders-topic';
  const [topic] = await pubsub.createTopic({
    name: topicName,
    messageRetentionDuration: { seconds: 86400 * 7 },
    messageStoragePolicy: { allowedPersistenceRegions: ['europe-west1'] }
  });
  console.log(`Topic created: ${topic.name}`);
}
createAdvancedTopic();

We set a 7-day retention period and a regional storage policy to meet data sovereignty requirements.

Publishing Messages with Ordering

publish-ordered.ts
import { PubSub } from '@google-cloud/pubsub';

const pubsub = new PubSub();

async function publishOrderedMessages() {
  const topic = pubsub.topic('orders-topic', { enableMessageOrdering: true });
  const messages = [
    { data: Buffer.from(JSON.stringify({orderId: '123', status: 'created'})), orderingKey: '123' },
    { data: Buffer.from(JSON.stringify({orderId: '123', status: 'paid'})), orderingKey: '123' }
  ];
  for (const msg of messages) {
    await topic.publishMessage(msg);
  }
}
publishOrderedMessages();

The orderingKey guarantees delivery order per key. Enable enableMessageOrdering on the topic to activate this critical production feature.

Creating a Subscription with Dead-Letter Queue

create-subscription.ts
import { PubSub } from '@google-cloud/pubsub';

const pubsub = new PubSub();

async function createSubscriptionWithDLQ() {
  const topic = pubsub.topic('orders-topic');
  const dlqTopic = pubsub.topic('orders-dlq');
  await dlqTopic.create();
  const [subscription] = await topic.createSubscription('orders-processing', {
    deadLetterPolicy: {
      deadLetterTopic: dlqTopic.name,
      maxDeliveryAttempts: 5
    },
    ackDeadlineSeconds: 60
  });
  console.log(`Subscription created: ${subscription.name}`);
}
createSubscriptionWithDLQ();

The dead-letter queue automatically isolates unprocessed messages after 5 attempts, preventing data loss while enabling later manual handling.

Consuming with Exactly-Once and Retry

consume-messages.ts
import { PubSub } from '@google-cloud/pubsub';

const pubsub = new PubSub();

async function consumeWithExactlyOnce() {
  const subscription = pubsub.subscription('orders-processing');
  subscription.on('message', async (message) => {
    try {
      const data = JSON.parse(message.data.toString());
      await processOrder(data);
      message.ack();
    } catch (error) {
      console.error('Processing error:', error);
      message.nack();
    }
  });
}
async function processOrder(order: any) {
  // Critical business logic
  console.log('Processing order:', order.orderId);
}
consumeWithExactlyOnce();

nack() enables controlled retries. Combine with DLQ for maximum resilience. Avoid long-running processing inside the handler.

Best Practices

  • Always enable ordering when event sequence is critical
  • Configure dead-letter queues with a limited number of attempts
  • Use Avro or Protobuf schemas to ensure message compatibility
  • Monitor backlog and latency metrics via Cloud Monitoring
  • Limit message size to 10 MB and prefer batch publishing

Common Errors to Avoid

  • Forgetting to enable enableMessageOrdering on the topic before using ordering keys
  • Not configuring a dead-letter queue, causing infinite retry loops
  • Ignoring message deserialization errors without proper nack
  • Using pull subscriptions without flow control, leading to timeouts

Going Further

Deepen your skills with our advanced Google Cloud training. Also explore event-driven architecture patterns and integration with Cloud Run and Dataflow.