Mastering HTTP Timeouts and Retry Strategies with Feign & Ribbon in Spring Cloud
This article explains how to configure connection and read timeouts for HTTP calls in Spring Cloud, compares Feign and Ribbon settings, reveals common pitfalls such as overly long timeouts and automatic retries, and provides practical solutions for improving concurrency and preventing duplicate requests in Java microservices.
Why HTTP timeouts matter
HTTP calls can hang or fail because of network latency, server overload, or mis‑configured client settings. Proper timeout configuration prevents threads from being blocked indefinitely and makes downstream problems visible early.
Choosing an HTTP client framework
Spring Cloud full stack – use Feign for declarative service calls.
Spring Boot only – use Apache HttpClient directly.
Connection and read timeout parameters
Both the TCP layer and the HTTP client expose two key timeout settings:
ConnectTimeout – maximum time to establish a TCP connection.
ReadTimeout – maximum time to wait for data after the connection is established.
Common pitfalls
Overly long connection timeout – a value of dozens of seconds is unnecessary; TCP handshakes complete in milliseconds. A range of 1–5 s is typical, and for internal calls an even shorter timeout can be used to fail fast.
Load‑balancer hides the real endpoint – when a client talks to Nginx or another proxy, the timeout may be caused by the balancer, not the target service. Verify the actual endpoint.
Read timeout does not mean server stopped processing – it only indicates that the client did not receive a response within the configured period. The server may still be executing business logic.
Best practices for timeout configuration
Configure both ConnectTimeout and ReadTimeout to values that reflect service‑level agreements (SLAs). For synchronous user‑facing calls keep the read timeout below 30 s to avoid thread‑pool exhaustion.
Feign and Ribbon timeout configuration
Global timeout settings
feign.client.config.default.connectTimeout=3000
feign.client.config.default.readTimeout=3000Both properties must be present; otherwise the values are ignored.
Per‑client overrides
feign.client.config.clientsdk.connectTimeout=2000
feign.client.config.clientsdk.readTimeout=2000Individual client settings override the global defaults.
Priority between Feign and Ribbon
When both Feign and Ribbon define timeouts, Feign’s settings win because LoadBalancerFeignClient creates a FeignOptionsClientConfig that overrides Ribbon’s DefaultClientConfigImpl.
clientsdk.ribbon.listOfServers=localhost:45678
feign.client.config.default.connectTimeout=3000
feign.client.config.default.readTimeout=3000
ribbon.ConnectTimeout=4000
ribbon.ReadTimeout=4000The logs show the 3 s Feign timeout taking effect.
Ribbon automatic retries
Ribbon’s MaxAutoRetriesNextServer defaults to 1, causing a second attempt on another server node after a read timeout. This can produce duplicate actions for non‑idempotent APIs (e.g., SMS sending). ribbon.MaxAutoRetriesNextServer=0 Set the value to 0 to disable automatic retries.
Concurrent HTTP calls in high‑throughput crawlers
The default PoolingHttpClientConnectionManager limits are defaultMaxPerRoute=2 (max concurrent connections per host) and maxTotal=20 (overall max connections). With 10 parallel requests the effective concurrency is limited to 2 per host, causing a total latency of about 5 s.
Custom HttpClient configuration
HttpClientBuilder builder = HttpClients.custom();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setDefaultMaxPerRoute(50);
cm.setMaxTotal(100);
builder.setConnectionManager(cm);
CloseableHttpClient client = builder.build();Increasing the limits reduces the execution time for 10 concurrent calls to roughly 1 s.
Key takeaways
Set both connection and read timeouts to realistic values; avoid excessively long timeouts.
When using Feign, configure ConnectTimeout together with ReadTimeout to make the settings effective.
Disable Ribbon’s automatic retries for non‑idempotent APIs or switch the API to POST.
Adjust HttpClient’s per‑host ( defaultMaxPerRoute) and total ( maxTotal) connection limits for high‑concurrency scenarios such as web crawlers.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
JavaEdge
First‑line development experience at multiple leading tech firms; now a software architect at a Shanghai state‑owned enterprise and founder of Programming Yanxuan. Nearly 300k followers online; expertise in distributed system design, AIGC application development, and quantitative finance investing.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
