How to call a function after delay in Kotlin?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In Kotlin, the best way to call a function after a delay depends on the environment and execution model. In modern coroutine-based code, delay is usually the cleanest solution because it suspends without blocking a thread, while older approaches such as Thread.sleep or Android Handler.postDelayed serve narrower purposes.
The key question is whether you want delayed scheduling or an actual thread pause. Those are related ideas, but they are not the same operation.
Prefer Coroutines In Modern Kotlin
If your project already uses coroutines, the standard solution is to launch a coroutine and call delay:
delay(1000) waits about one second without blocking the underlying thread. That makes it a much better choice than Thread.sleep in asynchronous code.
Android Example With A Lifecycle-Aware Scope
On Android, delayed UI work should usually run in a lifecycle-aware coroutine scope:
This integrates well with structured concurrency. If the activity or fragment is destroyed, the coroutine scope can be canceled so delayed UI actions do not run against a dead view.
Handler.postDelayed In Legacy Android Code
If you are working in older Android callback-based code without coroutines, Handler.postDelayed is the classic solution:
This schedules the lambda to run on the main thread after the delay. It is still valid, but in modern Kotlin Android code coroutines are usually easier to compose and cancel.
Why Thread.sleep Is Different
Thread.sleep pauses the current thread:
That may be acceptable in a tiny console demo, but it is usually the wrong tool for UI code or highly concurrent systems. On the Android main thread, it can freeze the interface and contribute to Application Not Responding behavior.
Use Thread.sleep only when you truly mean "block this thread" rather than "schedule this work for later."
Repeating Delays Need A Different Shape
A one-time delayed call is not the same as repeated periodic work. If you need a function to run over and over, use a loop with delay, a timer, or a scheduler that matches the lifecycle of the component.
That distinction prevents a lot of awkward code where developers keep nesting delayed callbacks when a simple repeating coroutine would be clearer. It also makes cancellation behavior easier to reason about when the work should stop with the screen or scope.
Common Pitfalls
The biggest mistake is using Thread.sleep on the Android main thread. That blocks the UI and makes the app feel broken.
Another pitfall is trying to call delay outside a coroutine or suspending function. delay is a suspending function, so it must run inside coroutine-aware code.
A third issue is launching delayed UI work in a scope that outlives the screen incorrectly. On Android, prefer lifecycle-aware scopes so delayed callbacks do not fire after the view is gone.
Summary
- In modern Kotlin, coroutine
delayis usually the best way to call a function later. - '
delayis non-blocking, whileThread.sleepblocks the current thread.' - In older Android code,
Handler.postDelayedremains a valid alternative. - Use lifecycle-aware scopes for delayed UI work on Android.
- Choose the delay mechanism based on whether you want scheduling or actual blocking.

