Create a subscription with a pull or push delivery type; set ackDeadlineSeconds to slightly longer than your worst-case processing time (maximum is 600 seconds)
When pulling, use the streaming pull client (StreamingPull RPC) rather than synchronous pull for throughput; acknowledge each message by message ID before the ack deadline expires
Extend the ack deadline mid-processing by calling ModifyAckDeadline if processing may exceed the initial deadline; most client libraries do this automatically when auto-ack extension is enabled
Configure a dead-letter topic on the subscription by setting deadLetterPolicy.deadLetterTopic to a separate topic and deadLetterPolicy.maxDeliveryAttempts (5–100); failed messages are forwarded after that many unacknowledged deliveries
Grant the Pub/Sub service account the roles/pubsub.publisher role on the dead-letter topic and roles/pubsub.subscriber on the original subscription so the service can forward and nack messages automatically
Monitor the subscription/oldest_unacked_message_age and subscription/dead_letter_message_count Cloud Monitoring metrics to detect processing lag and DLQ build-up
Known gotchas
Pub/Sub guarantees at-least-once delivery, not exactly-once — design your consumer to be idempotent using message IDs or a deduplication store
The ack deadline clock restarts from the moment the message is delivered, not from when it was published; if your consumer is slow to start processing, the deadline can expire before work begins
Dead-letter forwarding itself requires the Pub/Sub service agent to have publish rights on the DLT — forgetting this IAM binding causes silent message loss rather than an obvious error
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp