What is the difference between concurrency and parallelism?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Concurrency means structuring a program to handle multiple tasks that can make progress independently. Parallelism means executing multiple tasks simultaneously on multiple processors. Concurrency is about design — dealing with many things at once. Parallelism is about execution — doing many things at once. You can have concurrency without parallelism (single-core CPU switching between tasks) and parallelism without concurrency (SIMD processing the same instruction on multiple data points). Rob Pike summarized it as: "Concurrency is about dealing with lots of things at once. Parallelism is about doing lots of things at once."
Concurrency: Managing Multiple Tasks
Concurrency is about program structure. A concurrent program can handle multiple tasks by interleaving their execution, even on a single CPU core.
Both downloads make progress concurrently, but only one line of Python executes at any instant (single thread).
Parallelism: Simultaneous Execution
Parallelism requires multiple processors/cores executing tasks at the same physical time.
Each worker process runs on a different CPU core. The computations happen at the same time, not interleaved.
Visual Comparison
Real-World Analogy
| Scenario | Type |
| One cashier serving two lines by alternating | Concurrent, not parallel |
| Two cashiers each serving their own line | Parallel |
| Two cashiers serving three lines by alternating | Concurrent and parallel |
| One cashier serving one line | Neither |
Concurrency in Different Languages
Go — Goroutines (Concurrent, Optionally Parallel)
Java — Threads (Parallel)
JavaScript — Event Loop (Concurrent, Not Parallel)
When to Use Each
| Scenario | Use | Why |
| Web server handling requests | Concurrency | I/O-bound, need to handle many connections |
| Image processing pipeline | Parallelism | CPU-bound, benefit from multiple cores |
| Database query + API call | Concurrency | Both are I/O-bound, interleave waiting |
| Matrix multiplication | Parallelism | CPU-bound, split across cores |
| Chat application | Concurrency | Many idle connections, little CPU per message |
| Video encoding | Parallelism | CPU-intensive, split frames across cores |
Python's GIL and the Distinction
Python's Global Interpreter Lock (GIL) prevents multiple threads from executing Python bytecode simultaneously. Threads are concurrent but not parallel for CPU-bound work. Use multiprocessing for true parallelism.
Common Pitfalls
- Assuming concurrency requires multiple cores: Concurrency is a software design concept. A single-core CPU can run concurrent programs by time-slicing between tasks. Parallelism requires hardware support (multiple cores or processors).
- Using threads for I/O-bound work when async is simpler: Thread-based concurrency adds complexity (locks, race conditions). For I/O-bound tasks (HTTP requests, file reads, database queries),
async/awaitprovides concurrency with less overhead and no shared-state bugs. - Ignoring the GIL in Python: Python threads do not speed up CPU-bound work due to the GIL. Using
threadingfor matrix multiplication gives no speedup. Usemultiprocessingor libraries like NumPy that release the GIL during computation. - Assuming parallel code is always faster: Parallelism has overhead — process creation, memory copying, synchronization. For small tasks, the overhead exceeds the time saved. Parallelize only when the work is large enough to amortize the startup cost.
- Confusing async with parallel:
async/awaitin JavaScript and Python provides concurrency (interleaving) not parallelism (simultaneous execution). Anawait fetch()call yields control to other tasks but does not run on a separate core.
Summary
- Concurrency: Structuring code to handle multiple tasks that make independent progress (design)
- Parallelism: Executing multiple tasks simultaneously on multiple cores (execution)
- Concurrency without parallelism: single-core time-slicing (async I/O, event loops)
- Parallelism without concurrency: SIMD, GPU shader programs
- Use concurrency for I/O-bound work (web servers, network requests)
- Use parallelism for CPU-bound work (image processing, scientific computing)
- Python GIL: threads are concurrent but not parallel for CPU work; use multiprocessing

