Concurrency vs parallelism
Concurrency means several tasks are in progress at once: one can start before another has finished. Parallelism means they run at the very same instant, on different cores. Every parallel program is concurrent; a concurrent one is parallel only if the hardware and the runtime let it be.
Concurrency on one thread
Two Tokio tasks share a single thread. Both are in progress at once, but at any moment only one runs: they switch at each await.
Two tasks share one thread. They take turns, and every switch happens at an .await.
Threads, but still not parallel
Two Python threads crunch numbers. They are separate threads, yet the GIL lets only one run Python code at a time, so they take turns on one core.
Two threads crunch numbers. They take turns holding the GIL, so only one core is ever busy.
Parallel: two cores at once
The same Python code on the free-threaded build. With no GIL, both threads crunch at the same time, and two cores are busy.
The same code on the free-threaded build. With no GIL, both threads crunch at the same time on two cores.
Which one you need
Waiting on networks, disks or users? Concurrency is enough: tasks overlap their waiting even on one thread. Crunching numbers? You need parallelism: separate cores, through threads without a GIL, processes, or a pool.
Common questions
What's the difference between concurrency and parallelism?
Concurrency is several tasks in progress at once, taking turns. Parallelism is several tasks running at the same instant, on different cores. Concurrency is about structure; parallelism is about hardware.
Can you have concurrency without parallelism?
Yes. Tokio's current_thread runtime runs many tasks on one thread, switching at each .await. JavaScript's event loop does the same. They overlap waiting, not computing.
Do threads always run in parallel?
No. Python threads with the GIL take turns: two CPU-bound threads used one CPU's worth of time between them in our tests. On the free-threaded build, the same code used two.
Every timeline here is checked against a real program in CI. How we verify