Why are kotlin coroutines called asynchronous?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Kotlin coroutines are called asynchronous because they let a computation pause while some other work continues, then resume later when the awaited result is ready. The code often looks sequential, but the execution model is non-blocking at suspension points.
That said, coroutine does not automatically mean “runs on another thread” or “is parallel.” A coroutine is asynchronous when it can suspend instead of blocking a thread, and it becomes concurrent or parallel only depending on how you schedule it.
What Makes a Coroutine Asynchronous
The key mechanism is suspension. A suspend function can pause without blocking the underlying thread. While that coroutine is suspended, the thread can do other work.
That is different from a blocking call such as Thread.sleep, which occupies the thread for the whole wait.
delay suspends the coroutine. It does not block the thread the way Thread.sleep(1000) would. That is why the style is asynchronous even though the code reads top to bottom.
Sequential Style, Asynchronous Behavior
One reason coroutines confuse people is that they remove callback noise. The code looks synchronous, but the runtime behavior is still asynchronous.
In callback-based code, the asynchrony is obvious because the continuation is written as a nested function. With coroutines, the compiler transforms the suspend function into a state machine behind the scenes, so the waiting and resuming are explicit in execution but hidden from source-level structure.
This is the same reason async and await style code in other languages still counts as asynchronous even though it reads linearly.
Coroutines Are Not the Same as Threads
A coroutine is a lightweight unit of work. A thread is an operating-system execution resource. Coroutines can run on threads, move between threads, or share a thread with many other coroutines.
Here the coroutines represent asynchronous tasks. Whether they run concurrently depends on the dispatcher and the environment, but their ability to suspend without blocking is what makes the model asynchronous.
Asynchronous Versus Concurrent Versus Parallel
These terms are related but not identical.
- Asynchronous means the caller does not block waiting for completion.
- Concurrent means multiple tasks can make progress during overlapping time periods.
- Parallel means multiple tasks execute at the same instant on different cores or threads.
Coroutines are often used for all three, which is why the terminology gets blurred. The safest statement is that coroutines provide a convenient abstraction for asynchronous and concurrent programming, with parallelism available depending on dispatchers and workload.
Why the Name Sticks
Historically, coroutine discussions appear in the same places as async I/O, network calls, UI responsiveness, and background work. The typical selling point is, “write asynchronous code without callback hell.” That framing is accurate enough for day-to-day use, even if it omits nuance about dispatchers and scheduling.
So when people call Kotlin coroutines asynchronous, they are describing the way coroutines suspend and resume around long-running operations without blocking the current thread.
Common Pitfalls
A common mistake is assuming every suspend function automatically runs on a background thread. Suspension and thread choice are different concerns. A coroutine can suspend on the main thread and resume on the main thread.
Another mistake is treating coroutines as always parallel. If everything runs on one dispatcher thread, the code may be asynchronous without being parallel at all.
Developers also sometimes use blocking APIs inside coroutines and expect coroutine magic to make them non-blocking. If a library call blocks the thread, the coroutine blocks that thread too unless you isolate it appropriately.
Finally, do not use GlobalScope casually. Structured concurrency is one of the main benefits of Kotlin coroutines, and unscoped jobs make error handling and cancellation harder.
Summary
- Coroutines are called asynchronous because they can suspend and resume without blocking a thread.
- The code may look sequential while still behaving asynchronously.
- Coroutines are lighter than threads and are not the same concept.
- Asynchronous, concurrent, and parallel are related but different terms.
- A coroutine only stays non-blocking if the work inside it is also non-blocking or scheduled appropriately.

