Skip to content

Why Does time.sleep() Break Python Async Code? Fix Event Loop Blocking

Problem

When I wrote an async Python application, I used time.sleep() for delays. The entire application became frozen and unresponsive. Other async tasks stopped running during the sleep period.

Here’s what I saw:

Console output
Task 1 starting...
[Application frozen for 1 second - no other output]
Task 1 completed.
Task 2 starting...
[Application frozen again]

Environment

  • Python 3.11
  • asyncio for async programming
  • Ubuntu 22.04

What happened?

I wrote an async function that uses time.sleep() for a delay:

bad_sleep_example.py
import asyncio
import time
async def task(name):
print(f"{name} starting...")
time.sleep(1) # This is the problem!
print(f"{name} completed.")
async def main():
# Two tasks running concurrently
await asyncio.gather(task("Task 1"), task("Task 2"))
asyncio.run(main())

I expected both tasks to run concurrently. But when I ran this:

Run the script
python bad_sleep_example.py

I got sequential output:

Output showing blocking behavior
Task 1 starting...
[1 second pause - nothing else happens]
Task 1 completed.
Task 2 starting...
[1 second pause]
Task 2 completed.

Both tasks ran one after another, not concurrently. The async code behaved like synchronous code.

How to solve it?

I replaced time.sleep() with asyncio.sleep():

good_sleep_example.py
import asyncio
async def task(name):
print(f"{name} starting...")
await asyncio.sleep(1) # Non-blocking!
print(f"{name} completed.")
async def main():
await asyncio.gather(task("Task 1"), task("Task 2"))
asyncio.run(main())

Now I run the script again:

Run the fixed script
python good_sleep_example.py

I get concurrent execution:

Output showing concurrent behavior
Task 1 starting...
Task 2 starting...
[Both tasks wait together]
Task 1 completed.
Task 2 completed.

Both tasks started at the same time. They completed together after 1 second, not 2 seconds.

The reason

I think the key reason is how Python’s event loop works:

  1. time.sleep() is synchronous - It blocks the entire thread. The event loop cannot run any other task while sleeping. Everything stops.

  2. asyncio.sleep() is asynchronous - It returns control to the event loop. The event loop can run other tasks while waiting. Concurrency continues.

Event loop blocking comparison
time.sleep(1):
┌──────────────────────────────────────┐
│ Thread BLOCKED for 1 second │
│ No other tasks can run │
└──────────────────────────────────────┘
asyncio.sleep(1):
┌────────────┐ ┌────────────┐
│ Task 1 │ │ Task 2 │
│ yields │ ──→ │ runs while │
│ control │ │ Task 1 │
└────────────┘ │ waits │
└────────────┘

This distinction matters for async web servers handling thousands of requests. Blocking the event loop makes all users wait, not just the one request using time.sleep().

Common mistakes to avoid

I also found other blocking operations that cause the same problem:

blocking_operations.py
import asyncio
import requests # Sync HTTP client
import os
async def bad_example():
# All of these BLOCK the event loop:
time.sleep(1) # Blocking sleep
requests.get(url) # Blocking HTTP request
os.system("ls") # Blocking system call
open("file.txt").read() # Blocking file I/O

For each blocking operation, there’s an async alternative:

async_alternatives.py
import asyncio
import aiohttp # Async HTTP client
import aiofiles # Async file I/O
async def good_example():
await asyncio.sleep(1) # Non-blocking sleep
async with aiohttp.ClientSession() as session:
await session.get(url) # Non-blocking HTTP
await asyncio.to_thread(os.system, "ls") # Offload to thread
async with aiofiles.open("file.txt") as f:
await f.read() # Non-blocking file I/O

Summary

In this post, I showed why time.sleep() breaks async Python code. The key point is: time.sleep() blocks the entire event loop, while asyncio.sleep() yields control to other tasks. Always use async alternatives for I/O operations in async code.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments