Guides

bash sleep command: wait seconds, minutes or forever, in loops and on Windows

The bash sleep command: seconds, minutes and fractions, sleep infinity, retry loops until a port opens, sleep vs timeout vs wait, and Windows timeout.

Published ~7 min read
On this page

Short answer: sleep 5 pauses a bash script or the shell for five seconds. GNU sleep, the version on Debian, Ubuntu, Rocky Linux and AlmaLinux, also takes suffixes (s, m, h, d), fractions (sleep 0.5) and several values that add up (sleep 1m 30s). On Windows, use timeout /t 5 in cmd or Start-Sleep -Seconds 5 in PowerShell.

bash · any Linux
sleep 5            # 5 seconds
sleep 0.5          # half a second (GNU sleep)
sleep 2m           # 2 minutes; also h for hours, d for days
sleep 1m 30s       # several arguments are added: 90 seconds
sleep infinity     # never returns; stop it with Ctrl+C or kill

The timings and messages below come from GNU coreutils 9.1 and bash 5.2.15 on Debian 12, measured with time in a scratch directory on 21 October 2026, with short durations only. The Windows commands follow Microsoft Learn (the timeout page and the Start-Sleep reference for PowerShell 7.5) as of October 2026.

bash sleep cheat sheet

TaskCommand
Wait N secondssleep 10
Wait less than a secondsleep 0.2
Wait minutes or hourssleep 5m
Combine unitssleep 1h 30m
Wait foreversleep infinity
Random delay of 0 to 30 s, any shellsleep $(shuf -i 0-30 -n 1)
Retry until something is upuntil CHECK; do sleep 2; done
Stop a command after N secondstimeout 30 COMMAND
Wait for background jobswait
Windows cmdtimeout /t 10 /nobreak
Windows PowerShellStart-Sleep -Seconds 10

Seconds, minutes, fractions and several arguments

A bare number is seconds. GNU sleep reads s, m, h and d as seconds, minutes, hours and days, accepts decimals, and adds up all its arguments. Measured:

bash · Debian 12
$ time sleep 0.5
real    0m0.501s
$ time sleep 0.2 0.3
real    0m0.501s
$ time sleep 0.01m
real    0m0.601s

Wrong input fails at once with exit status 1, which a script can catch:

bash · Debian 12 (the Try 'sleep --help' lines left out)
$ sleep
sleep: missing operand
$ sleep 1x
sleep: invalid time interval ‘1x’
$ sleep -1
sleep: invalid option -- '1'

POSIX only promises a whole number of seconds. Suffixes, fractions and several arguments are GNU additions, so a script that must also run on BusyBox (Alpine images) or a BSD should check sleep --help there, or stick to integers. sleep 0 returns immediately and is valid everywhere.

sleep infinity

sleep infinity (or sleep inf) never returns on its own. It is the usual way to keep a container running with nothing else in it, for example docker run -d debian:12 sleep infinity for a box you then enter with docker exec; the docker run guide explains -d and docker exec. It ends on a signal like any process: timeout 1 sleep infinity returned after one second with status 124, and a sleep killed with plain kill (SIGTERM) reported 143, which is 128 plus signal 15.

sleep in a loop: wait until a port is open

The common real use is polling: try something, wait, try again. Waiting for a database before starting an app:

bash
until nc -z 127.0.0.1 5432; do
  echo "waiting for PostgreSQL..."
  sleep 2
done
echo "port 5432 is open"

nc -z only tests whether the port accepts a connection; the port check guide explains its output and what to install. Without netcat, bash can open the connection itself: until (exec 3<>/dev/tcp/127.0.0.1/5432) 2>/dev/null; do sleep 2; done. An endless loop is a bad idea in a deploy script, so give it a limit. Either count the tries, or wrap the whole loop in timeout:

bash
# give up after 30 tries (about a minute)
for i in $(seq 1 30); do
  nc -z 127.0.0.1 5432 && break
  [ "$i" -eq 30 ] && { echo "gave up" >&2; exit 1; }
  sleep 2
done

# or: one overall limit of 60 seconds, exit status 124 on timeout
timeout 60 bash -c 'until nc -z 127.0.0.1 5432; do sleep 2; done'

The loop logic was checked here with a file in place of the port: an until loop waiting for a file that a background job created after 0.4 seconds printed waiting twice and stopped, and timeout 1 around a loop whose condition never came true ended with status 124. The nc and /dev/tcp checks follow their documentation. Print progress with echo as above (the echo guide has the timestamp form for logs).

Running something every N seconds

while true; do ./check.sh; sleep 60; done works, but it drifts by the run time of the check and dies with your SSH session. For anything that should keep running, a cron job or a systemd timer is the better tool. cron cannot go below one minute; the usual trick for a 30-second rhythm is two lines, * * * * * /path/job and * * * * * sleep 30; /path/job.

sleep in the background, wait and signals

bash · Debian 12 (job messages left out)
$ date +%T.%N | cut -c1-12; sleep 0.3 & sleep 0.6 & wait; date +%T.%N | cut -c1-12
22:55:24.670
22:55:25.272

wait without arguments waits for every background job, so the two sleeps overlapped and the whole line took 0.6 seconds, not 0.9. wait $! waits for the last job only and returns its exit status. A long sleep started with & in an SSH session can be killed when the session ends; the nohup guide explains why and how to keep it.

One behaviour matters for scripts that run as services or in containers. bash runs a trap only after the foreground command has finished. A script with trap '...; exit' TERM that was inside sleep 3 when it got SIGTERM reacted 2.5 seconds later, when the sleep ended. Written as sleep 3 & wait $!, the same script reacted at once, because wait returns as soon as a trapped signal arrives. With long sleeps, that is the difference between a clean shutdown and docker stop or systemd giving up and sending SIGKILL.

sleep vs timeout vs wait

ToolWhat it doesUse it for
sleep NWaits a fixed time, runs nothingPauses between retries, rate limits, delays
timeout N cmdRuns cmd and stops it after N (exit 124)Commands that could hang: network calls, polling loops
waitWaits until background jobs of this shell finishRunning steps in parallel, then continuing
cron, systemd timerStarts a command on a scheduleAnything repeated: backups, checks, reports

timeout sends SIGTERM by default; timeout -k 5 30 cmd follows up with SIGKILL five seconds later if the command ignores it. It is also part of GNU coreutils.

A random delay

A random delay spreads jobs out so that many servers do not hit the same API in the same second. In bash, $RANDOM gives a number from 0 to 32767:

bash
sleep $((RANDOM % 30))            # 0 to 29 seconds, bash only
sleep "$(shuf -i 0-30 -n 1)"      # 0 to 30 seconds, any shell (GNU coreutils)

Windows: timeout and Start-Sleep

cmd.exe has no sleep. The built-in pause with a time limit is timeout; per Microsoft Learn it takes a value from -1 to 99999 seconds, and a key press ends the wait early unless you add /nobreak:

cmd · batch file
rem wait 10 seconds, a key press skips it
timeout /t 10
rem wait 10 seconds and ignore key presses (Ctrl+C still works)
timeout /t 10 /nobreak
rem wait until a key is pressed
timeout /t -1

timeout needs a console for its input. Run from a context where input is redirected, it stops at once with ERROR: Input redirection is not supported, exiting the process immediately. The old workaround, ping -n 6 127.0.0.1 > nul, waits about five seconds (one second between six pings), or call PowerShell from the batch file: powershell -NoProfile -Command "Start-Sleep -Seconds 5".

PowerShell
Start-Sleep -Seconds 5
Start-Sleep -Milliseconds 500
Start-Sleep -Seconds 1.5                                 # fractions: PowerShell 6.2 and later
Start-Sleep -Duration (New-TimeSpan -Minutes 2)          # PowerShell 7.3 and later

sleep is an alias of Start-Sleep on Windows only; in PowerShell on Linux, sleep runs the GNU program. Windows Server ships Windows PowerShell 5.1 (PowerShell 7 is a separate install), where -Seconds takes whole numbers, so use -Milliseconds there for fractions of a second.

sleep on a server

  • Do not build a supervisor out of sleep. while true; do ./app; sleep 5; done restarts a crashed app, but it does not start after a reboot and has no logs. A systemd unit with Restart=on-failure and RestartSec=5 does the same properly, as shown in creating a systemd service.
  • Rate-limit loops that call outside services. A sleep 1 inside a loop over hundreds of API calls or downloads keeps you under rate limits and out of abuse filters.
  • Delay at boot only when you must. @reboot sleep 60 && ... in a crontab is a workaround for a missing dependency; a systemd unit with After=network-online.target waits for the actual condition.

On a Linux VPS you have root and systemd for all of the above, and a background loop costs next to nothing while it sleeps: sleep used about 0.001 seconds of CPU time in every measurement on this page. More everyday commands are in the Linux commands cheat sheet.

Frequently asked

How do I sleep for less than a second in bash?

Use a decimal: sleep 0.5 waits half a second and sleep 0.1 a tenth. GNU sleep, the version on Debian, Ubuntu, Rocky Linux and AlmaLinux, accepts fractions; POSIX only promises whole seconds, so check sleep --help on BusyBox or BSD systems.

How do I sleep for minutes or hours in bash?

Add a suffix: sleep 5m waits five minutes, sleep 2h two hours and sleep 1d a day. Several values are added up, so sleep 1m 30s waits 90 seconds. A bare number means seconds.

What is the difference between sleep and timeout?

sleep only waits a fixed time and runs nothing. timeout runs a command and stops it if it is still running after the given time, returning exit status 124. Use sleep between retries and timeout around commands that might hang.

What is the Windows equivalent of sleep?

In cmd and batch files use timeout /t 10, adding /nobreak so a key press does not end the wait. In PowerShell use Start-Sleep -Seconds 10 or Start-Sleep -Milliseconds 500. On Windows, sleep is also an alias for Start-Sleep in PowerShell.

Related articles

All guides