Starts by default

Google's Pub/Sub emulator, wired in.

Topics, subscriptions, publish, pull, StreamingPull and push, on Google's own emulator.

Backed by: Google's Pub/Sub emulator Google's emulator

In the console

A Pub/Sub topic and its subscriptions
Captured 2026-09-28 from main @5da2bd0. Product icons hidden.
A Pub/Sub subscription
Captured 2026-09-28 from main @5da2bd0. Product icons hidden.

What it covers

Pub/Sub runs on Google’s own emulator, integrated rather than reimplemented. PUBSUB_EMULATOR_HOST from cloudburrow env is all the official clients need. Its state is lost on restart, whatever --mode says.

  • Topics and subscriptions
  • Publish and pull
  • StreamingPull
  • Push delivery

Tested snippet

From docs/examples/ at main 82a2eb9. CI runs these blocks against CloudBurrow.

Python · Pub/Sub
import os, uuid
from google.cloud import pubsub_v1

project = os.environ["GOOGLE_CLOUD_PROJECT"]
publisher, subscriber = pubsub_v1.PublisherClient(), pubsub_v1.SubscriberClient()
topic = publisher.topic_path(project, f"example-{uuid.uuid4().hex[:12]}")
sub = subscriber.subscription_path(project, f"example-{uuid.uuid4().hex[:12]}")
publisher.create_topic(name=topic)
subscriber.create_subscription(name=sub, topic=topic)

publisher.publish(topic, b"hello").result(timeout=30)
messages = subscriber.pull(subscription=sub, max_messages=1, timeout=30).received_messages
assert messages[0].message.data == b"hello"
subscriber.acknowledge(subscription=sub, ack_ids=[messages[0].ack_id])

subscriber.delete_subscription(subscription=sub)
publisher.delete_topic(topic=topic)

This block is run by CloudBurrow's Python suite in CI. If it stops working, CI fails. docs/examples/python.md

Node.js · Pub/Sub
import assert from 'node:assert/strict';
import { randomUUID } from 'node:crypto';
import { once } from 'node:events';
import { PubSub } from '@google-cloud/pubsub';

const pubsub = new PubSub({ projectId: process.env.GOOGLE_CLOUD_PROJECT });
const [topic] = await pubsub.createTopic(`example-${randomUUID()}`);
const [subscription] = await topic.createSubscription(`example-${randomUUID()}`);

await topic.publishMessage({ data: Buffer.from('hello') });
const [message] = await once(subscription, 'message', { signal: AbortSignal.timeout(30_000) });
assert.equal(message.data.toString(), 'hello');
message.ack();

await subscription.close();
await subscription.delete();
await topic.delete();
await pubsub.close();

This block is run by CloudBurrow's Node.js suite in CI. If it stops working, CI fails. docs/examples/node.md

What's verified

Pub/Sub

18 of 25 RPCs Verified in v0.1.0

Pub/Sub in v0.1.0: 18 Verified of 25

33 of 35 RPCs Verified on main next release

Pub/Sub on main: 33 Verified of 35
Every Pub/Sub RPC, with its test →

Not supported

  • State does not survive a restart, a limitation of Google's emulator, measured
  • IAM methods return Unimplemented from Google's emulator
  • gcloud pubsub is partial: topics list only

Source: docs/compatibility.md at main 82a2eb9.

Questions

Does Pub/Sub keep its topics across a restart?

No. Google's emulator loses topics even with --data-dir. It was measured, not assumed.
Link to this answer

Build against Google Cloud APIs, locally

Free and open source under Apache-2.0. No account, no sign-up, no Google Cloud bill.

Get started