Why This Matters
People often use "concurrent" and "parallel" interchangeably, but they mean very different things. Concurrency is about managing multiple tasks that overlap in time. Parallelism is about executing multiple tasks at the exact same instant. A single-core CPU can be concurrent (switching between tasks quickly) but cannot be parallel (only one instruction runs at a time). A multi-core CPU can be both.
This distinction matters because it changes what tools you reach for. If your program waits on network requests, you need concurrency (async I/O, event loops). If your program crunches numbers, you need parallelism (multiple cores, worker threads). Choosing the wrong model wastes resources or adds unnecessary complexity. Understanding this difference is the key to writing efficient, scalable software.
Define Terms
Visual Model
The full process at a glance. Click Start tour to walk through each step.
Concurrency interleaves tasks on one core. Parallelism runs tasks simultaneously on multiple cores.
Code Example
// SEQUENTIAL: one after another (slow)
async function sequential() {
const start = Date.now();
const user = await fetchUser(1); // waits 1 second
const posts = await fetchPosts(1); // waits 1 second
const comments = await fetchComments(1); // waits 1 second
console.log(`Sequential: ${Date.now() - start}ms`); // ~3000ms
}
// CONCURRENT: all at once, wait for all (fast)
async function concurrent() {
const start = Date.now();
// Start all three requests simultaneously
const [user, posts, comments] = await Promise.all([
fetchUser(1), // starts immediately
fetchPosts(1), // starts immediately
fetchComments(1) // starts immediately
]);
console.log(`Concurrent: ${Date.now() - start}ms`); // ~1000ms
}
// Simulated fetch functions
function fetchUser(id) {
return new Promise(r => setTimeout(() => r({ id, name: "Alice" }), 1000));
}
function fetchPosts(id) {
return new Promise(r => setTimeout(() => r(["post1", "post2"]), 1000));
}
function fetchComments(id) {
return new Promise(r => setTimeout(() => r(["comment1"]), 1000));
}
// Run both to compare
sequential();
concurrent();Interactive Experiment
Try these exercises:
- Measure the difference: make three
fetchcalls sequentially vs withPromise.all. Compare the total time. - Open your browser's Performance tab. Load a web page and observe how network requests overlap (concurrency).
- In Python, run a CPU-bound task with
threadingvsmultiprocessing. Which one actually uses multiple cores? - Try
Promise.allSettledinstead ofPromise.all. What happens if one of the promises rejects?
Quick Quiz
Coding Challenge
The function `fetchAllSequential` makes three simulated API calls one after another, taking 3 seconds total. Rewrite it as `fetchAllConcurrent` using `Promise.all` so all three calls run concurrently, taking only about 1 second. The function should return an object with `user`, `posts`, and `comments` properties.
Real-World Usage
The concurrency vs parallelism distinction shapes every architecture decision:
- Node.js uses single-threaded concurrency via the event loop. This handles thousands of I/O-bound connections efficiently without threads.
- Go uses goroutines for lightweight concurrency. The Go runtime schedules them across OS threads for parallelism automatically.
- Web browsers use concurrency for network requests (fetching many resources at once) and parallelism for rendering (compositing layers on the GPU).
- MapReduce (Hadoop, Spark) uses parallelism to process massive datasets by splitting work across many machines.
- Async frameworks like FastAPI (Python) and Express (Node.js) achieve high throughput through concurrent I/O, not parallel computation.