A load-balanced retry can select another instance, but a lost response cannot tell the caller whether a write committed.
Spring Cloud client retries: distinguish a safe read from an uncertain write
Classify before replay
A GET of an immutable receipt version can normally be retried after a connection failure within a caller deadline. A POST reserving seven units cannot be replayed merely because its response timed out: the first instance may already have committed. Carry a tenant-scoped idempotency key, persist the request fingerprint and outcome, then test a timeout after commit. The loopback timeout fixture proves that this ambiguity is real even without service discovery.
Budget the whole call
Choose a maximum number of attempts and a total deadline, including discovery, connect, read and backoff time. Separate overload from transient reachability; retrying a saturated service can amplify its queue. Spring Cloud LoadBalancer exposes retry settings, but this source kit does not install it, so the values below express a policy to test in a Cloud-enabled application rather than a verified deployment setting.
Boundary sketch
spring.cloud.loadbalancer.retry.enabled=true
spring.cloud.loadbalancer.retry.max-retries-on-same-service-instance=0
spring.cloud.loadbalancer.retry.max-retries-on-next-service-instance=1
spring.cloud.loadbalancer.retry.retry-on-all-operations=falseCost and verification
With two attempts, one logical request can consume two upstream slots and nearly double its worst-case service time unless the total deadline cuts it short. This sketch is not executed by the current Spring source kit; verify it against the chosen dependencies and deployment.
Common Mistakes
- Do not infer failure from a missing response to a write.
- Do not add independent retries in the gateway, client and listener without a shared budget.
- Do not assume a second instance makes the operation idempotent.
Read next
Spring HTTP retries: only replay a command with a defined identity, Spring POST idempotency keys: bind replay to tenant and command, Spring Cloud discovery: a service name locates an instance, not a trusted peer, Spring Cloud Circuit Breaker: make fallback obey the original data contract.
