rguides

Sys.sleep

Sys.sleep(time)

Signature

Sys.sleep(time)

Parameters

ParameterTypeDescription
timenumericA positive number of seconds to suspend execution. Fractional values (e.g. 0.5) are accepted.

Passing a non-positive value, zero, or a non-numeric type produces an error.

Return value

Invisible NULL. This function is called purely for its side effect, it does not return useful data.

Behavior

Sys.sleep suspends the R process for the requested number of seconds. The process yields its CPU during this time, so it is not busy-waiting.

In interactive GUI sessions, R wakes roughly every 0.5 seconds to handle GUI events. This means the pause is not a full system block in GUIs like RStudio, GUI interactions may still register when they coincide with these wake cycles.

On all platforms (Windows, macOS, Linux), behavior is identical.

Code examples

Basic pause

start <- proc.time()
Sys.sleep(1.5)
elapsed <- proc.time() - start
print(elapsed)
##   user  system elapsed 
##  0.00    0.00    1.502

The elapsed column reports actual wall-clock time rather than CPU time, which is what matters when coordinating with external systems. The slight difference between the requested 1.5 seconds and the measured 1.502 seconds reflects OS scheduling granularity — the kernel schedules processes in discrete time slices, so Sys.sleep may overshoot by a few milliseconds. This imprecision is harmless for rate-limiting but makes the function unsuitable as a benchmark timer.

Rate-limiting a loop

# Simulate fetching 3 pages, pausing 1 second between each
for (page in 1:3) {
  cat("Fetching page", page, "...\n")
  # fetch_page(page)  # your actual HTTP call goes here
  Sys.sleep(1)
}
# Fetching page 1 ...
# Fetching page 2 ...
# Fetching page 3 ...

This is a blunt but readable way to space out repeated calls, such as polling an API. A fixed one-second pause works for low-frequency requests, but for production-grade retry logic you typically want a strategy that backs off after each failure. Exponential backoff increases the wait time after each consecutive failure, reducing the load on a struggling server while still retrying to recover from transient outages. The pattern below doubles the wait with each attempt.

Retry with exponential backoff

fetch_with_retry <- function(url, max_attempts = 4) {
  for (attempt in 1:max_attempts) {
    # if (check_server(url)) break  # replace with your health check
    wait_seconds <- 2^attempt        # 2, 4, 8, 16 seconds
    cat("Attempt", attempt, "failed. Retrying in", wait_seconds, "s...\n")
    Sys.sleep(wait_seconds)
  }
  cat("All attempts exhausted.\n")
}

fetch_with_retry("https://example.com/api")
# Attempt 1 failed. Retrying in 2 s...
# Attempt 2 failed. Retrying in 4 s...
# Attempt 3 failed. Retrying in 8 s...
# Attempt 4 failed. Retrying in 16 s...
# All attempts exhausted.

Exponential backoff spaces retries further apart as failures continue, which reduces load on a struggling server. In practice you replace the placeholder condition with a real health check — an HTTP GET to a status endpoint — and break out of the loop when the server responds. You might also cap the maximum wait at 60 seconds so that retries do not become unreasonably long. The Sys.sleep() call enforces the delay between each attempt.

Timing a block with a simulated delay

t0 <- Sys.time()
# your expensive computation here
Sys.sleep(0.75)  # simulate a brief network round-trip
t1 <- Sys.time()
cat("Approximate elapsed:", round(t1 - t0, 2), "seconds\n")
# Approximate elapsed: 0.75 seconds

Sys.sleep is not a precision timer, use microbenchmark or proc.time() for benchmarks. OS scheduler granularity varies, so actual sleep duration may be slightly longer than requested, especially under system load.

Common mistakes

Confusing seconds with milliseconds. JavaScript’s setTimeout uses milliseconds. A common slip is writing Sys.sleep(500) expecting half a second. That sleeps for 500 seconds. Use Sys.sleep(0.5) for half a second.

Using sleep as a benchmark timer. Sys.sleep is not accurate enough for performance measurement. The OS scheduler may delay execution beyond the requested duration. For timing code, use proc.time() or microbenchmark::microbenchmark() instead.

Assuming sleep compounds in parallel workers. When using parallel::mclapply(), each worker runs its own Sys.sleep independently. The wall-clock time of the whole operation is the maximum of the workers’ sleeps, not the sum. Don’t assume a 1-second sleep inside each of 8 workers adds 8 seconds to total runtime.

Forgetting fractional seconds. Sys.sleep(1) sleeps for 1 second. If you need 200 milliseconds, write Sys.sleep(0.2).

See also

  • Sys.time(), get the current wall-clock time, useful for measuring elapsed intervals
  • seq() — generate sequences, often used with Sys.sleep() to pace iterations