📝 Python

Event Loop in Python: How asyncio Achieves "Parallelism"

P
Author
Pyland
📅
Published
30.06.2026
⏱️
Reading time
1 min
👁️
Views
129
🌳
Level
Advanced

Event loop is the heart of asyncio. It doesn’t run code in parallel across multiple threads. Instead, it switches between tasks the moment they wait for I/O — and that’s how concurrency is achieved in a single thread.

I/O bound vs CPU bound

import time, asyncio

# CPU bound — async won't help
def sum_squares(n):
    return sum(i * i for i in range(n))  # pure computation

# I/O bound — async will speed it up
async def fetch(url):
    await asyncio.sleep(1)  # simulating network wait

Rule: if code waits (network, disk, database) — async gives a speedup. If it computes — it doesn’t.

How the Event Loop Works

import asyncio

async def task(name, delay):
    print(f"{name}: started")
    await asyncio.sleep(delay)   # <-- event loop switches here
    print(f"{name}: done")

async def main():
    # Without gather — sequential, 3 seconds
    await task("A", 1)
    await task("B", 2)

asyncio.run(main())

At every await the event loop checks: are there other tasks ready to run? If yes — it runs them. That’s why asyncio.gather() is faster than sequential await calls.

Future and Task

Future — a low-level object: a “promise” that a result will come later.
Task — a wrapper around a coroutine that the event loop runs concurrently.

async def main():
    # asyncio.create_task() wraps coroutine in a Task
    # and schedules it for immediate execution
    task1 = asyncio.create_task(task("A", 1))
    task2 = asyncio.create_task(task("B", 2))

    # Both tasks are already running. await here just waits for completion
    await task1
    await task2

Debug Mode

import asyncio, logging
logging.basicConfig(level=logging.DEBUG)

# Warns about slow coroutines (> 100ms)
asyncio.run(main(), debug=True)

In debug mode asyncio warns when a coroutine holds the CPU too long — this helps find accidentally blocking code.

Your reaction to the article

💬 Comments (0)

🔐 Sign in to leave a comment
🚪 Login
💭

No comments yet

Be the first to share your opinion about this article!

🔗 Similar

Similar articles

Continue learning with these materials

📝

pytest-django: Testing Django

Охватываемые темы: Installation, @pytest.mark.djangodb, Fixtures, Testing views.

📅 30.06.2026 👁️ 134
📝

pip: Python Package Manager

Охватываемые темы: Installing packages, Upgrading and removing, requirements.txt, Virtual environment.

📅 30.06.2026 👁️ 120
📝

run_in_executor and anyio: Sync Libraries in Asyn…

Sometimes you need to call a synchronous library from async code without blocking the event...

📅 30.06.2026 👁️ 103

Did you like the article?

Subscribe to our updates and receive new articles first. Grow with PyLand!