Java SDK Connection Pooling for Agent Desktop

Quick question about the Genesys Cloud Java SDK.

Context:
We are building an Angular agent desktop using the GC Premium App framework. The backend Java service uses genesyscloud-java-rest-client. Under load, we see ConnectionPoolTimeoutException despite setting poolSize to 20.

Question:
Is the SDK’s underlying Apache HttpClient configured for thread-safe connection pooling by default? How do we properly override the RequestConfig to ensure keep-alive connections are reused across concurrent WebSocket and REST calls without hitting the default 20-connection limit per route?

This is caused by default connection eviction policies. The SDK uses Apache HttpClient, which does not clean up idle connections automatically. You need to configure an idle connection monitor.

  • Implement ConnectionKeepAliveStrategy in your ApiClient builder.
  • Schedule a PoolingHttpClientConnectionManager closeExpiredConnections task.
  • Verify maxTotal exceeds concurrent worker threads.

This issue stems from the default Apache HttpClient behavior in the SDK, which does not actively evict stale connections from the pool. The suggestion about ConnectionKeepAliveStrategy is correct, but it is only half the solution. You must also implement a background thread to clean up idle connections, or your pool will eventually fill with “zombie” connections that timeout on the next request.

In Azure Functions or high-concurrency Java services, I recommend configuring the PoolingHttpClientConnectionManager with a dedicated eviction timer. Here is how I structure the client builder in .NET, and the equivalent Java logic is identical in principle.

// Configure the connection manager with max total and per-route limits
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
connManager.setMaxTotal(100);
connManager.setDefaultMaxPerRoute(20);

// Set up the connection manager with a custom TTL strategy if needed
CloseableHttpClient httpClient = HttpClients.custom()
 .setConnectionManager(connManager)
 .evictIdleConnections(30, TimeUnit.SECONDS) // Key: Evict idle connections
 .evictExpiredConnections()
 .build();

// Inject into Genesys SDK
PlatformClient platformClient = new PlatformClient(httpClient);

The critical part is evictIdleConnections. Without this, the SDK holds onto connections that the server may have already closed, leading to ConnectionPoolTimeoutException when the pool appears full but has no usable sockets.

I also suggest checking your thread pool size in your Java application. If your application uses a fixed thread pool of 50 threads, but your maxTotal is 20, you will still block. Ensure maxTotal is at least 1.5x your expected concurrent thread count.

Have you verified the actual active connection count in your logs? If the pool is healthy but requests are still failing, it might be a DNS resolution bottleneck or a proxy timeout issue, not the pool itself.

You need to address the connection lifecycle management directly, as the SDK’s default Apache HttpClient configuration often leads to resource exhaustion under high concurrency. The previous suggestions regarding eviction are correct but incomplete without explicit pool tuning.

  • Configure PoolingHttpClientConnectionManager with explicit setMaxTotal and setDefaultMaxPerRoute values that exceed your expected concurrent worker threads.
  • Implement a ConnectionKeepAliveStrategy to respect the keep-alive headers from the Genesys Cloud API, preventing premature closure.
  • Schedule a background thread to evict idle connections every 30 seconds. This prevents “zombie” connections from consuming pool slots.
  • Ensure your ApiClient is a singleton. Instantiating it per request destroys the pool benefit entirely.
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
connManager.setMaxTotal(100);
connManager.setDefaultMaxPerRoute(20);
// Schedule eviction task
scheduler.scheduleAtFixedRate(connManager::closeExpiredConnections, 0, 30, TimeUnit.SECONDS);

Failure to implement the eviction thread will cause timeouts regardless of your poolSize setting.

connectionManager.closeIdleConnections(30, TimeUnit.SECONDS);

The suggestion above covers eviction, but you must explicitly close idle connections to prevent pool exhaustion.

ConnectionPoolTimeoutException: Timeout waiting for connection from pool

I am new to Java SDKs, so I am guessing this applies to the Python SDK too.