ConnectionTimeout versus SocketTimeout
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
ConnectionTimeout and SocketTimeout control two different phases of a network request. ConnectionTimeout limits how long the client waits to establish a TCP connection (the three-way handshake). SocketTimeout limits how long the client waits for data after the connection is already established. Setting them correctly is essential for building services that fail fast on unreachable hosts without dropping requests from slow-but-functioning servers.
Both throw similar exceptions (typically SocketTimeoutException in Java), which makes them easy to confuse. But they protect against completely different failure modes.
What Happens During a Network Request
A typical HTTP request goes through distinct phases, each with its own potential for delay:
ConnectionTimeout covers phase 2 (and sometimes phases 1 and 3 depending on the HTTP client). SocketTimeout covers phases 5 and 6, specifically the gap between receiving data packets.
ConnectionTimeout in Detail
ConnectionTimeout defines the maximum time to wait for the TCP connection to be established. If the remote server is unreachable, overloaded, or firewalled, the TCP handshake stalls and eventually times out.
Java HttpURLConnection
Apache HttpClient 5
OkHttp (Kotlin/Java)
Python Requests
When ConnectionTimeout Fires
A ConnectionTimeout typically indicates one of these problems:
- The server is down or not listening on that port.
- A firewall is silently dropping SYN packets (no RST returned).
- DNS resolved to a wrong or unreachable IP.
- The server's connection backlog is full and it cannot accept new connections.
A reasonable default is 3-5 seconds. If a TCP handshake takes longer than that, the server is likely unreachable and waiting longer rarely helps.
SocketTimeout in Detail
SocketTimeout (also called ReadTimeout in many libraries) defines the maximum time to wait between receiving consecutive data packets after the connection is established. It does not limit the total transfer time. It limits the idle gap.
Key Distinction: Per-Packet, Not Total
This is the most commonly misunderstood aspect. A SocketTimeout of 10 seconds does not mean the entire response must arrive within 10 seconds. It means that if 10 seconds pass without any new data arriving, the read operation times out.
A large response that streams continuously at 1 byte per second will never trigger a 10-second SocketTimeout. But a server that stops sending for 10 seconds will trigger it, even if it has already sent 99% of the response.
When SocketTimeout Fires
A SocketTimeout after connection typically indicates:
- The server is processing the request and taking too long to respond.
- The server started sending a response but stalled mid-stream (garbage collection pause, deadlock, resource exhaustion).
- Network congestion is causing packet loss and retransmission delays.
- The server accepted the connection but is not reading or writing (connection leak on the server side).
Configuration Across Libraries
| Library/Framework | Connection Timeout | Socket/Read Timeout | Write Timeout |
| Java HttpURLConnection | setConnectTimeout(ms) | setReadTimeout(ms) | N/A |
| Apache HttpClient 5 | setConnectTimeout() | setResponseTimeout() | N/A |
| OkHttp | .connectTimeout() | .readTimeout() | .writeTimeout() |
| Python requests | timeout=(connect, read) | timeout=(connect, read) | N/A |
| Go net/http | Transport.DialContext deadline | Client.Timeout (total) | Part of Client.Timeout |
| Node.js (Axios) | N/A (OS default) | timeout (total) | N/A |
| cURL | CURLOPT_CONNECTTIMEOUT | CURLOPT_TIMEOUT (total) | N/A |
Note that some libraries (Go, Axios, cURL) use a total timeout rather than a per-phase timeout. A total timeout limits the entire request lifecycle, which is simpler to reason about but less precise.
Choosing the Right Values
General Guidelines
| Scenario | ConnectionTimeout | SocketTimeout |
| Internal microservice calls | 1-3 seconds | 5-15 seconds |
| External third-party APIs | 3-5 seconds | 15-30 seconds |
| File downloads / large responses | 3-5 seconds | 30-60 seconds |
| Health checks | 1-2 seconds | 2-5 seconds |
| Database connections | 2-5 seconds | 30-60 seconds |
The Relationship Between Timeouts
ConnectionTimeout should almost always be shorter than SocketTimeout. The TCP handshake is a fixed, fast operation. If it takes more than a few seconds, waiting longer is pointless. But once connected, the server may legitimately need more time to process a complex query, compile a report, or stream a large dataset.
Retry Strategy and Timeout Interaction
Timeouts and retries interact in important ways. A ConnectionTimeout failure is usually safe to retry immediately on a different server instance (the request was never received). A SocketTimeout failure is more dangerous to retry because the server may have already started processing the request.
For non-idempotent operations (POST, PUT), retrying after a SocketTimeout risks duplicate processing. Use idempotency keys or check the operation status before retrying.
Connection Pool Timeout
Many HTTP client libraries add a third timeout: the time to acquire a connection from the connection pool. This is separate from ConnectionTimeout (which is about TCP) and SocketTimeout (which is about data):
If all connections in the pool are in use and a new request arrives, it waits up to connectionRequestTimeout for a connection to become available. This timeout firing usually means the pool is undersized or downstream services are slow.
Common Pitfalls
- Setting the same value for both timeouts. ConnectionTimeout should be much shorter than SocketTimeout. A 30-second connection timeout wastes time waiting for unreachable hosts.
- Using zero or no timeout. A missing timeout means the client will wait indefinitely. In a server handling concurrent requests, one stuck downstream call can exhaust the thread pool and cascade into a full outage.
- Confusing SocketTimeout with a total request timeout. SocketTimeout resets with every packet received. A slow but continuously streaming response will not trigger it, even if the total transfer takes minutes.
- Retrying non-idempotent requests after a SocketTimeout. The server may have already processed the request. The timeout only means the client did not receive the response, not that the server did not act on it.
- Ignoring connection pool timeout. Under load, requests may time out waiting for a connection from the pool, not waiting for the network. The symptoms look similar but the fix (increase pool size or reduce downstream latency) is different.
- Not logging which timeout fired. Both throw
SocketTimeoutExceptionin Java. Log the phase (connect vs. read) so you can distinguish "server unreachable" from "server too slow" in production.
Summary
- ConnectionTimeout limits the TCP handshake duration. Set it to 1-5 seconds. Failures indicate the server is unreachable.
- SocketTimeout limits the idle gap between data packets after connection. Set it based on expected server processing time. Failures indicate the server is slow or stalled.
- ConnectionTimeout should always be shorter than SocketTimeout.
- Never use zero or unlimited timeouts in production. Every outbound network call should have both timeouts configured.
- Retry ConnectionTimeout failures freely. Retry SocketTimeout failures only for idempotent operations.
- Log which timeout fired so you can distinguish network reachability problems from server performance problems.

