What is the thread pool, and why not just create threads?

.NET Framework & CLR Concurrency Intermediate 2–3 Yrs3–5 Yrs Conceptual 1 min read

Quick Answer

The thread pool is a managed set of reusable worker threads. Creating a raw Thread costs ~1MB of stack and kernel setup, and having thousands is counterproductive. The pool reuses threads for short work items (Task.Run, async continuations, timer callbacks) and grows/shrinks its size based on demand.

The thread pool is a pool of worker threads the runtime keeps around and hands out for short pieces of work. Making a raw thread is expensive — about a megabyte of stack each — so you don't want thousands of them, and the pool solves that by reusing threads for things like Task.Run, async continuations and web request handling. The failure mode is thread-pool starvation: if you block pool threads by calling .Result on async code, eventually there are no free threads, and the pool only adds new ones about once a second, so the whole app grinds. That's the number-one reason “async all the way” matters.

  • Task.Run, Parallel.ForEach, ASP.NET Core request handling and async continuations all use the pool.
  • Thread-pool starvation: blocking pool threads (with .Result, lock held long, Thread.Sleep) leaves none to run new work; the pool adds threads slowly (~1/second by default) so throughput collapses.
  • Fix: never block on async; keep pool work short and non-blocking; raise ThreadPool.SetMinThreads only as a stopgap.
  • Use a dedicated Thread for genuinely long-running, blocking, dedicated loops.