Compare
Side-by-side on the decisions that recur: process vs thread, threads vs async, mutex vs semaphore, blocking vs non-blocking I/O, container vs VM — with when to choose each.
Process vs ThreadThreads vs Async / event loopConcurrency vs ParallelismMutex vs SemaphoreBlocking I/O vs Non-blocking / async I/Oselect / poll vs epoll / kqueueContainer vs Virtual machineStack vs HeapPipe vs Shared memoryOS page cache vs Application cache
| Concurrency | Parallelism | |
|---|---|---|
| Definition | Several tasks in progress, interleaved over time | Several tasks executing at the same instant on different cores |
| Needs multiple cores | No — one core interleaves via time slices or an event loop | Yes, by definition |
| What it buys | Responsiveness and overlap of waiting (I/O) with work | Throughput: N cores can finish CPU-bound work up to N× faster |
| Where the OS provides it | The scheduler’s time slicing; blocking I/O releasing the core | Multiple runnable threads placed on multiple cores |
| Runtime reality | Node’s event loop is concurrent, not parallel; CPython threads are concurrent, parallel only outside the GIL | C++ threads, Python multiprocessing, Node worker threads / cluster |
| Typical misreading | "It is async so it uses all my cores" — it does not | "Eight threads so eight times faster" — only if the work is CPU-bound and independent |
| Choose this when | The problem is waiting: the tasks spend most of their time blocked on network, disk or users. | The problem is computing: the tasks are CPU-bound, divisible, and you have idle cores. |