asyncio is a Python library for asynchronous programming. It handles multiple I/O operations concurrently, keeping applications responsive instead of making each web request, database query, or network connection wait sequentially. A workload with 100 one-second I/O operations can theoretically finish in about one second when those operations overlap. section 1.0 section 1.1
The core model is cooperative multitasking: coroutines explicitly pause at await points while waiting for I/O, allowing other coroutines to run. An event loop tracks these tasks, and non-blocking sockets let the operating system notify it when data is ready. This provides concurrency on one Python thread, not parallel execution. section 1.3.5 section 1.6.1 section 1.8
Figure 1.8 Making a non-blocking I/O request returns immediately and tells the O/S to watch sockets for data. This allows execute_other_code() to run right away instead of waiting for the I/O requests to finish. Later, we can be alerted when I/O is complete and process the response.
Visualizes how a non-blocking I/O request returns immediately, lets other code run, and later resumes when the operating system reports completion. section 1.6.1
A practical asyncio workflow uses these building blocks:
- Define asynchronous functions with async; calling one creates a coroutine object rather than executing its body immediately. section 2.1.1
- Start the application with asyncio.run, which creates an event loop, runs the main coroutine, performs cleanup, and closes the loop. section 2.1.1
- Create tasks for independent long-running operations and await them while other coroutines continue running. section 2.3.2
- Cancel tasks or set timeouts when requests may run indefinitely or users need a way to stop them. section 2.4
Running independent delays together
A main coroutine can create three tasks with asyncio.create_task(delay(3)), then await each task. The delays overlap, so the total runtime is roughly three seconds rather than nine. While those tasks wait, another coroutine can print status messages or perform other work. section 2.3.2
asyncio suits I/O-heavy applications such as echo servers, microservice clients, database batch queries, and producer-consumer systems. It does not bypass Python’s GIL for CPU-bound code; process pools can provide parallel CPU execution, while thread pools adapt blocking I/O libraries such as requests or psycopg. section 3.5 section 5.5 section 6.0 section 7.0

