Back to all use cases

SupportFinancial Services / Payments

Every slowdown made the next one worse

Digital Wallet Provider

Subscribers on GKE fell behind, Pub/Sub redelivered messages they were still working on, and members received duplicate notifications. AceMQ found the gap between the ack deadline and the handler.

Overview

A digital wallet provider published transaction events to Google Cloud Pub/Sub for a notification service running on GKE. During busy hours the oldest unacknowledged message age climbed, the pods looked healthy on every dashboard, and members began to receive the same notification more than once.

Challenge

The notification handler called a fraud-scoring service whose latency rose under load, so processing took longer than the subscription's ack deadline. Pub/Sub treated those messages as undelivered and sent them again while the first attempt was still running, which doubled the work and slowed the handler further. The Java subscribers had no flow control, so each pod pulled far more messages than its threads could work and the client could not extend the deadlines in time.

Environment

A Pub/Sub topic and pull subscription consumed by Java subscribers on GKE, with a PostgreSQL database for notification state and an internal fraud-scoring service called in the handler.

Approach

AceMQ ran three live sessions with the customer's engineers. The first compared expired ack deadlines, oldest unacked message age and handler p99 over a busy week. The second reproduced the spiral in staging with a slowed dependency. The third made the changes one at a time, so each could be measured.

Solution

  1. Matched the subscription ack deadline to the measured p99 of the handler, and left the client library's deadline extension to cover the tail
  2. Set flow control on the subscriber to a maximum number of outstanding messages and bytes that its worker threads could actually process
  3. Added a short timeout and a circuit breaker on the fraud-scoring call, so a slow dependency fails a message quickly instead of holding a thread
  4. Recorded each notification against the message ID in PostgreSQL, so a redelivery is recognised and acknowledged without sending again
  5. Set an exponential backoff retry policy and a dead-letter topic with a defined maximum delivery attempts
  6. Alarmed on expired ack deadlines, oldest unacked message age and undelivered message count, with a short runbook for each

Outcome

Backlog during busy hours now drains instead of feeding itself. Duplicate notifications stopped, because a redelivery is recognised before anything is sent, and the on-call engineer sees expired ack deadlines rising before members do.

Technologies

Google Cloud Pub/SubKubernetesJavaPostgreSQL

Need Expert Google Cloud Pub/Sub Support?

AceMQ's senior Google Cloud Pub/Sub engineers have handled this exact type of engagement before. Whether you need architectural guidance, hands-on remediation, or an ongoing managed partnership, we're ready to help.