Concurrency vs Parallelism

Concurrency is dealing with many things at once; parallelism is doing many things at once.

Beginner6 min read3 interview questions

Concurrency is about structure: a program makes progress on several tasks by interleaving them, even on a single CPU core. A web server waiting on a database can serve another request in the meantime.

Parallelism is about execution: tasks literally run at the same instant on multiple cores or machines. Rendering video frames on eight cores is parallel work.

Most back-end services are concurrency-bound (waiting on I/O), not CPU-bound. That is why async I/O often improves throughput more than adding cores.

Diagram

Concurrency — 1 core, interleavedParallelism — 2 cores, simultaneousTask ATask BCPU coreA, B, A, B…Task ATask BCore 1runs ACore 2runs B
Concurrency switches between tasks; parallelism runs them at the same time.

Key concepts

Thread
A unit of execution scheduled by the operating system. Threads share memory inside a process.
Async / await
Lets a thread start an I/O operation and do other work until it completes, instead of blocking.
Race condition
A bug where the result depends on the timing of concurrent operations on shared state.
Lock / mutex
Ensures only one thread enters a critical section at a time. Correct, but can reduce throughput.
Amdahl’s law
The serial part of a workload limits how much speed-up parallelism can deliver.

Trade-offs

Benefits

  • Concurrency keeps CPUs busy while waiting on I/O
  • Parallelism shortens CPU-heavy jobs
  • Both increase throughput when applied to the right bottleneck

Costs

  • Shared state introduces races and deadlocks
  • Harder to test and reproduce bugs
  • Thread overhead and context switching cost CPU and memory

Use it when

  • Concurrency: APIs, web servers, anything that waits on network or disk
  • Parallelism: image processing, data transforms, report generation, ML inference batches

Common mistakes

  • Blocking on async code (.Result, .Wait()), which can starve the thread pool
  • Adding threads to a database-bound service — the database becomes the queue
  • Mutating shared collections without synchronisation

Interview questions

Q1Can you have concurrency without parallelism?
Yes. A single-core machine or a single-threaded event loop (like Node.js) interleaves many tasks without running two at the same instant.
Q2Why does async I/O improve API throughput?
While a request waits on the database, its thread is released to serve other requests. The same thread pool handles far more in-flight requests.
Q3How would you avoid a race condition on a shared counter?
Use an atomic operation (e.g. Interlocked.Increment), a lock around the update, or avoid shared state by giving each worker its own counter and summing at the end.