Question
How can I call a function after a delay in Kotlin, such as waiting 1 second before running it?
For example, I want to delay execution and then invoke a function like this:
fun sayHello() {
println("Hello")
}
What is the correct way to run that function after a short delay in Kotlin?
Short Answer
By the end of this page, you will understand the main ways to delay code execution in Kotlin, when each approach is appropriate, and why Kotlin coroutines are usually the preferred modern solution. You will also see simple examples, common mistakes, and a small practice project.
Concept
In Kotlin, calling a function after a delay means waiting for some amount of time before running code. There is no single universal delay mechanism that works the same way in every context, because the correct approach depends on where your Kotlin code is running.
The main idea is this:
- Sometimes you want to block the current thread and wait.
- Sometimes you want to schedule work without blocking the thread.
- In modern Kotlin, especially with coroutines, you usually want a non-blocking delay.
Why this matters
Delays are common in real programs:
- showing a message briefly before moving to the next screen
- retrying a network request after waiting
- debouncing user input
- scheduling background work
- simulating loading or timeouts in tests
The important distinction: blocking vs non-blocking
A beginner mistake is to think “wait 1 second” is always the same operation. It is not.
Blocking delay
A blocking delay stops the current thread completely.
Example:
Thread.sleep(1000)
While sleeping:
- that thread cannot do other work
- a UI thread may freeze
- it is usually not a good choice for Android UI or coroutine-based code
Non-blocking delay
A non-blocking delay pauses the task without blocking the whole thread.
Example with coroutines:
delay(1000)
While delayed:
Mental Model
Think of delay like setting a reminder.
Thread.sleepis like telling a worker: “Do nothing for 1 second.” The worker is completely unavailable during that time.- A scheduled task is like putting a note on a calendar: “Do this 1 second later.” The worker can keep doing other work until then.
- A coroutine delay is like saying: “Pause my task for 1 second, but let the office keep working.” The task waits, but the whole system does not stop.
This mental model helps you choose the right tool:
- Need a quick blocking pause? Use thread sleep.
- Need proper asynchronous waiting? Use coroutines.
- Need to schedule code in platform-specific code like Android legacy APIs? Use a scheduler like
Handleror a timer.
Syntax and Examples
1. Using Thread.sleep (blocking)
fun sayHello() {
println("Hello")
}
fun main() {
Thread.sleep(1000)
sayHello()
}
This waits 1000 milliseconds, then calls sayHello().
Note: This blocks the current thread. Avoid this on UI threads.
2. Using a Timer
import java.util.Timer
import kotlin.concurrent.schedule
fun sayHello() {
println("Hello")
}
fun main() {
Timer().schedule(1000) {
sayHello()
}
Thread.sleep(1500)
}
Here, the function is scheduled to run later.
The extra Thread.sleep(1500) keeps the program alive long enough for the timer task to run in a simple console app.
3. Using Kotlin coroutines (recommended)
Step by Step Execution
Consider this coroutine example:
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
fun greet() {
println("Hello after delay")
}
fun main() = runBlocking {
println("Start")
delay(1000)
greet()
println("End")
}
What happens step by step
main()starts insiderunBlocking.println("Start")runs immediately.delay(1000)pauses this coroutine for 1000 milliseconds.- During that delay, the thread is not blocked in the same way as
Thread.sleep. - After 1 second, execution continues.
greet()is called, soHello after delayis printed.println("End")runs last.
Output
Start
Hello after delay
End
Real World Use Cases
Common practical uses for delayed execution
UI feedback
Wait briefly before hiding a success message or showing the next screen.
// Conceptually: wait, then continue
Retry logic
If an API request fails, wait before trying again.
// delay(2000) before retrying a request
Debouncing user input
When a user types in a search box, wait a short time before sending a request so you do not search on every keystroke.
Background task scheduling
Run cleanup logic, polling, or status checks after a delay.
Animation and game timing
Wait between events, frames, or actions in simple timing workflows.
Tests and demos
Simulate network latency or asynchronous timing in sample code.
In most production code, developers avoid arbitrary delays unless there is a clear reason. But when timing is part of the feature, choosing the right delay mechanism matters.
Real Codebase Usage
In real Kotlin projects, delayed execution is usually part of a larger pattern rather than a standalone line of code.
1. Guard clauses before delaying
Developers often check whether work should still happen.
import kotlinx.coroutines.delay
suspend fun sendReminder(isEnabled: Boolean) {
if (!isEnabled) return
delay(1000)
println("Reminder sent")
}
This avoids waiting when the work is unnecessary.
2. Retry with delay
import kotlinx.coroutines.delay
suspend fun fetchWithRetry(fetch: suspend () -> String): String {
repeat(3) { attempt ->
try {
return fetch()
} catch (e: Exception) {
if (attempt == 2) throw e
delay(1000)
}
}
error("Unreachable")
}
This pattern is common in networking code.
3. Delayed UI actions
Common Mistakes
1. Using Thread.sleep on the UI thread
Broken idea:
Thread.sleep(1000)
updateScreen()
Problem:
- the UI freezes during the sleep
Better:
- use coroutines or platform scheduling APIs
2. Forgetting that delay only works in coroutines
Broken code:
import kotlinx.coroutines.delay
fun main() {
delay(1000)
println("Hi")
}
Problem:
delayis asuspendfunction- it must be called from a coroutine or another suspend function
Correct:
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
fun main() = runBlocking {
delay(1000)
println()
}
Comparisons
| Approach | Blocks thread? | Best for | Notes |
|---|---|---|---|
Thread.sleep(1000) | Yes | Simple console demos or tests | Easy, but dangerous on UI threads |
Timer().schedule(1000) | No, not in the same way | Basic scheduled tasks | Older style; less common in modern Kotlin |
Handler.postDelayed(...) | No | Older Android code | Android-specific |
delay(1000) | No | Modern Kotlin and Android with coroutines | Usually the preferred choice |
Thread.sleep vs delay
Cheat Sheet
Quick reference
Block current thread for 1 second
Thread.sleep(1000)
Delay inside a coroutine for 1 second
delay(1000)
Simple coroutine example
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
fun main() = runBlocking {
delay(1000)
println("Done")
}
Schedule with a timer
import java.util.Timer
import kotlin.concurrent.schedule
Timer().schedule(1000) {
println("Done")
}
Android older-style delayed execution
Handler(Looper.getMainLooper()).postDelayed({
println("Done")
}, 1000)
Rules to remember
- Time values here are usually in milliseconds.
1000milliseconds = second.
FAQ
How do I delay a function by 1 second in Kotlin?
In modern Kotlin, use a coroutine and call delay(1000). In simple blocking code, you can use Thread.sleep(1000).
Is Thread.sleep() bad in Kotlin?
Not always, but it blocks the current thread. It is usually a poor choice for UI code and modern asynchronous programs.
Why does delay() give an error in a normal function?
Because delay() is a suspend function. It must be called inside a coroutine or another suspend function.
What is the best way to delay code in Android Kotlin?
Usually coroutines are the best option. Older Android code may use Handler.postDelayed().
Are delay values in Kotlin measured in seconds or milliseconds?
Most common APIs shown here use milliseconds. 1000 means 1 second.
Can I call a function later without blocking the app?
Yes. Use coroutines with delay() or another scheduling API such as a timer or Android handler.
Should I use a delay to fix race conditions?
No. Delays are unreliable for synchronization problems. Use proper concurrency tools, lifecycle-aware scopes, or event-based logic instead.
Mini Project
Description
Build a small Kotlin program that prints a welcome message after a short delay. This helps you practice the difference between immediate execution and delayed execution using coroutines, which is the most common modern Kotlin approach.
Goal
Create a program that waits 1 second, prints a delayed message, then waits another second and prints a second message.
Requirements
- Use Kotlin coroutines.
- Wait 1 second before printing the first delayed message.
- Wait another 1 second before printing the second message.
- Print a message immediately at the start so the execution order is clear.
Keep learning
Related questions
Accessing Kotlin Extension Functions from Java
Learn how Kotlin extension functions are compiled and how to call them correctly from Java with clear examples and common pitfalls.
Android AlarmManager Example: Scheduling Tasks with AlarmManager
Learn how to use Android AlarmManager to schedule tasks, set alarms, and handle broadcasts with a simple beginner example.
Android Foreground Service Notification Channels in Kotlin
Learn why startForeground fails on Android 8.1 and how to create a valid notification channel for foreground services in Kotlin.