asyncio

The Python asyncio module provides a framework for writing asynchronous programs using coroutines, event loops, and tasks.

It allows you to write concurrent code using the async and await keywords, making it easier to manage I/O-bound tasks in your code.

Here’s a quick example:

Python
>>> import asyncio

>>> async def main():
...     print("Hello ...")
...     await asyncio.sleep(0.5)
...     print("... World!")
...

>>> asyncio.run(main())
Hello ...
... World!

Key Features

  • Provides a framework for writing concurrent code using coroutines, typically in a single-threaded event loop
  • Supports asynchronous input/output (I/O) tasks
  • Manages event loops for scheduling and executing tasks
  • Allows task synchronization with locks, events, and semaphores

Frequently Used Classes and Functions

Object Type Description
asyncio.run() Function Runs the main coroutine and manages the event loop
asyncio.create_task() Function Schedules the execution of a coroutine object
asyncio.sleep() Function Asynchronously sleeps for a specified amount of time
asyncio.gather() Function Runs multiple coroutines concurrently
asyncio.as_completed() Function Returns an iterator that yields awaitables as they complete
asyncio.Lock Class Provides a lock object for coroutines

Examples

Running multiple coroutines concurrently:

Python
>>> import asyncio

>>> async def say(what, when):
...     await asyncio.sleep(when)
...     print(what)
...

>>> async def main():
...     await asyncio.gather(
...         say("first", 1),
...         say("second", 2),
...         say("third", 3),
...     )
...

>>> asyncio.run(main())
first
second
third

Using an asyncio.Lock for task synchronization:

Python
>>> import asyncio

>>> async def worker(id, lock):
...     async with lock:
...         print(f"Lock acquired by worker: {id}")
...         await asyncio.sleep(1)
...     print(f"Lock released by worker: {id}")
...

>>> async def main():
...     lock = asyncio.Lock()
...     await asyncio.gather(worker("1", lock), worker("2", lock))
...

>>> asyncio.run(main())
Lock acquired by worker: 1
Lock released by worker: 1
Lock acquired by worker: 2
Lock released by worker: 2

Common Use Cases

  • Managing concurrent I/O-bound operations efficiently
  • Building network clients and servers
  • Coordinating tasks with synchronization primitives
  • Running background tasks while maintaining responsive applications

Real-World Example

Say that you want to know the length in characters of several web pages concurrently. Here’s how you can do it using asyncio:

Python
>>> import asyncio
>>> import aiohttp

>>> async def fetch(session, url):
...     async with session.get(url) as response:
...         content = await response.text()
...         return url, len(content)
...

>>> async def main():
...     urls = [
...         "https://python.org",
...         "https://realpython.com",
...         "https://google.com",
...         "https://example.com"
...     ]
...     async with aiohttp.ClientSession() as session:
...         tasks = [fetch(session, url) for url in urls]
...         for coro in asyncio.as_completed(tasks):
...             try:
...                 url, length = await coro
...                 print(f"{url} => {length} chars")
...             except Exception as e:
...                 print(f"Failed to fetch url: {e}")
...

>>> asyncio.run(main())
https://python.org => 50014 chars
https://example.com => 1256 chars
https://google.com => 20230 chars
https://realpython.com => 83489 chars

In this example, asyncio efficiently manages the concurrent HTTP requests, allowing for faster retrieval of web pages.

Tutorial

Async IO in Python: A Complete Walkthrough

This tutorial will give you a firm grasp of Python’s approach to async IO, which is a concurrent programming design that has received dedicated support in Python, evolving rapidly from Python 3.4 through 3.7 (and probably beyond).

intermediate python

For additional information on related topics, take a look at the following resources:


By Leodanis Pozo Ramos • Updated June 23, 2025