N
NexusDigitalLabs
← Back to Academy

Phase 1 — Foundations · Lesson 7 · 20 XP

Async Python: asyncio and concurrency

async and await let your program start a slow operation — like waiting for a network response — and let other work run while it waits, instead of blocking. This only helps for I/O-bound work (waiting on the network, disk, or another service). It does nothing for CPU-bound work like a tight math loop, because the CPU is still busy the whole time.

import asyncio, httpx

async def fetch(client, url):
    r = await client.get(url)
    return r.status_code

async def main():
    async with httpx.AsyncClient() as client:
        results = await asyncio.gather(*(fetch(client, u) for u in urls))

asyncio.run(main())

asyncio.gather runs a batch of coroutines concurrently and waits for all of them — fetching 50 URLs this way takes roughly as long as the slowest one, not the sum of all 50. A plain for loop with await inside it runs them one at a time, sequentially, gaining nothing from async at all.

Exercise

Fetch 50 URLs concurrently using httpx.AsyncClient and asyncio.gather, and time it against a plain sequential for loop doing the same requests. Confirm the concurrent version is dramatically faster.

Check yourself

1. Why does async speed up I/O-bound work like HTTP calls but do nothing for CPU-bound work?

2. What does asyncio.gather do that a for loop with await inside it doesn't?

← Previous lesson

HTTP fundamentals: requests, status codes, JSON, httpx

Answer the check-yourself questions to unlock this