I'm using Spring WebClient in my Java application to authenticate with Keycloak. The issue I'm facing is:
The first WebClient request takes a long time (5-9 seconds), but all subsequent requests are extremely fast.
This slowdown happens consistently everyday when I try to access the application for the first time.
Here’s my WebClient configuration:
@Configuration
public class WebClientConfig {
@Bean
public WebClient webClient() {
return WebClient.builder()
.codecs(configurer ->
configurer.defaultCodecs().maxInMemorySize(5 * 1024 * 1024) // 5MB limit
)
.build();
}
}
And here is the login method making the Keycloak token call:
@Override
public LoginResponseDto login(LoginRequestDto loginRequestDto) {
LinkedMultiValueMap formData = getLoginFormDataRequest(loginRequestDto);
String uri = UriComponentsBuilder.fromUriString(keycloakProperties.serverUrl())
.pathSegment("realms", keycloakProperties.realm(), "protocol", "openid-connect", "token")
.toUriString();
try {
String response = webClient.post()
.uri(uri)
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.bodyValue(formData)
.retrieve()
.bodyToMono(String.class)
.block();
JsonNode jsonNode = objectMapper.readTree(response);
return new LoginResponseDto(
jsonNode.get("token_type").asText(),
jsonNode.get("access_token").asText(),
jsonNode.get("refresh_token").asText(),
jsonNode.get("expires_in").asText(),
jsonNode.get("refresh_expires_in").asText()
);
} catch (WebClientResponseException e) {
log.error("Error in Keycloak login: {}", e.getMessage(), e);
if (e.getStatusCode() == HttpStatus.UNAUTHORIZED) {
throw new InvalidCredentialsException("Invalid username or password", projectUtil.getCurrentUtcTimestamp());
}
throw new KeycloakServiceException("Invalid password", projectUtil.getCurrentUtcTimestamp());
} catch (JsonProcessingException e) {
log.error("JsonProcessing error in Keycloak login: {}", e.getMessage(), e);
throw new KeycloakServiceException("JSON processing error: login", projectUtil.getCurrentUtcTimestamp());
}
}
What I’ve observed:
It only happens for the very first request after startup.
Could be related to connection pool initialization, DNS lookup, SSL handshake, or WebClient configuration.
Using block() — but I need blocking here since this method must return synchronously.
Why does the first WebClient request take significantly longer than subsequent ones, and how can I prevent or reduce this startup delay?
Any insights, profiling tips, or config improvements would be very helpful.