Timeouts & Connection Configuration
By default an AWS SDK will wait a long time for a slow endpoint. In a request path, that patience turns one slow dependency into a pile of stuck threads or event-loop tasks.
Busca en todas las páginas de la documentación
By default an AWS SDK will wait a long time for a slow endpoint. In a request path, that patience turns one slow dependency into a pile of stuck threads or event-loop tasks.
This page shows how to set connect and read timeouts and tune the HTTP connection pool in both SDKs, so calls fail fast and the client scales under load.
There are two timeouts that matter most.
The connect timeout bounds how long to wait for the TCP (and TLS) connection to establish. The read timeout (also called socket timeout) bounds how long to wait for bytes once connected.
# --- Python (boto3) ---
import boto3
from botocore.config import Config
cfg = Config(
connect_timeout=3, # seconds to establish the connection
read_timeout=10, # seconds to wait for a response
)
s3 = boto3.client("s3", region_name="us-east-1", config=cfg)// --- TypeScript (AWS SDK v3) ---
import { S3Client } from "@aws-sdk/client-s3";
import { NodeHttpHandler } from "@smithy/node-http-handler";
const s3 = new S3Client({
region: "us-east-1",
requestHandler: new NodeHttpHandler({
connectionTimeout: 3000, // ms to establish the connection
requestTimeout: 10000, // ms to wait for a response
}),
});boto3 uses seconds on Config; SDK v3 uses milliseconds on NodeHttpHandler. Both replace the long defaults with values you control.
For a request-path service call, pair tight timeouts with a bounded retry count so the worst-case latency is predictable.
Here the per-attempt read timeout is 10 seconds and the SDK makes at most 3 attempts, so the ceiling is roughly 30 seconds plus backoff, not unbounded.
# --- Python (boto3) ---
import boto3
from botocore.config import Config
cfg = Config(
connect_timeout=3,
read_timeout=10,
retries={"max_attempts": 3, "mode": "standard"},
max_pool_connections=50, # concurrency for this client
)
ddb = boto3.client("dynamodb", region_name="us-east-1", config=cfg)
item = ddb.get_item(TableName="Sessions", Key={"id": {"S": "s-1"}})
print(item.get("Item"))// --- TypeScript (AWS SDK v3) ---
import { DynamoDBClient, GetItemCommand } from "@aws-sdk/client-dynamodb";
import { NodeHttpHandler } from "@smithy/node-http-handler";
import { Agent } from "node:https";
const ddb = new DynamoDBClient({
region: "us-east-1",
maxAttempts: 3,
requestHandler: new NodeHttpHandler({
connectionTimeout: 3000,
requestTimeout: 10000,
httpsAgent: new Agent({ maxSockets: 50 }), // concurrency for this client
}),
});
const out = await ddb.send(new GetItemCommand({ TableName: "Sessions", Key: { id: { S: "s-1" } } }));
console.log(out.Item);The pool size and the retry count are as important as the timeouts. Together they bound both latency and resource use.
Connect timeout catches an unreachable or overloaded endpoint quickly, before any data flows. A small value like 1 to 3 seconds is usually right, because a healthy connection establishes in well under a second.
Read timeout catches a connection that opened but then stalls. Size it to the operation: a DynamoDB GetItem should return in milliseconds, while a large S3 upload legitimately takes longer.
Setting both explicitly is the point. The defaults are long enough to mask real failures during an incident.
Each client keeps a pool of reusable HTTPS connections. Reusing a warm connection skips the TCP and TLS handshake, which is a large latency win.
If concurrency exceeds the pool size, extra requests queue for a free connection, adding hidden latency that looks like a slow service. Size the pool (max_pool_connections in boto3, maxSockets on the Node agent in SDK v3) to your expected concurrent in-flight calls.
| Setting | boto3 | SDK v3 |
|---|---|---|
| Connect timeout | connect_timeout (s) | connectionTimeout (ms) |
| Read/socket timeout | read_timeout (s) | requestTimeout (ms) |
| Pool size | max_pool_connections | maxSockets on the agent |
| Max attempts | retries={"max_attempts": n} | maxAttempts: n |
Total wall-clock time is per-attempt timeout multiplied by attempts, plus backoff between them.
A 30-second read timeout with 4 attempts can mean two minutes of waiting on a persistently slow endpoint. Shorter per-attempt timeouts with a sane attempt count usually beat one long timeout, because the client can back off and retry rather than block.
In Lambda, keep client timeouts well under the function timeout, so the SDK gives up and lets your code handle the failure before the platform kills the function.
Initialize the client outside the handler so its connection pool survives across warm invocations, avoiding a fresh handshake on every request.
NodeHttpHandler or a different botocore session) gives finer control when the standard knobs are not enough.For most services the built-in timeout and pool settings are sufficient; reach for these only when you have a specific need.
Connect timeout bounds establishing the connection; read (socket) timeout bounds waiting for data once connected. They catch different failure modes.
On a botocore.config.Config object via connect_timeout and read_timeout (in seconds), passed as the client's config.
On a NodeHttpHandler from @smithy/node-http-handler, using connectionTimeout and requestTimeout in milliseconds, passed as requestHandler.
boto3 uses seconds and SDK v3 uses milliseconds. A boto3 read_timeout=10 equals SDK v3 requestTimeout: 10000.
Size it to your expected concurrent in-flight requests per client. Too small and requests queue; too large wastes memory and file descriptors.
Total time is roughly the per-attempt timeout times the number of attempts, plus backoff. Account for both when setting a latency budget.
Set client timeouts below the function timeout so the SDK fails and your code reacts before the platform kills the function.
No, raise it. Large uploads and downloads legitimately take longer, so give them a read timeout that matches the transfer size.
Yes. A new client starts with a cold connection pool, forcing a fresh handshake. Reuse one client so warm connections are reused.
In SDK v3, yes, using an AbortController's signal on the send call. That cancels one request independently of the configured timeout.
Stack versions: This page was written for boto3 1.43.x (Python 3.10+) and the AWS SDK for JavaScript v3 (Node.js 18+).
Revisado por Chris St. John·Última actualización: 23 jul 2026