Spring RestClient Timeout Configuration
When making HTTP requests using Spring's RestClient
(introduced in Spring Framework 6.1), configuring proper connection and read timeouts is critical for application stability. Without explicit timeout settings, unresponsive servers can cause thread exhaustion and application hangs through indefinite blocking calls.
Solutions
1. SimpleClientHttpRequestFactory (JDK-Based Client)
This solution works without additional dependencies using Java's built-in HTTP client:
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestClient;
public RestClient restClient() {
return RestClient.builder()
.requestFactory(getClientHttpRequestFactory())
.build();
}
private ClientHttpRequestFactory getClientHttpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(5000); // 5 seconds connection timeout
factory.setReadTimeout(10000); // 10 seconds read timeout
return factory;
}
- Connect Timeout: Maximum time to establish a connection
- Read Timeout: Maximum time between data packets during response
- Best for: Simple use cases without SSL configuration needs
2. ClientHttpRequestFactorySettings (Recommended Modern Approach)
This comprehensive approach works for both basic timeouts and advanced configurations like SSL bundles:
Basic Timeout Configuration
import java.time.Duration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpRequestFactorySettings;
import org.springframework.http.client.JdkClientHttpRequestFactory;
import org.springframework.web.client.RestClient;
public RestClient restClient() {
ClientHttpRequestFactorySettings settings = ClientHttpRequestFactorySettings.DEFAULTS
.withConnectTimeout(Duration.ofSeconds(5))
.withReadTimeout(Duration.ofSeconds(10));
ClientHttpRequestFactory factory = new JdkClientHttpRequestFactory(settings);
return RestClient.builder()
.requestFactory(factory)
.build();
}
With SSL Bundle (Spring Boot 3.1+)
@Bean
public RestClient restClient(RestClient.Builder builder, SslBundles sslBundles) {
ClientHttpRequestFactorySettings settings = ClientHttpRequestFactorySettings.DEFAULTS
.withConnectTimeout(Duration.ofSeconds(30))
.withReadTimeout(Duration.ofSeconds(30))
.withSslBundle(sslBundles.getBundle("myBundle"));
ClientHttpRequestFactory factory = ClientHttpRequestFactories.get(settings);
return builder
.requestFactory(factory)
.build();
}
Key advantages of this approach:
- Timeouts as
Duration
for cleaner value definitions - Auto-switching client implementation (JDK vs Apache)
- Integrated SSL configuration without overriding timeouts
- Single configuration point for all HTTP settings
IMPORTANT
When using SSL bundles, always apply configurations through ClientHttpRequestFactorySettings
rather than using RestClientSsl
directly to prevent overwriting existing timeout settings.
Implementation Notes
Default Timeout Values:
java// Recommended production values Duration.ofSeconds(5) // Connection timeout Duration.ofSeconds(30) // Read timeout
Dependency Considerations:
- Apache HTTP Client: Automatic detection when
httpclient5
is present - JDK Client: Default fallback without additional dependencies
- Apache HTTP Client: Automatic detection when
SSL Integration Principle:
Configure timeouts consistently across your services to prevent cascading failures. Test timeout behavior using tools like httpstat
or timeout
test endpoints.