Java › Java Networking & HTTP Client
How would you implement retry logic with exponential backoff for HTTP requests made via HttpClient, given the client doesn't provide built-in retry support natively?
AdvancedAnswer
Since HttpClient doesn't include built-in retry logic, implementing resilient retry behavior requires wrapping request execution in your own retry loop (or using a dedicated resilience library like Resilience4j or Failsafe), catching transient failures (specific IOException subtypes, or specific HTTP status codes like 503 Service Unavailable) and retrying with an exponentially increasing delay between attempts (doubling the wait time after each failed attempt, often with added random jitter to avoid many clients retrying in lockstep and overwhelming a recovering server simultaneously), up to a maximum number of attempts before ultimately giving up and propagating the failure.
public <T> HttpResponse<T> sendWithRetry(HttpRequest request, HttpResponse.BodyHandler<T> handler, int maxAttempts) throws Exception {
int attempt = 0;
while (true) {
try {
HttpResponse<T> response = client.send(request, handler);
if (response.statusCode() < 500) return response; // don't retry client errors, only server errors
throw new IOException("Server error: " + response.statusCode());
} catch (IOException e) {
attempt++;
if (attempt >= maxAttempts) throw e;
long delayMs = (long) (Math.pow(2, attempt) * 100); // exponential backoff
Thread.sleep(delayMs);
}
}
}Real-world example A payment processing client retries a failed downstream API call up to three times with exponential backoff (200ms, then 400ms, then 800ms delays) specifically for 5xx server errors and network-level IOExceptions, while deliberately NOT retrying 4xx client errors (like an invalid request), since retrying a genuinely malformed request would just fail identically every time.