EMZETT.
Login

asyncio: Concurrency in Python without threads

In short: With asyncio many waiting tasks (network, files) run side by side in a single thread by making room for each other while waiting.

In more detail: Many programs wait most of the time: for a reply from the server, for the disk, for the database. Instead of starting a thread for every request, asyncio uses cooperative multitasking: an event loop runs coroutines, and each gives up control while waiting (await) so that another can continue.

In Depth

Basic terms

  • Coroutine: a function with async def that can pause.
  • await: pauses the coroutine until the result is ready and lets the event loop do other work.
  • Task: a scheduled coroutine that runs concurrently (asyncio.create_task).
  • Event loop: loop that manages and resumes tasks (asyncio.run).

Example

import asyncio
 
async def fetch(name, seconds):
    await asyncio.sleep(seconds)       # simulates waiting for the network
    return f"{name} done"
 
async def main():
    results = await asyncio.gather(
        fetch("A", 2), fetch("B", 1), fetch("C", 3)
    )
    print(results)                     # after about 3 s, not 6 s
 
asyncio.run(main())

The three tasks wait at the same time. The total time equals the longest, not the sum.

When it helps and when not

Helpful for I/O-bound tasks: many HTTP requests, database accesses, websockets, web servers (FastAPI, aiohttp). For compute-intensive tasks it achieves nothing, since only one thread computes; for those use multiprocessing or concurrent.futures.ProcessPoolExecutor. Blocking calls such as time.sleep() or requests.get() inside a coroutine block the whole event loop; use asyncio.sleep and asynchronous libraries (httpx, aiohttp) or asyncio.to_thread.

Pitfalls

A forgotten await only creates a coroutine object but no execution. Errors in tasks that are not awaited easily get lost; use TaskGroup (Python 3.11+) for clean error handling. End long tasks with timeouts (asyncio.timeout). The same principle (async/await) you know from JavaScript, C# and Rust.

See also: async/await, Event loop, Concurrency