This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
backendcritical PriorityID: python-httpx-async-connection-pooling

Python HTTPX Async Client Lifecycles & TCP Pool Exhaustion Defense

Production networking standard for Python async microservices using HTTPX. Mandates reusing a single shared httpx.AsyncClient singleton across request lifecycles, configuring explicit connection pool limits (limits=httpx.Limits(max_keepalive_connections=20)), and strictly prohibits instantiating new clients inside function bodies.

Prohibited Anti-Pattern: AI creates a new `async with httpx.AsyncClient() as client` inside every API request, causing TCP socket exhaustion (TIME_WAIT state) under load.

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Python HTTPX Async Client Lifecycles & TCP Pool Exhaustion Defense - Production networking standard for Python async microservices using HTTPX. Mandates reusing a single shared httpx.AsyncClient singleton across request lifecycles, configuring explicit connection pool limits (limits=httpx.Limits(max_keepalive_connections=20)), and strictly prohibits instantiating new clients inside function bodies.
globs: **/client/**/*.py, **/services/**/*.py, **/api/**/*.py
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/python-httpx-async-connection-pooling"
---

# Python HTTPX Async Client Lifecycles & TCP Pool Exhaustion Defense

> **Severity**: CRITICAL | **Category**: backend
> **Anti-Pattern Warning**: AI creates a new `async with httpx.AsyncClient() as client` inside every API request, causing TCP socket exhaustion (TIME_WAIT state) under load.

## System Constraints
You are a Python High-Performance Networking Specialist. NEVER instantiate httpx.AsyncClient() inside individual function bodies or route handlers. Re-creating HTTP clients forces a new TCP handshake and TLS negotiation for every request, rapidly exhausting system file descriptors. Always maintain a shared, long-lived client with explicit connection pooling limits.

## Strict Guidelines
- MUST reuse a shared httpx.AsyncClient instance across the entire application lifetime.
- MUST NOT instantiate async with httpx.AsyncClient() inside endpoint handlers or utility functions.
- MUST configure explicit connection pool limits: httpx.Limits(max_connections=100, max_keepalive_connections=20).
- MUST configure explicit timeout budgets: httpx.Timeout(10.0, connect=3.0).
- MUST close the client in the application lifespan teardown handler (await client.aclose()).

## Bad vs Good Implementations
### Shared Persistent HTTPX Client vs Ephemeral Client Anti-Pattern

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Creating a new AsyncClient on every request tears down connections immediately. Sockets linger in TIME_WAIT for 60 seconds, quickly exhausting Linux ephemeral ports under moderate concurrency.
```python
# FATAL: Ephemeral client created per request causes socket exhaustion
import httpx

async def fetch_user_data(user_id: str):
  # CRITICAL ANTI-PATTERN: Opens new TCP socket and performs TLS handshake on EVERY call!
  # Under 500 req/sec, the server runs out of ephemeral ports (OSError: [Errno 99] Cannot assign address)
  async with httpx.AsyncClient() as client:
    response = await client.get(f"https://service.internal/users/{user_id}")
    return response.json()
```

#### Production Standard (Correct)
> **Standard**: Reuses a persistent connection pool with keep-alive connections, reducing request latency by eliminating TLS handshakes and protecting OS network sockets from exhaustion.
```python
# Singleton long-lived HTTPX Client with pooled keep-alive connections
import httpx
from typing import Optional

_http_client: Optional[httpx.AsyncClient] = None

def get_http_client() -> httpx.AsyncClient:
    global _http_client
    if _http_client is None or _http_client.is_closed:
        _http_client = httpx.AsyncClient(
            limits=httpx.Limits(max_connections=150, max_keepalive_connections=30),
            timeout=httpx.Timeout(10.0, connect=2.0),
            headers={"User-Agent": "ProductionService/1.0"}
        )
    return _http_client

async def fetch_user_data(user_id: str):
    client = get_http_client()
    # Reuses existing warm TCP + TLS connection (0ms handshake delay)
    response = await client.get(f"https://service.internal/users/{user_id}")
    return response.json()
```

Recommended MCP Servers (mcp-serverlist.com)

Equip agent with system tools to verify code for this stack.

Recommended Agent Skills (askills.dev)

Ready-to-use executable skill functions tailored to this stack.

Architectural Specification & Invariant Rationale

Architectural Invariant Design: Python HTTPX Async Client Lifecycles & TCP Pool Exhaustion Defense

Python HTTPX Async Client Lifecycles & TCP Pool Exhaustion Defense defines an industrial-grade behavioral standard for backend engineering. Production networking standard for Python async microservices using HTTPX. Mandates reusing a single shared httpx.AsyncClient singleton across request lifecycles, configuring explicit connection pool limits (limits=httpx.Limits(max_keepalive_connections=20)), and strictly prohibits instantiating new clients inside function bodies. Modern software architectures require strict adherence to deterministic patterns to guarantee high availability, maintainability, and zero security vulnerabilities.

Framework Paradigm Shift & Drift MechanicsLLMs are trained on millions of open-source repositories containing outdated code, legacy idioms, and unpatched antipatterns. When coding assistants generate implementations for this stack, they default to common statistical tokens: AI creates a new `async with httpx.AsyncClient() as client` inside every API request, causing TCP socket exhaustion (TIME_WAIT state) under load. Without an explicit system instruction file, developers spend hours debugging silent failures.
Failure Modes & Production Blast Radius

Hazard Analysis: What Breaks Without This Rule

The following failure modes have been cataloged from hundreds of hours of production code reviews where AI assistants produced non-compliant implementations:

Failure ModeAI Symptom (The Anti-Pattern)SeverityProduction Impact & Remedy
AI Hallucination & Deprecation DriftAI creates a new `async with httpx.AsyncClient() as client` inside every API request, causing TCP socket exhaustion (TIME_WAIT state) under load.Critical
Violating this industrial standard introduces regression bugs, security risks, and unexpected runtime failures in production.
Enforce explicit behavioral system directives across all AI coding assistants in your repository.
Silent Architecture InconsistencyAI assistants produce mixed paradigms across files, creating fragmented codebase conventions.Medium
Increases cognitive load during code reviews and leads to maintenance debt across engineering teams.
Pin project conventions in .cursor/rules, CLAUDE.md, and AGENTS.md so all team agents follow identical guardrails.
Architectural Directives in Detail

Step-by-Step Production Directives

Each rule constraint below is injected into the AI agent's system prompt to establish deterministic boundaries:

1

MUST reuse a shared httpx.AsyncClient instance across the entire application lifetime.

MUST reuse a shared httpx.AsyncClient instance across the entire application lifetime.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
2

MUST NOT instantiate async with httpx.AsyncClient() inside endpoint handlers or utility functions.

MUST NOT instantiate async with httpx.AsyncClient() inside endpoint handlers or utility functions.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
3

MUST configure explicit connection pool limits

MUST configure explicit connection pool limits: httpx.Limits(max_connections=100, max_keepalive_connections=20).

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
4

MUST configure explicit timeout budgets

MUST configure explicit timeout budgets: httpx.Timeout(10.0, connect=3.0).

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
5

MUST close the client in the application lifespan teardown handler (await client.aclose()).

MUST close the client in the application lifespan teardown handler (await client.aclose()).

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
Technical Questions & Answers

Frequently Asked Technical Questions

Common questions developers face when configuring AI coding assistants for this stack:

Q:Why is Python HTTPX Async Client Lifecycles & TCP Pool Exhaustion Defense critical for AI coding assistants?

Production networking standard for Python async microservices using HTTPX. Mandates reusing a single shared httpx.AsyncClient singleton across request lifecycles, configuring explicit connection pool limits (limits=httpx.Limits(max_keepalive_connections=20)), and strictly prohibits instantiating new clients inside function bodies. Without explicit behavioral boundaries, AI coding assistants (Cursor, Claude Code, Windsurf, Codex) rely on training data averages, which frequently produce deprecated, inefficient, or vulnerable code patterns.

Q:How does adopting this rule prevent AI hallucinations?

This rule explicitly declares what the AI must avoid (AI creates a new `async with httpx.AsyncClient() as client` inside every API request, causing TCP socket exhaustion (TIME_WAIT state) under load.) and prescribes verified positive examples. Grounding the LLM with negative and positive pairs eliminates guesswork.

Q:Which AI coding environments are supported?

This specification is multi-platform compatible: Cursor (.cursor/rules/*.mdc & .cursorrules), Anthropic Claude Code (CLAUDE.md), Windsurf (.windsurfrules), Codex / Cline (AGENTS.md), and GitHub Copilot (.github/copilot-instructions.md).

Q:Can I combine this rule with other technology stacks?

Yes. Use the Interactive Stack Builder or download an Agent Pack to merge this rule with other frontend, backend, database, security, and DevOps rules without syntax collision.

Open Specification · CC BY 4.0·Free for Personal, Team & Commercial In-Repo Use

Citation & Open Source Attribution Guidelines

This specification is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). You are completely free to adapt and share this rule in your workspace. If citing, including in public AI benchmark datasets, or redistributing, attribution to AgentRules.org is required.

1 Rule in Stack

Python