Skip to content

Event Loop and asyncio.run

What is the event loop?

The event loop is the “engine” that:

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

asyncio.run

asyncio.run(coro)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()))
asyncio_run.py
import asyncio
 
 
async def main():
    await asyncio.sleep(0.1)
    return 123
 
 
print(asyncio.run(main()))

Running multiple coroutines

To run multiple coroutines concurrently, you’ll use:

  • tasks
  • gather

(covered in next pages)

Common mistake in notebooks

Some notebook environments already have an event loop running.

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

In normal Python scripts, prefer asyncio.runasyncio.run.

Visualize it

asyncio.runasyncio.run starts the event loop. It runs one coroutine until that coroutine hits an awaitawait, 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 awaitawait, 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.

🧪 Try It Yourself

Exercise 1 – asyncio.run() Entry Point

Exercise 2 – Get the Running Loop

Exercise 3 – Schedule and Await

If this helped you, consider buying me a coffee ☕

Buy me a coffee

Was this page helpful?

Let us know how we did