title: Why is ThreadPoolExecutor's default max_workers decided based on the number of CPUs?
body: <p>The documentation for <a href="https://docs.python.org/dev/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor" rel="noreferrer"><code>concurrent.futures.ThreadPoolExecutor</code></a> says:</p>
  
  <blockquote>
    <p><em>Changed in version 3.5:</em> If <em>max_workers</em> is <code>None</code> or not given, it will default to the number of processors on the machine, multiplied by <code>5</code>, assuming that <a href="https://docs.python.org/dev/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor" rel="noreferrer">ThreadPoolExecutor</a> is often used to overlap I/O instead of CPU work and the number of workers should be higher than the number of workers for <a href="https://docs.python.org/dev/library/concurrent.futures.html#concurrent.futures.ProcessPoolExecutor" rel="noreferrer">ProcessPoolExecutor</a>.</p>
  </blockquote>
  
  <p>I want to understand why the default <code>max_workers</code> value depends on the number of CPUs. Regardless of how many CPUs I have, only one Python thread can run at any point in time.</p>
  
  <p>Let us assume each thread is I/O intensive and it spends only 10% of its time in the CPU and 90% of its time waiting for I/O. Let us then assume we have 2 CPUs. We can only run 10 threads to utilize 100% CPU. We can't utilize any more CPU because only one thread runs at any point in time. This holds true even if there are 4 CPUs.</p>
  
  <p>So why is the default <code>max_workers</code> decided based on the number of CPUs?</p>