Async, concurrency, and parallelism are different

· 5 min read

engineering software-development #csharp #dotnet #async #concurrency #parallelism

These words are often used as if they mean the same thing. They do not.

Keeping those questions separate makes design decisions simpler.

Async is about waiting

Async is useful when an operation spends time waiting for I/O: an HTTP response, a database query, a file read, or a message from another service.

The operation may take a while, but the CPU does not do the work for most of that time. Async starts the operation, yields while an external system responds, and lets other ready work continue instead of blocking.[1]

Making coffee is a good everyday example. Once the kettle is boiling, standing beside it does not help. You can set out the mug or answer a message, then come back when the water is ready. Async works the same way: start the I/O, let other work continue, and resume when there is a result.

Async does not make the remote service faster. It also does not automatically create a new thread. Its main job is to avoid using execution capacity during an external wait.

Concurrency is about overlap

Concurrency means that more than one operation can be in progress during the same interval. They do not need to execute at exactly the same instant.

Imagine you want to make breakfast. You start the coffee, then boil an egg or prepare something else while it waits; neither task needs attention every second, so their waiting time overlaps. Concurrency is the same idea: keep independent work moving instead of treating every wait as idle time.

For example, two independent downloads can overlap. While file A waits for network data, file B may receive a packet. A single execution resource can coordinate both operations.

Operation 0 ms 1–500 ms 500 ms
Download A Start Waiting for network data Complete
Download B Start Waiting for network data Complete

This is concurrent I/O. It can reduce the total time the user waits for both downloads because their network waits overlap. It does not mean that two CPU-heavy calculations are running at once.

Concurrency also needs coordination. Operations may compete for a database connection, a rate limit, a shared file, or a finite amount of memory. Starting every operation immediately is not always better.

Parallelism is about CPU work

Parallelism divides computation across multiple CPU cores so calculations can execute simultaneously.

For the same coffee example, imagine two people working at once: one grinds the beans while the other heats the milk. Both are actively working, so coffee prepration finishes sooner. Parallelism is similar: independent CPU-bound tasks run at the same time on separate cores.

Consider processing two large images by resizing pixels, applying filters, and calculating histograms. This is CPU-bound work. If the machine has available cores and the images are independent, processing both in parallel may reduce elapsed time. .NET's parallel-programming guidance describes this as distributing work across multiple processors that can execute threads simultaneously.[3]

Parallelism has costs. Splitting work, coordinating results, and competing for memory or CPU cache can make a small job slower. Consider it when measurement shows that CPU work is the bottleneck, not because a method looks expensive.

A small decision guide

Situation Primary tool Why
Wait for an API, database, file, or queue Async I/O The operation is waiting on an external system.
Wait for several independent API calls Async with concurrency Their waits can overlap.
Transform many large images or run expensive calculations Parallelism Multiple CPU cores may reduce computation time.
Validate a small object or format text Synchronous code There is no meaningful external wait or expensive CPU work.

Microsoft's async guidance makes the same practical distinction: async is the usual choice for I/O-bound scenarios, while expensive calculations are CPU-bound work that may need a different approach.[2]

Sources

  1. Asynchronous — MDN Web Docs
  2. Asynchronous programming scenarios — Microsoft Learn
  3. Parallel programming in .NET — Microsoft Learn
Share on LinkedIn