Why httpx for Proxy Work
httpx occupies a unique position in the Python HTTP ecosystem as the only major library offering both synchronous and asynchronous interfaces through a single, consistent API. This dual-mode design makes it the ideal choice when your proxy project starts as a simple script but needs to scale into a high-concurrency pipeline later. You write proxy configuration once, and it works identically whether you use `httpx.Client` or `httpx.AsyncClient`. The library was designed by Tom Christie, creator of Django REST Framework, and its API reflects years of lessons learned from Python's HTTP landscape.
httpx also provides native HTTP/2 support, which can be significant for proxy work targeting modern websites. HTTP/2 multiplexing allows multiple requests to share a single TCP connection through the proxy, reducing the connection overhead that dominates latency in proxy-routed traffic. When your target supports HTTP/2 and you enable it via `http2=True`, you can see measurable latency improvements on high-volume workloads through gate.hexproxies.com:8080.
Configuration Patterns
httpx takes a clean approach to proxy configuration with the `proxy` parameter (previously `proxies` in older versions). Pass a single URL string to route all traffic through one gateway, or provide a dictionary mapping URL patterns to different proxies. The `httpx.Timeout` object separates connect, read, write, and pool timeouts, giving you precise control over each phase of the proxied request lifecycle. This granularity matters because proxy connect failures and slow target responses require different timeout thresholds.
For environments that require mTLS or custom certificate authorities, httpx accepts a `verify` parameter pointing to a CA bundle file. This is valuable for corporate proxy setups where an internal CA signs proxy certificates. The `follow_redirects=True` parameter is especially important for proxy work because many target sites issue 3xx redirects that need to be followed through the same proxy connection.
Common Pitfalls
A frequent source of confusion is the API change between httpx 0.23 and 0.24+, where `proxies` was replaced by `proxy`. Code copied from older tutorials will fail silently or raise deprecation warnings. Always check you are using the parameter name matching your installed version. Run `httpx.__version__` to verify.
Connection pool exhaustion is another pitfall when running httpx behind a proxy. The default pool limit of 10 connections can bottleneck high-concurrency workloads. Override it with `limits=httpx.Limits(max_connections=100, max_keepalive_connections=20)` to match your target throughput. Also note that httpx does not retry failed requests by default, unlike libraries such as urllib3. Install `httpx[http2]` explicitly if you need HTTP/2 support, as it requires the `h2` dependency.
Performance Optimization
httpx shines when you leverage its async interface for proxy workloads. The `AsyncClient` uses the same connection pooling and proxy configuration as the sync client but runs on the asyncio event loop, enabling thousands of concurrent proxied requests. Pair it with `anyio` task groups for structured concurrency that automatically cancels in-flight requests if one critical task fails.
Profile your proxy pipeline using httpx's event hooks. The `event_hooks={"request": [log_request], "response": [log_response]}` pattern lets you inject timing measurements without modifying business logic. Track the time between request dispatch and first byte received to isolate proxy latency from target server processing. Use connection pooling aggressively: a warm pool of 20 keep-alive connections to the proxy eliminates the 50-100ms TCP/TLS setup cost on every request.