Skip to content

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:

java
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

This comprehensive approach works for both basic timeouts and advanced configurations like SSL bundles:

Basic Timeout Configuration

java
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+)

java
@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

  1. Default Timeout Values:

    java
    // Recommended production values
    Duration.ofSeconds(5)  // Connection timeout
    Duration.ofSeconds(30) // Read timeout
  2. Dependency Considerations:

    • Apache HTTP Client: Automatic detection when httpclient5 is present
    • JDK Client: Default fallback without additional dependencies
  3. SSL Integration Principle:

Configure timeouts consistently across your services to prevent cascading failures. Test timeout behavior using tools like httpstat or timeout test endpoints.