Async vs threading vs multiprocessing

Posted 2026-02-18 on the pythondeck.com blog

Three concurrency models, three different problems. The decision rule is short: shape of the workload, not personal preference.

Threading

One process, multiple OS threads, sharing memory. The GIL means only one thread runs Python bytecode at a time, so threading does NOT speed up pure-Python CPU work. It DOES speed up I/O-bound work, because threads release the GIL while waiting on sockets, files or subprocesses. Use threading for blocking I/O when an asyncio rewrite would be too disruptive.

Asyncio

One process, one thread, cooperative scheduling. await hands control back to the event loop while waiting on I/O, letting thousands of operations run concurrently. The catch is that the entire stack needs to be async-aware - a single sync database call blocks the whole loop. Use asyncio when you control the whole I/O stack and need very high concurrency.

Multiprocessing

Multiple OS processes, no shared memory, no GIL contention. This is the only option that gives true parallelism for pure-Python CPU-bound work. The cost is inter-process communication overhead - pass small messages, not gigabytes. Use multiprocessing for number crunching, image processing, parsing large corpora.

Decision tree

« all blog posts Browse tutorials