Asyncio Basics
9 examples to get you started with Asyncio - 6 basic and 3 intermediate.
Search across all documentation pages
9 examples to get you started with Asyncio - 6 basic and 3 intermediate.
asyncio stdlib.async/await syntax - not legacy @asyncio.coroutine generators.Coroutines are async functions paused at await.
import asyncio
async def hello() -> str:
await asyncio.sleep(0.1)
return "hello"
async def main() -> None:
print(await hello())
asyncio.run(main())async def defines a coroutine function.asyncio.run manages loop lifecycle for scripts.Related: Tasks & Gather - concurrent coroutines
Other tasks run while one awaits I/O.
import asyncio
async def tick(name: str) -> None:
print(name, "start")
await asyncio.sleep(0.1)
print(name, "end")
async def main() -> None:
await tick("a")
await tick("b")
asyncio.run(main())Related: Debugging Async Code - blocking mistakes
Run multiple coroutines concurrently.
import asyncio
async def work(n: int) -> int:
await asyncio.sleep(0.1)
return n
async def main() -> None:
results = await asyncio.gather(work(1), work(2), work(3))
print(results)
asyncio.run(main())gather schedules all awaitables on the same loop.return_exceptions=True.Related: Tasks & Gather - Task objects
Schedule background work without awaiting immediately.
import asyncio
async def background() -> None:
await asyncio.sleep(0.1)
print("done")
async def main() -> None:
task = asyncio.create_task(background())
print("scheduled")
await task
asyncio.run(main())create_task wraps coroutine in a Task.Related: Structured Concurrency - TaskGroup
Never block the loop with sync sleep.
import asyncio
async def good() -> None:
await asyncio.sleep(0.05)
# time.sleep(0.05) in coroutine blocks ALL tasks - avoidasyncio.sleep is awaitable and non-blocking for other tasks.time.sleep freezes entire event loop thread.Related: Sync/Async Bridging - offload blocking
Bound waiting time on slow coroutines.
import asyncio
async def slow() -> str:
await asyncio.sleep(1)
return "ok"
async def main() -> None:
try:
await asyncio.wait_for(slow(), timeout=0.1)
except TimeoutError:
print("timed out")
asyncio.run(main())TimeoutError on expiry.asyncio.timeout context manager (3.11+) in new code.Related: Structured Concurrency - timeout patterns
Async context managers release resources without blocking peers.
import asyncio
class AsyncResource:
async def __aenter__(self):
await asyncio.sleep(0)
return self
async def __aexit__(self, *args):
await asyncio.sleep(0)
async def main() -> None:
async with AsyncResource() as res:
print("using", res)
asyncio.run(main())__aenter__/__aexit__ mirror sync with.Related: Async Context Managers & Iterators
CPU loops starve other coroutines.
import asyncio
async def bad_cpu() -> int:
total = 0
for i in range(500_000):
total += i
return total
# Fix: await asyncio.to_thread(cpu_intensive_fn)Related: Sync/Async Bridging - to_thread
Servers keep one long-lived loop - not repeated asyncio.run per request.
# Conceptual FastAPI 0.115+ pattern
# @asynccontextmanager async def lifespan(app):
# yield
# app = FastAPI(lifespan=lifespan)httpx.AsyncClient in lifespan startup.Related: Async HTTP with httpx/aiohttp - shared client
Stack versions: This page was written for Python 3.14.0 (stable 3.14, maintenance 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, and uv 0.6+.
Reviewed by Chris St. John·Last updated Jul 19, 2026