programming
sleep function
code optimization
time delay
milliseconds

How do I get my program to sleep for 50 milliseconds?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Pausing execution for a precise duration is a common requirement for rate limiting, polling loops, animation timing, and test synchronization. Every major language provides a sleep or delay primitive, but the API, precision guarantees, and threading implications differ significantly. This article shows how to sleep for 50 milliseconds in Python, JavaScript, Java, C#, Go, C++, and Rust, with notes on precision and best practices.

Python

Python's time.sleep() accepts seconds as a float, so 50 milliseconds is 0.05.

python
1import time
2
3print("Starting work")
4time.sleep(0.05)  # 50 ms
5print("Resumed after delay")

For async Python code, use asyncio.sleep() instead. This releases the event loop during the wait rather than blocking the entire thread.

python
1import asyncio
2
3async def delayed_task():
4    print("Before delay")
5    await asyncio.sleep(0.05)
6    print("After delay")
7
8asyncio.run(delayed_task())

The time.sleep() call blocks the current thread and cannot be interrupted except by a signal. In GUI applications and async servers, always prefer the non-blocking variant.

JavaScript and Node.js

JavaScript does not have a built-in synchronous sleep. The standard approach wraps setTimeout in a Promise.

javascript
1function sleep(ms) {
2  return new Promise((resolve) => setTimeout(resolve, ms));
3}
4
5async function main() {
6  console.log("Before delay");
7  await sleep(50);
8  console.log("After 50ms delay");
9}
10
11main();

In Node.js 16 and above, the timers/promises module provides a built-in promise-based delay.

javascript
1import { setTimeout as sleep } from "timers/promises";
2
3await sleep(50);
4console.log("Resumed");

Never use a busy-wait loop (while (Date.now() < target) {}) to simulate sleep in JavaScript. It blocks the event loop and freezes the entire application.

Java

Java provides Thread.sleep() which accepts milliseconds directly.

java
1public class SleepExample {
2    public static void main(String[] args) throws InterruptedException {
3        System.out.println("Before delay");
4        Thread.sleep(50);
5        System.out.println("After 50ms delay");
6    }
7}

Thread.sleep() throws InterruptedException, which you must either catch or declare. For finer control, TimeUnit provides a more readable API.

java
import java.util.concurrent.TimeUnit;

TimeUnit.MILLISECONDS.sleep(50);

Inside virtual threads (Project Loom, Java 21+), Thread.sleep() unmounts the virtual thread from the carrier thread, making it non-blocking at the OS level.

C#

C# offers both a blocking sleep and an async delay.

csharp
1using System;
2using System.Threading;
3using System.Threading.Tasks;
4
5// Blocking — freezes the current thread
6Thread.Sleep(50);
7
8// Async — releases the thread back to the pool
9await Task.Delay(50);

In ASP.NET and UI applications, always prefer Task.Delay over Thread.Sleep. Blocking a thread-pool thread in ASP.NET can lead to thread starvation under load, while blocking the UI thread in a desktop application freezes the interface.

csharp
1async Task PollingLoop(CancellationToken ct)
2{
3    while (!ct.IsCancellationRequested)
4    {
5        await CheckForUpdatesAsync();
6        await Task.Delay(50, ct);
7    }
8}

Passing a CancellationToken to Task.Delay lets you interrupt the wait cleanly without waiting for the full duration.

Go

Go's time.Sleep() accepts a time.Duration value.

go
1package main
2
3import (
4    "fmt"
5    "time"
6)
7
8func main() {
9    fmt.Println("Before delay")
10    time.Sleep(50 * time.Millisecond)
11    fmt.Println("After 50ms delay")
12}

time.Sleep pauses the current goroutine, not the entire OS thread. The Go runtime scheduler moves other goroutines onto available threads while one sleeps. For cancellable delays, use a context or a timer channel.

go
1select {
2case <-time.After(50 * time.Millisecond):
3    fmt.Println("Timer fired")
4case <-ctx.Done():
5    fmt.Println("Cancelled")
6}

C++

C++11 introduced std::this_thread::sleep_for in the <thread> header.

cpp
1#include <iostream>
2#include <thread>
3#include <chrono>
4
5int main() {
6    std::cout << "Before delay\n";
7    std::this_thread::sleep_for(std::chrono::milliseconds(50));
8    std::cout << "After 50ms delay\n";
9    return 0;
10}

The chrono duration types provide compile-time safety. You cannot accidentally pass seconds when you mean milliseconds because the types are distinct. For POSIX systems, usleep(50000) (microseconds) also works but is considered legacy.

Rust

Rust's standard library provides std::thread::sleep for blocking and tokio::time::sleep for async code.

rust
1use std::thread;
2use std::time::Duration;
3
4fn main() {
5    println!("Before delay");
6    thread::sleep(Duration::from_millis(50));
7    println!("After 50ms delay");
8}

In async Rust with Tokio, use the non-blocking alternative.

rust
1use tokio::time::{sleep, Duration};
2
3#[tokio::main]
4async fn main() {
5    println!("Before delay");
6    sleep(Duration::from_millis(50)).await;
7    println!("After 50ms delay");
8}

The blocking thread::sleep inside an async runtime starves the executor. Always use the runtime-provided sleep in async contexts.

Common Pitfalls

  • Assuming exact precision: Operating system schedulers introduce jitter. A 50 ms sleep may wake after 51-65 ms depending on system load, timer resolution, and power-saving settings.
  • Blocking the event loop: In JavaScript and async Python, using synchronous sleep (or a busy-wait loop) blocks the entire event loop and prevents other tasks from executing.
  • Ignoring InterruptedException in Java: Swallowing InterruptedException with an empty catch block breaks thread interruption contracts and makes graceful shutdown impossible.
  • Using Thread.Sleep in ASP.NET request handlers: Blocking a thread-pool thread under load causes thread starvation. Use await Task.Delay() instead to free the thread for other requests.
  • Busy-waiting instead of sleeping: A while loop that repeatedly checks the clock consumes 100% CPU. Always use the platform sleep primitive to yield the processor.

Summary

  • Every major language provides a sleep or delay API that accepts a duration in seconds, milliseconds, or a typed duration value.
  • Prefer non-blocking, async-aware variants (asyncio.sleep, Task.Delay, tokio::time::sleep) in event-driven or async applications.
  • OS scheduler granularity means sleep durations are minimum guarantees, not exact promises.
  • Pass cancellation tokens or use context-aware patterns to make delays interruptible for graceful shutdown.
  • Never busy-wait as a substitute for sleeping; it wastes CPU resources and degrades system performance.

Course illustration
Course illustration

All Rights Reserved.