How to Manage HTTP Resources and Connection Pooling in the Anthropic Python SDK
The Anthropic Python SDK centralizes HTTP connection management through httpx with default limits of 1,000 concurrent connections and 100 keep-alive sockets, allowing customization via the http_client parameter or environment proxies while providing automatic cleanup mechanisms.
The anthropics/anthropic-sdk-python repository builds its async HTTP layer on top of httpx, offering fine-grained control over connection pooling, timeouts, and proxy configuration. Understanding how to manage HTTP resources and connection pooling in the Anthropic Python SDK ensures efficient API usage without leaking sockets or exhausting file descriptors.
Default HTTP Configuration Constants
The SDK defines its baseline HTTP behavior in src/anthropic/_constants.py. These values are injected automatically when the SDK instantiates its internal httpx.AsyncClient.
- Timeout:
httpx.Timeout(timeout=600.0, connect=5.0)— 10 minutes total request time, 5 seconds to establish a connection. - Connection Limits:
httpx.Limits(max_connections=1000, max_keepalive_connections=100)— up to 1,000 concurrent connections per host, with 100 sockets kept alive for reuse. - Redirect Handling:
follow_redirects=True— automatically follows 3xx responses.
These defaults balance high-throughput scenarios with reasonable resource constraints, preventing connection leaks while maintaining low latency for subsequent requests to the Anthropic API.
The Default Client Architecture
When you instantiate AsyncAnthropic without providing a custom HTTP client, the SDK creates an AsyncHttpxClientWrapper that inherits from DefaultAsyncHttpxClient. This class, defined in src/anthropic/_base_client.py, configures the underlying transport layer with production-ready defaults.
Socket Options and Keep-Alive
The DefaultAsyncHttpxClient applies platform-specific TCP keep-alive settings to prevent idle connections from being silently dropped by the OS. It sets SO_KEEPALIVE and tunes parameters like TCP_KEEPINTVL and TCP_KEEPIDLE to maintain persistent connections efficiently.
Environment Proxy Handling
Before constructing the transport, the SDK parses proxy environment variables using get_environment_proxies() in src/anthropic/_utils/_httpx.py. This function normalizes http_proxy, https_proxy, and no_proxy settings into a mount map. The SDK then explicitly creates AsyncHTTPTransport objects for these proxies and attaches them via the mounts parameter, ensuring explicit control rather than relying on httpx's auto-configuration.
Overriding HTTP Defaults
You can customize connection pooling and timeouts by passing a pre-configured httpx.AsyncClient to the http_client parameter when initializing the Anthropic client.
import httpx
from anthropic import AsyncAnthropic, DefaultAsyncHttpxClient
# Custom limits for a resource-constrained environment
custom_client = DefaultAsyncHttpxClient(
limits=httpx.Limits(max_connections=200, max_keepalive_connections=20),
timeout=httpx.Timeout(30.0, connect=5.0),
)
anthropic_client = AsyncAnthropic(
api_key="sk-...",
http_client=custom_client,
)
Alternatively, pass individual timeout values directly to the constructor, which override the default constants while retaining the standard connection limits.
Managing Client Lifecycle and Resource Cleanup
Proper resource management requires explicitly closing the HTTP connection pool to avoid leaking sockets. The SDK provides two mechanisms for deterministic cleanup.
Explicit Closure
Use the async context manager protocol or call aclose() directly:
client = AsyncAnthropic(api_key="sk-...")
# Context manager ensures closure
async with client:
response = await client.completions.create(...)
# Or manual cleanup
await client.aclose()
Garbage Collection Safety Net
The AsyncHttpxClientWrapper class implements a __del__ method that attempts to schedule a background aclose() if the client is garbage-collected while the event loop is still running. This safety net, implemented in src/anthropic/_base_client.py, prevents resource leaks when you forget to close the client explicitly, though deterministic cleanup remains the recommended pattern.
Practical Implementation Examples
Basic Usage with Default Pooling
Use the SDK's built-in connection pooling for standard use cases:
from anthropic import AsyncAnthropic
async def main():
client = AsyncAnthropic(api_key="YOUR_API_KEY")
completion = await client.completions.create(
model="claude-3-sonnet-20240229",
max_tokens=1024,
prompt="Explain quantum computing."
)
print(completion.completion)
await client.aclose()
Custom Connection Limits for High-Throughput Applications
Reduce connection overhead when running many concurrent requests:
import httpx
from anthropic import AsyncAnthropic, DefaultAsyncHttpxClient
http_client = DefaultAsyncHttpxClient(
limits=httpx.Limits(
max_connections=500,
max_keepalive_connections=50
),
)
client = AsyncAnthropic(
api_key="YOUR_API_KEY",
http_client=http_client,
)
Runtime Proxy Configuration
Inject a specific proxy without relying on environment variables:
import httpx
from anthropic import AsyncAnthropic, DefaultAsyncHttpxClient
proxy_transport = httpx.AsyncHTTPTransport(
proxy="http://proxy.example.com:3128",
verify=True,
)
client = AsyncAnthropic(
api_key="YOUR_API_KEY",
http_client=DefaultAsyncHttpxClient(transport=proxy_transport),
)
Sharing Connection Pools Across Concurrent Tasks
Reuse a single client instance across multiple async workers to maximize connection reuse:
import asyncio
from anthropic import AsyncAnthropic
client = AsyncAnthropic(api_key="YOUR_API_KEY")
async def generate_text(prompt):
return await client.completions.create(
model="claude-3-opus-20240229",
max_tokens=512,
prompt=prompt,
)
async def main():
prompts = ["Write a poem.", "Summarize this article."]
results = await asyncio.gather(*(generate_text(p) for p in prompts))
await client.aclose()
asyncio.run(main())
Summary
- Default Limits: The SDK configures 1,000 max connections and 100 keep-alive sockets via
DEFAULT_CONNECTION_LIMITSinsrc/anthropic/_constants.py. - Automatic Configuration:
DefaultAsyncHttpxClientinsrc/anthropic/_base_client.pyhandles TCP keep-alive, proxy parsing viaget_environment_proxies(), and transport mounting. - Customization: Pass a custom
httpx.AsyncClientto thehttp_clientparameter to override timeouts, limits, or proxy settings. - Resource Cleanup: Always use
async with client:orawait client.aclose()to close connection pools deterministically; the wrapper's__del__provides a fallback safety net.
Frequently Asked Questions
How do I change the default timeout for API requests?
Pass a timeout value (in seconds) directly to the AsyncAnthropic constructor or provide a custom httpx.Timeout object via the http_client parameter. The SDK default is 600 seconds (10 minutes) total with a 5-second connection timeout.
Can I use the same HTTP client for multiple Anthropic client instances?
Yes. You can instantiate a single DefaultAsyncHttpxClient or httpx.AsyncClient and pass it to multiple AsyncAnthropic instances via the http_client parameter. This allows connection pooling across different API clients, though you must ensure proper closure of the shared HTTP client when all Anthropic clients are done.
What happens if I don't close the Anthropic client?
If you omit await client.aclose(), the AsyncHttpxClientWrapper destructor attempts to schedule a background close operation if the event loop is still running. However, this is not guaranteed to execute or complete successfully, potentially leading to socket leaks and resource exhaustion in long-running applications.
Does the SDK support HTTP/2 connection pooling?
The underlying httpx library supports HTTP/2 when configured with http2=True. You can enable this by passing a custom HTTP client: DefaultAsyncHttpxClient(http2=True). The SDK's default configuration uses HTTP/1.1 with keep-alive for maximum compatibility.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →