Kernel#sleep
sleep([duration]) -> integer or nil Kernel#sleep suspends the current thread’s execution for the specified number of seconds. If no duration is given, it sleeps indefinitely until interrupted. Returns the number of seconds actually slept, or nil if interrupted by a signal.
Syntax
sleep(duration)
sleep
The two forms are simple: pass a number to pause for that many seconds, or pass nothing to sleep indefinitely until a signal arrives. Ruby stores the duration as a Numeric, so you can use integers for whole seconds or floats for sub-second precision without any special configuration.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
duration | Numeric | nil | Number of seconds to sleep. Can be fractional for sub-second precision. If nil or omitted, sleeps indefinitely. |
Examples
Basic usage
puts "Starting"
sleep(2)
puts "Woke up after 2 seconds"
# Starting
# Woke up after 2 seconds
The simplest form of sleep takes an integer argument and pauses for exactly that many seconds. This is the form you reach for when a script needs to wait for a fixed amount of time — between retries, before reading a file that another process is writing, or to pace a sequence of printed messages so they are readable.
Sleeping for fractional seconds
start = Time.now
sleep(0.5) # sleep for 500 milliseconds
puts Time.now - start
# => 0.5
Ruby accepts fractional seconds as a Float, so sub-second precision is available without any special configuration. The actual sleep duration may be slightly longer than requested due to operating system scheduling, but for most timing tasks — rate limiting, polling, animation pacing — the difference is too small to matter.
Sleeping indefinitely
# This runs until interrupted
sleep
An indefinite sleep with no argument puts the thread to rest until a signal arrives, which is useful in daemon processes or scripts that wait for an external trigger. Without a duration, the call blocks forever, so this form should only appear in code that expects to be woken by a signal handler or an interrupt.
Using sleep in a loop
5.times do |i|
puts "Count: #{i}"
sleep(1)
end
# Count: 0
# Count: 1
# Count: 2
# Count: 3
# Count: 4
A one-second pause inside a counting loop creates a visible rhythm that makes the output easy to follow in the terminal. In real applications, the delay would usually be shorter or driven by an external event, but the structure is the same: the loop body does work, then sleep yields control before the next iteration begins.
Common Patterns
Polling interval
def poll_until(condition, interval: 1, timeout: 30)
elapsed = 0
while elapsed < timeout
return yield if yield
sleep(interval)
elapsed += interval
end
nil
end
# Usage: wait for a file to exist
poll_until { File.exist?('/tmp/ready') }
Polling with sleep avoids busy-waiting, which would spin the CPU at full speed while checking a condition that changes only occasionally. The interval gives the external resource time to become ready and keeps the CPU load low. The timeout parameter adds a safety net so the loop cannot run forever if the condition never becomes true.
Rate limiting
requests = ['req1', 'req2', 'req3']
requests.each do |req|
process(req)
sleep(0.5) # rate limit to 2 requests per second
end
Retry with backoff
When a transient failure is likely to clear after a short wait, exponential backoff is a safer strategy than hammering the failing service at a fixed interval. Each retry doubles the delay, giving the remote system breathing room while the local code keeps trying:
def retry_with_backoff(max_attempts: 3)
attempt = 0
begin
attempt += 1
yield
rescue => e
if attempt < max_attempts
sleep(2 ** attempt) # 2, 4, 8 seconds
retry
else
raise e
end
end
end
Errors
- ArgumentError: Raised if duration is negative.
- ThreadError: May be raised if sleeping while the thread is being killed.
pausing with a clear purpose
sleep is most useful when the pause itself is part of the behavior, such as polling, simple retries, or pacing a loop so it does not run too fast. The code should make that reason visible, because an unexplained pause can look like a bug. Keeping the delay small and intentional makes it easier to test and easier to remove later if the timing strategy changes. That is especially true in scripts that only need to wait long enough for the next step to be ready.
The method also pairs well with loops that need to check for a condition without using busy waiting. A short pause can give a resource time to appear, give a background task time to finish, or give the user a moment before the next retry. The important part is that the wait belongs to the task, not just to the code style. When the reason is clear, sleep reads like part of the plan instead of a mystery delay.
It is also worth keeping the duration visible near the logic that depends on it. That way the reader can tell whether the pause is a tiny pacing step or a more deliberate wait. If the timing starts to spread across several methods, it can become hard to tell why the code is idle. A simple, local pause is easier to explain and easier to change when the task no longer needs it.