Python Tutorial · Going Further · Lesson 40 of 42

Python Async and Await

Run I/O-bound work concurrently with asyncio, async def and await.

Why async?

Programs often wait on I/O — network calls, databases, files. asyncio lets one thread start many waits at once and continue whichever finishes first.

async def and await

An async def function is a coroutine. await pauses it until another coroutine finishes, letting other work run meanwhile.

Example 1
import asyncio

async def greet(name):
    await asyncio.sleep(0.1)   # pretend to wait for I/O
    return f"Hello, {name}"

async def main():
    message = await greet("Ada")
    print(message)

asyncio.run(main())

Output

Hello, Ada

Run this on your computer — see “Get Started” for setup.

Running tasks concurrently

asyncio.gather() runs coroutines at the same time — the total time is roughly the longest task, not the sum:

Example 2
import asyncio
import time

async def fetch(name, seconds):
    await asyncio.sleep(seconds)
    return f"{name} done"

async def main():
    start = time.perf_counter()
    results = await asyncio.gather(fetch("users", 0.3), fetch("orders", 0.2), fetch("stock", 0.1))
    print(results)
    print(f"took about {round(time.perf_counter() - start, 1)}s")

asyncio.run(main())

Output

['users done', 'orders done', 'stock done']
took about 0.3s

Run this on your computer — see “Get Started” for setup.

Async helps with I/O-bound work. For CPU-heavy work (number crunching) use processes (multiprocessing, concurrent.futures).

These examples use asyncio.run(), which needs a regular Python installation — run them on your computer.

Test yourself

Which function runs several coroutines concurrently and collects their results?

  1. asyncio.wait_all()
  2. asyncio.gather()
  3. asyncio.parallel()
  4. await all()
Show answer

Answer: asyncio.gather()