Skip to content

Event Loop and asyncio.run

The event loop is the “engine” that:

  • runs coroutines
  • pauses them at await points
  • resumes them when I/O is ready

asyncio.run(coro):

  • creates an event loop
  • runs the coroutine until complete
  • closes the loop
asyncio_run.py
import asyncio
 
 
async def main():
    await asyncio.sleep(0.1)
    return 123
 
 
print(asyncio.run(main()))

To run multiple coroutines concurrently, you’ll use:

  • tasks
  • gather

(covered in next pages)

Some notebook environments already have an event loop running.

If asyncio.run fails there, use notebook-safe patterns.

In normal Python scripts, prefer asyncio.run.

asyncio.run starts the event loop. It runs one coroutine until that coroutine hits an await, at which point the coroutine suspends and hands control back to the loop, which picks the next ready task. Nothing runs in parallel — the loop just never sits idle waiting:

diagram await hands control back to the loop mermaid
Each coroutine runs until await, suspends, and the event loop schedules the next ready task.

Here the loop juggles three coroutines: one runs, hits await, yields, and the loop moves on to the next:

sketch The event loop juggles tasks p5.js
One coroutine runs until it hits await, then yields control back to the loop, which runs the next ready task.

pch.coffeeTagline

pch.coffeeCta

pch.feedbackHeading

pch.feedbackSubheading