opscape

Processes and jobs

sleep

Pause for a given amount of time, in seconds by default, with m, h and d suffixes and fractions allowed.

sleep NUMBER[SUFFIX]...

9 of 9 examples run in Debian 13.7 on 2026-10-31 · coreutils 9.7-3 · manual: sleep(1)

sleep 5 does nothing for five seconds and exits 0. It is the delay in retry loops, polling loops and rate-limited scripts, and the stand-in for "some long-running process" in examples across this site. GNU sleep accepts fractions (0.25), the suffixes s, m, h and d, several arguments that are added together (sleep 1m 30s), and infinity.

sleep is an external program, not a builtin, so in a shell it can be killed and interrupted like any process: Ctrl-C stops it, and a script blocked in sleep does not run its signal traps until sleep returns. The sleep N & wait $! idiom fixes that, as shown below.

For waiting until something is true (a file appears, a port opens), a loop with a short sleep and a test is the usual shape; add a counter or wrap it in timeout so it cannot loop forever. To wait for your own background jobs, use wait instead of guessing a duration.

Examples

Pause between two commands

date +%T
sleep 2
date +%T
output
20:20:49
20:20:51

Two seconds pass between the timestamps. sleep prints nothing; its whole effect is the delay.

Sleep for a fraction of a second

start=$(date +%s%N)
sleep 0.25
echo "slept $(( ($(date +%s%N) - start) / 1000000 )) ms"
output
slept 254 ms

GNU sleep takes decimal fractions. The measured time is slightly over 250 ms because starting the processes takes a moment too.

Use units and add durations together

time sleep 0.5s 0.25 0.005m
explain
output

real	0m1.052s
user	0m0.000s
sys	0m0.002s

Each argument may carry a suffix (s, m, h, d), and multiple arguments are summed: 0.5 s + 0.25 s + 0.3 s (0.005 minutes) = 1.05 s, as the bash time report shows.

Retry a command with a delay

for attempt in 1 2 3 4 5; do
  if [ -e ready.flag ]; then echo "ready after $attempt attempts"; break; fi
  echo "attempt $attempt: not ready, waiting"
  [ "$attempt" -eq 2 ] && touch ready.flag
  sleep 0.5
done
output
attempt 1: not ready, waiting
attempt 2: not ready, waiting
ready after 3 attempts

The standard poll-and-wait loop: test, sleep, try again, with a fixed number of attempts so it cannot hang. The touch on attempt 2 stands in for another process creating the file.

Back off exponentially between retries

delay=0.1
for attempt in 1 2 3 4; do
  echo "attempt $attempt failed, sleeping ${delay}s"
  sleep "$delay"
  delay=$(echo "$delay * 2" | bc)
done
output
attempt 1 failed, sleeping 0.1s
attempt 2 failed, sleeping .2s
attempt 3 failed, sleeping .4s
attempt 4 failed, sleeping .8s

Doubling the delay after each failure is kinder to a struggling server than hammering it. Shell arithmetic is integer-only, so bc doubles the fractional value. bc drops the leading zero (.2), which sleep accepts as it is.

Slow down a loop over many items

for host in web01 web02 db01; do
  echo "$(date +%T.%N | cut -c1-12) checking $host"
  sleep 0.3
done
output
20:20:55.260 checking web01
20:20:55.567 checking web02
20:20:55.871 checking db01

A short sleep per iteration keeps a loop from flooding an API or a log. The timestamps are about 0.3 seconds apart.

Make a sleeping script respond to signals at once

waiter.sh
#!/bin/bash
trap 'echo "got TERM, exiting"; exit 0' TERM
sleep 30 &
wait $!
bash waiter.sh &
sleep 0.3
time { kill $!; wait $!; }
output
got TERM, exiting

real	0m0.001s
user	0m0.001s
sys	0m0.003s

A script in a plain foreground sleep 30 runs its trap only after sleep ends. Sleeping in the background and blocking in wait lets the trap fire immediately, as the near-zero time shows. The background sleep is left to finish on its own; kill it in the trap if that matters.

Sleep forever

sleep infinity &
ps -o pid,args -p $!
kill $!
output
    PID COMMAND
   2604 sleep infinity

infinity (GNU) never returns on its own. It is common as a container's main process to keep it alive, and as a placeholder that something else will kill.

Invalid durations

sleep 5x
explain
outputexit 1
sleep: invalid time interval ‘5x’
Try 'sleep --help' for more information.

An unknown suffix or non-number is rejected with invalid time interval and exit status 1. Negative numbers are rejected too (the - is read as an option).

Common pitfalls

  • Polling with no upper bound. while ! test; do sleep 1; done hangs forever when the condition never comes true; count attempts or wrap the loop in timeout.

  • Using a fixed sleep to wait for a background job you started. Use wait $pid: it returns exactly when the job ends and gives you its exit status.

  • Expecting traps to run while a script sits in a foreground sleep. Bash runs the trap only after the sleep ends; use sleep N & wait $!.

  • Writing sleep 1m30s. The suffix applies to one number per argument; write sleep 1m 30s or sleep 90.

GNU vs BSD and macOS

The examples above ran the GNU/Linux version. These are the differences that matter on macOS and the BSDs (written from their documentation, not run here).

  • POSIX only guarantees whole seconds. GNU, macOS and FreeBSD sleep accept fractions, but suffixes (5m), several arguments and infinity are GNU features. sleep 300 works everywhere.

Related