From pubsub
Google Cloud Pub/Sub: topics and schemas, subscription types, delivery semantics, ordering, dead-letter topics, ack-deadline / flow control, Go client SDK. Use for Go code importing cloud.google.com/go/pubsub, .proto schemas attached to topics, or gcloud pubsub commands.
npx claudepluginhub christopherdavenport/christopherdavenport-marketplace --plugin pubsubThis skill uses the workspace's default tool permissions.
Pub/Sub is at-least-once by default and exactly-once on opt-in subscriptions, but only if the subscriber respects ack deadlines and the publisher uses ordering keys correctly. The frequent failure modes — duplicate processing, message loss after a subscriber crash, "stuck" subscriptions, OOM under load, push-endpoint retry storms — almost always trace to a handful of misconfigured knobs documen...
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Guides building MCP servers enabling LLMs to interact with external services via tools. Covers best practices, TypeScript/Node (MCP SDK), Python (FastMCP).
Share bugs, ideas, or general feedback.
Pub/Sub is at-least-once by default and exactly-once on opt-in subscriptions, but only if the subscriber respects ack deadlines and the publisher uses ordering keys correctly. The frequent failure modes — duplicate processing, message loss after a subscriber crash, "stuck" subscriptions, OOM under load, push-endpoint retry storms — almost always trace to a handful of misconfigured knobs documented across many Google docs pages. This skill encodes those rules so Claude can prevent them during topic/subscription design, subscriber code review, and publisher tuning.
Covers: topics and schemas (Avro, Protobuf, schema revisions, BACKWARD/FORWARD compatibility); subscription types (pull, push, StreamingPull, BigQuery, Cloud Storage); delivery semantics (at-least-once, exactly-once); ordering keys (OrderingKey, EnableMessageOrdering, ResumePublish); dead-letter topics (DLT/DLQ); ack-deadline and lease management (modifyAckDeadline, MaxExtension); flow control (MaxOutstandingMessages, MaxOutstandingBytes, NumGoroutines); message retention (RetainAckedMessages, seek, snapshot); subscription filters; retry policy and exponential backoff; publisher batching (PublishSettings, CountThreshold, DelayThreshold, ByteThreshold); the Go client (Topic.Publish, Subscription.Receive, msg.Ack / msg.Nack, PublishResult); monitoring metrics (oldest_unacked_message_age, num_undelivered_messages).
Out of scope: Pub/Sub Lite, Kafka, Cloud Tasks, Eventarc, Cloud Scheduler.
These cross-cut almost every Pub/Sub task. Internalize them before reaching for a topic-specific reference.
msg.ID (server-assigned, stable across redeliveries) or a business key. Even exactly-once subscriptions can deliver duplicates across a subscriber restart window; idempotency is the only durable defense.Receive's callback. If the callback hands work off to a background goroutine and returns, the lease stops extending and the message redelivers. Do the work synchronously inside the callback or use a worker pool that the callback selects on.EnableMessageOrdering = true on BOTH publisher and subscription. Setting it on only one side silently disables ordering. A publish error on one key blocks all subsequent publishes for that key — call Topic.ResumePublish(orderingKey) to recover.EnableExactlyOnceDelivery) and adds latency to every ack. EOD reduces but does not eliminate duplicates — make handlers idempotent regardless.roles/pubsub.publisher on the DLT, and roles/pubsub.subscriber on the source subscription. Without both, retries continue forever.Subscription.Receive blocks until error or ctx.Done() — and MUST be cancelled for clean shutdown. Never call Receive twice concurrently on the same *pubsub.Subscription; spawn a second handle (or restructure your worker) if you need parallel streams.PublishSettings.CountThreshold, DelayThreshold, and ByteThreshold; otherwise you pay per-message RPC overhead.MaxOutstandingMessages / MaxOutstandingBytes) is the only thing protecting subscribers from OOM. Defaults are 1000 messages / 1 GiB per Subscription.Receive call. Lower them when each message is heavy or processing is slow.RetainAckedMessages = true. Seek to a past timestamp only replays what is still retained (default retention 7 days; configurable up to 31 days, or 7 days for retained acked messages).BACKWARD for additive Avro/Proto changes — older subscribers can decode newer messages. Stricter modes (FULL, FULL_TRANSITIVE) reject more schema revisions.defer client.Close(), call topic.Stop() to flush pending publishes, and cancel the context passed to Receive for graceful shutdown. Skipping Stop() drops in-flight messages; skipping context cancellation hangs your process.Topic is safe to share across goroutines; a single Receive call is not. One Topic handle per topic, reused — the SDK batches publishes internally. One Receive invocation per subscription handle at a time.| Scenario | Use | Why |
|---|---|---|
| New service consuming events at scale | Pull subscription with StreamingPull (Go SDK default) | Bidirectional flow control, lower latency than push |
| Webhook-style fan-out to existing HTTP service | Push subscription with OIDC auth | No long-lived consumer; Pub/Sub handles retries |
| Stream events directly to a BigQuery table | BigQuery subscription | No subscriber code; built-in schema mapping |
| Archive every message to GCS | Cloud Storage subscription | Same — managed, no subscriber code |
| Need strict per-key ordering | OrderingKey + EnableMessageOrdering=true on both ends | Only ordering guarantee Pub/Sub offers (per-key, not global) |
| Cannot tolerate any duplicates | Exactly-once subscription plus idempotent handler | EOD reduces duplicates; idempotency is still the safety net |
| Bad-message poison pill | Dead-letter topic with MaxDeliveryAttempts (5–100) | After N failed acks, message republished to DLT for triage |
| Replay last N hours after a buggy deploy | Snapshot before deploy, Seek after rollback | Snapshots preserve un-acked state up to 7 days from creation |
| Replay to an exact wall-clock timestamp | Seek(time.Time) on a subscription with retention covering that point | Cheaper than snapshots when you only need a timestamp restore |
| Filter messages without subscriber-side discard | Subscription filter on attributes (attributes.region = "us") | Filtered messages auto-acked, never delivered, no client cost |
| High-volume publish | Tune PublishSettings.CountThreshold / DelayThreshold / ByteThreshold | Defaults batch only ~100 msgs / 10ms / 1MB; raise for throughput |
| Subscriber OOM under load | Lower MaxOutstandingMessages / MaxOutstandingBytes | Caps in-flight work per Subscription.Receive call |
| Long processing per message (>10 min) | Set MaxExtension higher, or hand off to an external work queue | Lease extension stops at MaxExtension; then redelivery fires |
| Schema evolution on a typed topic | BACKWARD compatibility (default) for additive changes | Old subscribers can read new messages; safest evolution path |
| Want at-most-once semantics | Not supported. Use idempotent handlers + dedup table | Pub/Sub does not offer at-most-once; this is by design |
Example 1: User says "my subscriber processes the same message multiple times even though I'm calling msg.Ack()" Actions:
gcloud pubsub subscriptions describe SUB --format='value(enableExactlyOnceDelivery)'.msg.ID or a business key with a uniqueness constraint. See references/delivery-guarantees.md.Example 2: User says "my push subscription endpoint is getting hammered with retries — error rate is climbing in our logs" Actions:
minimumBackoff, maximumBackoff). Without it, Pub/Sub retries aggressively.MaxDeliveryAttempts so a poison message can't loop forever. Confirm IAM bindings (publisher role on DLT, subscriber role on source).Example 3: User says "publish throughput is much lower than expected — I'm only getting a few hundred messages per second" Actions:
PublishSettings. The defaults batch only ~100 messages or 10ms — raise CountThreshold to 1000+, DelayThreshold to 50–100ms, ByteThreshold to 5–10 MiB. See references/publishing.md.Topic.Publish results are Get()-ed on a worker goroutine, not synchronously after each publish. Synchronous Get() defeats batching.Topic.Stop() is called on shutdown so the final batch flushes. See references/go-client.md.
Result: Throughput rises to the per-region quota ceiling because batching now amortizes RPC overhead across many messages.| Symptom | Reference |
|---|---|
Schema enforcement rejects a publish; need to evolve a Proto/Avro schema; topic retention questions; RetainAckedMessages behavior | references/topics-and-schemas.md |
| Choosing pull vs push vs BigQuery vs GCS; subscription filters not matching; push endpoint 500s; ack deadline tuning; expiration policy | references/subscriptions.md |
Publish throughput plateau; ordering-key publish blocked after error; PublishResult.Get hanging; messages lost on shutdown | references/publishing.md |
Subscriber OOM; flow-control tuning; "lease expired" / redelivery despite Ack; Receive not exiting; concurrent Receive calls | references/subscribing.md |
| Duplicate processing despite Ack; ordering guarantees questions; exactly-once vs at-least-once choice; dedup window | references/delivery-guarantees.md |
Session/goroutine leaks; Topic.Stop vs Client.Close ordering; Receive callback contract; OpenTelemetry tracing | references/go-client.md |
Quotas hit; backlog growth alarm; setting up DLT with IAM; Seek/snapshot recipes; cost surprises from retention | references/operations.md |
RetainAckedMessages, Avro/Protobuf schemas, schema revisions, compatibility modes, encoding, schema evolution playbookPublishSettings (count/byte/delay thresholds, buffer limits, timeouts), publisher flow control, PublishResult.Get, ordering keys and ResumePublish, attributes vs body, shutdownSubscription.Receive semantics, ReceiveSettings (max outstanding, NumGoroutines, MaxExtension), ack/nack discipline, lease internals, graceful shutdowncloud.google.com/go/pubsub: Client lifecycle, Topic/Subscription handles, callback contract, shutdown order, error wrapping, OpenTelemetry, common pitfallsoldest_unacked_message_age, num_undelivered_messages), DLT setup with IAM, retry policy, Seek and snapshots, capacity planning, cost leversAll recommendations trace back to Google's official documentation. When recommending a specific syntax or limit, prefer fetching the live page over relying on this skill's cached digest: