Coroutines are lightweight concurrency primitives for async code. They can suspend without blocking a thread and are scheduled by the Kotlin runtime, so you can run thousands of coroutines on a small thread pool. Threads are OS‑level, heavier and block when waiting.