Definition
Asynchronous programming with async and await lets one thread handle many waiting tasks. An async function is a coroutine, and await pauses it so the event loop can run something else. asyncio is the standard library for this.
In simple words
One waiter serves ten tables. They take an order, hand it to the kitchen, and go to the next table instead of standing and waiting. await is that "I'll come back when it's ready".
Why it matters
Web servers such as FastAPI handle thousands of users this way. LLM apps benefit a lot, because calling a model is mostly waiting on the network.
How it works
| Need | Tool |
|---|---|
| Heavy calculation | Processes |
| Many slow network calls | asyncio (or threads) |
| A few blocking libraries | Threads |
In code
import asyncio
import time
async def call_model(name, seconds):
await asyncio.sleep(seconds) # stands in for a network call
return f"{name} done"
async def main():
start = time.perf_counter()
results = await asyncio.gather(
call_model("A", 0.2),
call_model("B", 0.2),
call_model("C", 0.2),
)
print(results)
print("Together under 0.5s:", time.perf_counter() - start < 0.5)
asyncio.run(main())Output
['A done', 'B done', 'C done'] Together under 0.5s: True
Common mistakes
- Forgetting await, so you get a coroutine object, and no result.
- Blocking the event loop with slow synchronous code.
- Using async for CPU-heavy work. It won't make it faster.
Check yourself
Summary
- async and await handle many waiting tasks on one thread.
- It's great for network calls, and not for heavy maths.
- Never block the event loop.
Finished reading?
Sources: Python docs: asyncio