How to wait in Python
Learn how to make your Python script wait. Explore different methods, tips, real-world examples, and common error debugging.

To pause code execution in Python is a fundamental skill. It's essential when you need to manage resources, synchronize tasks, or handle API rate limits.
In this article, you'll explore several techniques to implement delays, from simple time.sleep() calls to more advanced methods. You'll find real-world applications, performance tips, and debugging advice.
Using time.sleep() for basic waiting
import time
print("Starting...")
time.sleep(2) # Wait for 2 seconds
print("...done waiting!")--OUTPUT--Starting...
...done waiting!
The time.sleep() function is the most direct way to pause your script. It's part of Python's standard time module and tells the program to halt execution for a specified duration. The argument you pass is the number of seconds to wait; in this case, 2. You can also use floating-point numbers for more precise delays when implementing delays in Python.
This function is incredibly useful for managing timing-sensitive tasks. You might use it to:
- Pace requests to an external API to stay within rate limits.
- Wait for a background process, like a file download, to complete.
- Simulate delays in a user interface or game.
Basic waiting techniques
Building on the simple time.sleep() function, you can create more flexible delays or even schedule code to run after a specific waiting period.
Using time.sleep() with dynamic values
import time
wait_seconds = 1.5
print(f"Waiting for {wait_seconds} seconds...")
time.sleep(wait_seconds)
print("Wait completed!")--OUTPUT--Waiting for 1.5 seconds...
Wait completed!
You aren't limited to using fixed numbers with time.sleep(). Passing a variable, like wait_seconds in the example, makes your code far more adaptable. The delay can be calculated or changed while your script runs, rather than being hardcoded.
- This is perfect for implementing retry logic where you increase the wait time after each failed attempt.
- You can also adjust delays based on user input or system load.
- Some APIs even tell you exactly how long to wait before your next request.
Creating a simple countdown timer
import time
seconds = 3
print("Countdown starting...")
while seconds > 0:
print(seconds)
seconds -= 1
time.sleep(1)
print("Blast off!")--OUTPUT--Countdown starting...
3
2
1
Blast off!
By combining a while loop with time.sleep(), you can build a simple timer. The loop runs as long as seconds > 0, printing the current count in each iteration. This demonstrates practical applications of using while loops in Python. The time.sleep(1) call ensures there's a one-second pause between each number, creating the countdown effect.
- This technique is useful for more than just timers. You can adapt it to poll a service for updates or to create simple, timed animations in a console application.
Using threading.Timer for delayed execution
import threading
def delayed_message():
print("This message appears after the delay")
timer = threading.Timer(2.0, delayed_message)
timer.start()
print("This message appears immediately")--OUTPUT--This message appears immediately
This message appears after the delay
For delays that don't block your main program, you can use threading.Timer. It schedules a function to run after a specified interval in a separate thread, allowing your script to continue executing other code immediately.
- The
Timerobject takes two main arguments: the delay in seconds and the function to execute, likedelayed_message. - Unlike
time.sleep(), it’s non-blocking. Notice how the final message prints right away without waiting for the timer to finish. - You must call the
start()method to actually begin the countdown in the background.
Advanced waiting techniques
Beyond basic pauses, you'll need more advanced control for handling asynchronous tasks, waiting for specific conditions, or managing interruptions gracefully.
Using asyncio for asynchronous waiting
import asyncio
async def wait_async():
print("Starting async wait...")
await asyncio.sleep(1)
print("Async wait complete!")
asyncio.run(wait_async())--OUTPUT--Starting async wait...
Async wait complete!
For modern, concurrent applications, Python's asyncio library is your go-to. The asyncio.sleep() function provides a non-blocking pause. This means that while one part of your program waits, the event loop can run other tasks, making your application much more memory-efficient.
- Functions defined with
async defbecome coroutines, which can be paused and resumed. - The
awaitkeyword is used to pause the coroutine—in this case, for theasyncio.sleep()call. - Finally,
asyncio.run()starts the event loop and executes your main coroutine.
Waiting for a specific condition
import time
start_time = time.time()
target_time = start_time + 3
while time.time() < target_time:
time.sleep(0.5)
print(f"Still waiting... ({round(target_time - time.time(), 1)} seconds left)")
print("Condition met!")--OUTPUT--Still waiting... (2.5 seconds left)
Still waiting... (2.0 seconds left)
Still waiting... (1.5 seconds left)
Still waiting... (1.0 seconds left)
Still waiting... (0.5 seconds left)
Condition met!
Instead of a fixed delay, you can use a while loop to wait until a specific condition is met. This example polls for a condition—in this case, whether the current time has passed a target_time. The loop continues as long as time.time() < target_time is true, checking the condition repeatedly. For more details on using time in Python, you can explore various time-related functions.
- The
time.sleep(0.5)call inside the loop is crucial. It prevents your script from consuming excessive CPU by adding a pause between each check. - This pattern is highly flexible. You can adapt it to wait for a file to exist or for a network connection to become available.
Using time.sleep() with keyboard interrupt handling
import time
try:
print("Waiting for 10 seconds (press Ctrl+C to interrupt)...")
time.sleep(10)
print("Wait completed successfully")
except KeyboardInterrupt:
print("\nWait was interrupted by user")--OUTPUT--Waiting for 10 seconds (press Ctrl+C to interrupt)...
^C
Wait was interrupted by user
Sometimes you need to let a user interrupt a long wait. By wrapping time.sleep() in a try...except block, you can gracefully handle these situations. This follows the same patterns for using try and except in Python. When a user presses Ctrl+C, Python raises a KeyboardInterrupt exception, which your code can then catch and handle.
- The
exceptblock catches this specific interruption, allowing your script to run cleanup code or print a message instead of crashing. - This pattern is essential for creating responsive command-line tools that don't force users to wait unnecessarily.
Move faster with Replit
Replit is an AI-powered development platform that comes with all Python dependencies pre-installed, so you can skip setup and start coding instantly. Describe what you want to build, and Agent 4 handles everything—from writing the code to connecting databases and deploying it live.
Instead of piecing together techniques, describe the app you want to build and Agent will take it from idea to working product:
- An API polling utility that periodically checks an endpoint for new data, managing the interval between requests to avoid overloading the server.
- A simple web scraper that automatically adds delays between requests to respect a site's rate limits and prevent being blocked.
- A command-line countdown timer that can be stopped early by the user without crashing the program.
Simply describe your app, and Replit will write the code, test it, and fix issues automatically, all within your browser.
Common errors and challenges
While pausing your code is straightforward, you might run into a few common pitfalls that can trip up even experienced developers.
- Fixing the common error with
time.sleep()units: A frequent mistake is confusing the units. Thetime.sleep()function always expects the delay in seconds, not milliseconds. If you pass1000thinking it's one second, your script will actually pause for over 16 minutes. - Troubleshooting missing
timemodule imports: If you try to usetime.sleep()without importing thetimemodule, your script will fail with aNameError. The fix is simple—just addimport timeat the top of your file to make the module's functions available. - Avoiding cumulative delays in loops: When you use
time.sleep()in a loop, the execution time of your other code adds to the sleep duration, causing drift. To maintain a consistent interval, calculate the sleep time dynamically based on when the next iteration is supposed to start.
Fixing the common error with time.sleep() units
It's easy to forget that time.sleep() measures delays in seconds, not milliseconds. Passing a value like 200 won't create a brief pause. Instead, it will halt your script for over three minutes. See this common error in action below.
import time
# Attempting to wait for 200 milliseconds
time.sleep(200)
print("This will print after an unexpectedly long time!")
Because time.sleep() expects seconds, passing 200 creates a pause of over three minutes, not the intended 200 milliseconds. This is a common source of bugs. The example below shows the correct way to achieve this.
import time
# Correctly waiting for 200 milliseconds
time.sleep(0.2)
print("This will print after 200 milliseconds!")
The solution is to express the delay in seconds. To wait for 200 milliseconds, you pass 0.2 to time.sleep(). This is especially important when you're working with external services or APIs, as they often specify wait times in milliseconds. Always remember to convert these values to seconds by dividing by 1000 to avoid unexpectedly long pauses in your script.
Troubleshooting missing time module imports
It's a classic slip-up: you try to call sleep() but forget to tell Python where to find it. This results in a NameError because the function isn't available until you import the time module. Check out the example below.
# Common error: Forgetting to import the time module
sleep(2) # NameError: name 'sleep' is not defined
print("This won't execute due to the error")
Since the sleep() function isn't a built-in, Python doesn't know where to find it without the proper context. This is what causes the NameError. The following example demonstrates the simple fix.
import time
# Correct usage with proper import
time.sleep(2)
print("This will execute after 2 seconds")
The solution is to add import time at the start of your script. This statement makes the module's functions available, so you can call time.sleep() without a NameError. It’s a common oversight, especially when quickly scripting or reusing code snippets. Always ensure you’ve imported any modules you need before using their functions.
Avoiding cumulative delays when using time.sleep() in loops
When you use time.sleep() inside a loop to create a regular interval, you might notice your timing slowly drifts. This happens because the execution time of other code in the loop adds to the delay, creating a cumulative error.
import time
start_time = time.time()
for i in range(5):
print(f"Iteration {i}")
time.sleep(1) # Fixed sleep causes cumulative timing drift
print(f"Total time: {time.time() - start_time:.2f} seconds")
The fixed one-second pause doesn't account for the time taken by the print() function. This small overhead accumulates with each loop, causing the total execution time to exceed five seconds. The following example demonstrates a more precise approach.
import time
start_time = time.time()
for i in range(5):
iteration_start = time.time()
print(f"Iteration {i}")
elapsed = time.time() - iteration_start
sleep_time = max(0, 1 - elapsed) # Adjust sleep time based on work done
time.sleep(sleep_time)
print(f"Total time: {time.time() - start_time:.2f} seconds")
The solution is to calculate the sleep duration dynamically. At the start of each loop, you measure how long your code takes to run. You then subtract that elapsed time from your target interval—in this case, one second. The result is the precise duration to pass to time.sleep(). This approach guarantees a consistent rhythm, which is crucial for tasks like polling a service or creating stable animations where timing accuracy is key.
Real-world applications
With the common pitfalls handled, you can use these techniques to build robust data pipelines and reliable retry mechanisms.
Using time.sleep() in a data processing pipeline
When building a data pipeline, time.sleep() helps you control the processing pace, ensuring that you don't overwhelm other services or hit API rate limits. This is particularly important when calling APIs in Python.
import time
def process_data(item):
print(f"Processing item: {item}")
time.sleep(1) # Simulate processing time
return f"Result: {item * 2}"
data = [5, 10, 15]
results = []
for item in data:
result = process_data(item)
results.append(result)
print(result)
time.sleep(0.5) # Brief pause between items
This example shows how you can use time.sleep() to manage timing in two distinct ways. The process_data function includes a one-second pause to simulate a task that takes time to complete, like a network request or a complex calculation.
- The main loop iterates through the
datalist, calling this function for each item. - After each item is processed, an additional
time.sleep(0.5)call introduces a brief, consistent delay. It's a useful way to add a deliberate pause between sequential tasks.
Creating a retry mechanism with time.sleep()
A retry mechanism using time.sleep() is an effective way to handle temporary failures, giving an operation another chance to succeed after a short pause.
import time
import random
def unstable_operation():
# Simulate operation that sometimes fails
if random.random() < 0.7:
print("Operation failed!")
return False
print("Operation successful!")
return True
max_attempts = 3
attempt = 1
while attempt <= max_attempts:
if unstable_operation():
break
retry_delay = attempt * 2
print(f"Retrying in {retry_delay} seconds...")
time.sleep(retry_delay)
attempt += 1
This script demonstrates a smart retry strategy for an operation that might fail. The while loop attempts the unstable_operation() up to three times. If the function succeeds, the loop immediately stops with a break statement.
- If the operation fails, the script calculates a
retry_delaythat increases with each attempt. This is a great way to avoid hammering a service with rapid requests. - The
time.sleep()function then pauses execution for that calculated duration before trying again, giving the service time to recover.
Get started with Replit
Put these techniques to work by building a real tool. Just tell Replit Agent: "build a site status checker that pings a URL every 5 minutes" or "create a script that retries uploads with a delay".
Replit Agent writes the code, tests for errors, and deploys your app directly from your browser. Start building with Replit.
Describe what you want to build, and Replit Agent writes the code, handles the infrastructure, and ships it live. Go from idea to real product, all in your browser.
Describe what you want to build, and Replit Agent writes the code, handles the infrastructure, and ships it live. Go from idea to real product, all in your browser.



