The SDK provides two client classes: OpenAI() for synchronous code and AsyncOpenAI() for async/await patterns.
Async Client
Key config options: timeout (default 600s), max_retries (default 2), base_url (for proxies/Azure), organization, project. You can override per-request with client.with_options(max_retries=5, timeout=120.0).
Why one client per process
Each call to OpenAI() constructs an httpx client underneath. httpx clients hold a connection pool. Constructing per-call means creating and tearing down a connection pool on every request — TLS handshake every time, no keep-alive, no pooling benefit. Under load, this manifests as inexplicable latency tail and connection-cap warnings.
The fix is one line: build the client at app startup, store it on a module-level variable or DI container, reuse forever. Per-call with_options() overrides give you per-request tuning without rebuilding the pool.