Change the connection pool size for Python's requests module when in Threading
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
When many Python threads send HTTP requests to the same host, the default connection pool settings in requests can become a bottleneck. Threads may block while waiting for an available socket, and the application can end up slower than expected even though the remote service is healthy. The usual fix is to configure a Session with a custom HTTPAdapter so the underlying urllib3 pool can hold more reusable connections.
Why the Default Pool Can Be Too Small
The requests library uses urllib3 underneath, and urllib3 manages persistent HTTP connections through connection pools. That is normally a good thing because reusing sockets reduces TCP and TLS setup overhead.
The problem appears when concurrency grows. If 20 worker threads all target the same host but the adapter only keeps a small number of reusable connections, some requests must wait or create extra churn.
A common symptom is:
- throughput flattens out as thread count rises
- response times become noisy under concurrency
- profiling shows time spent waiting on network setup rather than application logic
Configure a Bigger Pool With HTTPAdapter
The practical way to increase pool capacity is to mount a custom adapter on a Session.
The key options are:
- '
pool_maxsizefor the maximum number of connections per pool' - '
pool_connectionsfor the number of pools cached by the adapter' - '
pool_block=Trueso threads wait for a connection instead of creating unbounded churn'
Use the Session in a Threaded Workflow
Here is a small example using ThreadPoolExecutor:
This pattern works well when many threads reuse the same host and benefit from a warm pool of persistent connections.
Pick the Pool Size Intentionally
A good starting point is to match pool_maxsize to the number of concurrent requests you expect against the same host. If you have 16 worker threads that mostly target one API, a pool near 16 is a reasonable first test.
That does not mean bigger is always better. A very large pool can waste resources or exceed practical limits on the client or server side. Tune based on:
- number of worker threads
- number of target hosts
- average request duration
- server-side rate limits and keep-alive behavior
Measure under realistic load instead of guessing.
Shared Session or One Session Per Thread
This is where teams differ. The underlying urllib3 pool is designed for concurrent use, but a requests.Session also contains mutable state such as cookies and headers. If many threads are mutating that state, sharing one session can become risky.
A safe rule is:
- shared session is fine when configuration is set once and then treated as read-only
- per-thread sessions are simpler if threads need independent auth, cookies, or mutable headers
If you choose one session per thread, you can still configure the adapter the same way. The tradeoff is fewer shared connections across threads.
Always Set Timeouts
A larger pool does not solve hangs caused by missing timeouts. In threaded code, every request should set explicit connect and read timeouts so stuck workers do not occupy pool slots forever.
That keeps the connection pool healthy under failure conditions.
Common Pitfalls
The first mistake is increasing the thread count without increasing pool capacity. More threads alone do not improve throughput if they all fight for the same small pool.
Another issue is leaving pool_block at its default behavior and then wondering why connection usage becomes erratic under pressure. Blocking is often easier to reason about than unchecked connection churn.
Developers also share a session across threads while mutating cookies or headers dynamically. The pool may be fine, but the session state becomes the real problem.
Finally, do not forget timeouts. A few stuck requests can make a properly sized pool behave like an undersized one.
Summary
- '
requestsuses urllib3 connection pools, and the defaults may be too small for threaded workloads.' - Increase pool capacity by mounting a custom
HTTPAdapteron aSession. - Size
pool_maxsizearound the expected concurrent requests per host. - Treat a shared session as effectively read-only, or use separate sessions per thread when state differs.
- Combine pooling with explicit timeouts so blocked requests do not exhaust the pool.
Related reading
- Changing Kubernetes' node-proxy tcp keepalive time
- Changing On3 to On2 in JavaScript
- Changing Table Engine in MySQL
- Channel/BlockingCollection alloc free alternatives?
- Change WPF controls from a non-main thread using Dispatcher.Invoke
- Changing the number of threads in TensorFlow on Cifar10
- Change the name of a key in dictionary
- Change the number of request retries in boto3

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.