Overview
Google Pub/Sub is supported as a queue target alongside Kafka and Redpanda. The Wirekite extractor publishes one message per.ckt
change record (or one per batch when queueBatchSize > 1) using the
official cloud.google.com/go/pubsub SDK on the Go-side extractors and
google-cloud-cpp on the SQL Server C++ extractor.
For cross-vendor concepts (message format, ordering, retries, charts),
see Queues Overview.
When to choose Pub/Sub
Pick Pub/Sub when:- The deployment already runs in Google Cloud and Pub/Sub fits the existing pipeline (Dataflow, BigQuery streaming inserts, downstream services that already subscribe to Pub/Sub topics).
- You don’t want to operate a Kafka/Redpanda cluster.
- Per-table delivery order is required (Pub/Sub preserves it via ordering keys; see “Ordering and exactly-once” below).
- Latency is dominant and you control the broker hardware.
- Per-message cost is unacceptable (Pub/Sub Standard is metered; Kafka is hardware-cost only — see “Cost” below).
- The downstream consumer is a Kafka-native system.
One-time GCP setup
1. Create the topic
<env>-wirekite-<source>-to-<target>.
2. Create the subscription
The subscription is what the downstream consumer reads from. Two flags must be set at creation time — neither can be flipped later on an existing subscription:
Recommended subscription settings:
ack-deadline = 60s(default10s— increase if your consumer takes longer than 10s to process a single batched message).message-retention-duration = 1d(sufficient for catching up after a short consumer outage; longer retention raises storage cost).
3. Service-account credentials
Create a service account dedicated to the Wirekite migration:Both roles are required.
pubsub.publisher alone does not include
pubsub.topics.get, which Wirekite calls at startup to confirm the
topic exists before any publishes are accepted. Without
pubsub.viewer, the extractor exits at startup with pubsub topic … exists check: permission denied.pubsub_reader) or its drain helper (pubsub_admin -seek-now)
against the same subscription, also add:
Wirekite configuration
Queue-target definition
Create the queue target through the UX wizard or the API:The kafka-only fields (
brokers, compression) are rejected on
Pub/Sub queue targets — gRPC handles transport compression
transparently, and Pub/Sub has no “broker list” concept. Setting
either field surfaces the misconfiguration rather than silently
ignoring it.Extractor config keys
When wiring the extractor directly, the orchestrator emits:change_extractor_pubsub C++
binary).
Ordering and exactly-once
Ordering key. Wirekite setsOrderingKey = "<schema>.<table>" on
every published message. Per-table change order matches the source’s
commit order end-to-end as long as the subscription has
enableMessageOrdering=true.
Per-table batching. When queueBatchSize > 1, lines are accumulated
in independent per-key buffers — one buffer per schema.table. A
single Pub/Sub message therefore never contains rows from two
different tables (each message carries exactly one ordering key).
Exactly-once delivery. Wirekite’s reference consumer relies on
enableExactlyOnceDelivery=true. Without it, transient ack failures
cause the broker to redeliver messages already processed; the change
loader will reapply changes and validation runs will report spurious
diffs.
Per-key throughput ceiling. Pub/Sub bounds throughput per ordering
key at roughly 1 MB/s. For a single high-write table whose change
volume exceeds that, split it at the source level (separate migrations
or separate topics) — a single Pub/Sub topic with one ordering key per
table is not the right shape for >1 MB/s on one table.
Failure semantics
The Wirekite Pub/Sub publisher is fail-fast, with two distinct detection paths:-
Explicit error. When the SDK’s
PublishResult.Get()returns an error (aftergaxexponential backoff is exhausted on retryable codes —Unavailable,DeadlineExceeded,ResourceExhausted), Wirekite incrementserrors, logsFATAL: QUEUE delivery failed, and exits. -
Stall watchdog. A 5-second-cadence watchdog tracks whether the
deliveredcounter is advancing. If it has been frozen for 30 seconds while there are unresolved publishes (inflight > 0), Wirekite logsFATAL: QUEUE stall detected — inflight=N, delivered held at M for Ks with no progressand exits. This catches the pathological case where the SDK’s per-message future never resolves — an observed-once failure mode that the SDK does not surface as an error.
Cost
Pub/Sub Standard pricing (US, as of 2026-05):$40 / TB of message
throughput, plus $0.27/GB egress for cross-region consumers, plus
storage if subscription retention exceeds 7 days.
Concrete sizing:
Notes:
- “Changes/s” is per source, not per topic. A single topic carries every change from one migration.
- Application-level batching (
queueBatchSize=100) does NOT reduce message-throughput billing — Pub/Sub bills on byte volume, not RPC count. Batching reduces RPC count and SDK overhead, not data volume. - For benchmark-scale runs, prefer Kafka/Redpanda on customer-managed hardware. Pub/Sub Standard is cost-appropriate for production-rate workloads, not synthetic load tests.
Operations
Drain a subscription
The reference helperqa/queue_reader/pubsub_admin -seek-now moves the
subscription’s read cursor to the current time so any messages
published before that point are treated as already-acked. Used by
qa/fulltest between iterations; usable ad-hoc:
Reference consumer
OP\tschema\ttable\t... prefix into per-table .ckt files in
<demux-dir>. Refuses to start unless the subscription has both
enableMessageOrdering=true and enableExactlyOnceDelivery=true.
Validate publish counts
The extractor andpubsub_reader print final counters in the same
shape:
submitted and delivered should match exactly when the run completes
cleanly. Any non-zero errors indicates a publish-side failure that
will already have been logged earlier as a FATAL line and triggered
extractor exit.
Troubleshooting
For Kafka/Redpanda-specific setup, see Kafka and Redpanda.
