When working with Kotlin coroutines, developers often rely on the delay()
function to pause execution without blocking threads. However, a common frustration arises: “Why is my coroutine delay not working?” If you have faced this issue, you are not alone. In this article, we will dive deep into the possible reasons why delay()
may not behave as expected and how to fix it effectively.

Understanding Coroutine delay()
The delay()
function is a suspending function provided by kotlinx.coroutines
. Unlike Thread.sleep()
, it does not block the thread but instead suspends the coroutine, allowing other coroutines to continue running on the same thread.
import kotlinx.coroutines.* fun main() = runBlocking { println("Start") delay(1000L) // Suspends for 1 second println("End after 1 second") }
In this example, the coroutine will print “Start”, then suspend for 1 second before printing “End after 1 second”. If your program skips the delay or terminates too early, something is wrong in your coroutine setup.
Why delay()
Might Not Work
There are several reasons why delay()
may appear to not work. Let’s go through the most common scenarios:
1. Not Running Inside a Coroutine
The delay()
function only works inside a coroutine or another suspending function. If you try to call it outside of a coroutine scope, it will not compile or may not behave as expected.
// ❌ Incorrect usage fun main() { delay(1000L) // Error: Suspend function 'delay' should be called only from a coroutine }
✅ Solution: Wrap your code inside runBlocking
or a CoroutineScope
.
fun main() = runBlocking { delay(1000L) println("Correct usage") }
2. The Program Exits Before Delay Completes
In Kotlin, if your main function ends before the coroutine completes, the delay will be skipped because the application shuts down.
fun main() { GlobalScope.launch { delay(2000L) println("This will not print if main ends early") } }
✅ Solution: Use runBlocking
or join()
to keep the program alive until the coroutine finishes.
fun main() = runBlocking { val job = launch { delay(2000L) println("Now it works correctly!") } job.join() }
3. Using Thread.sleep()
Instead of delay()
Mixing Thread.sleep()
and coroutines can cause unexpected behavior because Thread.sleep()
blocks the thread, preventing other coroutines from running.
// ❌ Incorrect fun main() = runBlocking { println("Start") Thread.sleep(1000L) // Blocks the thread println("End after 1 second but blocked") }
✅ Solution: Always use delay()
instead of Thread.sleep()
in coroutine code.
// ✅ Correct fun main() = runBlocking { println("Start") delay(1000L) // Non-blocking delay println("End after 1 second smoothly") }
4. Incorrect Coroutine Scope
If you are using Android or a custom coroutine scope, the scope may cancel before the delay completes. For instance, if the lifecycle ends, your coroutine may never reach the print statement after delay()
.
✅ Solution: Always use the correct scope such as lifecycleScope
in Android or manage job cancellation properly.
5. Dispatchers and Context Issues
Using the wrong dispatcher can also affect coroutine execution. For example, running delay inside Dispatchers.Main
in a console project without a proper Main dispatcher setup will crash.
fun main() = runBlocking { launch(Dispatchers.Default) { delay(1000L) println("Works on Default dispatcher") } }
Comparison: Thread.sleep()
vs delay()
Feature | Thread.sleep() | delay() |
---|---|---|
Blocks Thread | Yes | No |
Works with Coroutines | No | Yes |
Performance | Lower | Higher (non-blocking) |
Cancellation | Not cancellable | Cancellable |
Best Practices for Using delay()
- Always run
delay()
inside a coroutine or suspending function. - Do not mix
Thread.sleep()
with coroutines. - Use proper scopes like
runBlocking
,CoroutineScope
, orlifecycleScope
in Android. - Ensure the application or scope is alive long enough for delay to complete.
- Use
join()
or structured concurrency to handle coroutine completion.
Conclusion
If your Kotlin coroutine delay
is not working, it is usually due to one of the issues explained above: calling delay()
outside a coroutine, letting the program terminate too early, mixing Thread.sleep()
, using the wrong scope, or dispatchers not configured properly. By following the solutions in this guide, you can ensure that delay()
works correctly and your coroutines run smoothly.
For more details, check the official documentation on Kotlin Coroutines.