📝 Python

asyncio: Timeouts, Task Cancellation and Graceful Shutdown

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

Three things you absolutely need in production async code.

asyncio.timeout() — painless timeouts (Python 3.11+)

import asyncio

async def slow_operation():
    await asyncio.sleep(10)

async def main():
    try:
        async with asyncio.timeout(3.0):   # 3 seconds max
            await slow_operation()
    except TimeoutError:
        print("Timeout exceeded")

Before Python 3.11 asyncio.wait_for() was used:

try:
    result = await asyncio.wait_for(slow_operation(), timeout=3.0)
except asyncio.TimeoutError:
    print("Timeout")

CancelledError — task cancellation

async def worker():
    try:
        while True:
            await do_work()
    except asyncio.CancelledError:
        await cleanup()    # release resources
        raise              # IMPORTANT: always re-raise CancelledError

async def main():
    task = asyncio.create_task(worker())
    await asyncio.sleep(5)
    task.cancel()          # send CancelledError into task
    try:
        await task
    except asyncio.CancelledError:
        print("Task cancelled cleanly")

Rule: in except CancelledError always re-raise. Otherwise the task won’t finish correctly.

Graceful Shutdown — clean termination

import asyncio, signal

async def main():
    loop = asyncio.get_running_loop()
    stop = asyncio.Event()

    def handle_signal():
        print("Got SIGINT, shutting down...")
        stop.set()

    loop.add_signal_handler(signal.SIGINT, handle_signal)
    loop.add_signal_handler(signal.SIGTERM, handle_signal)

    # Main work
    tasks = [asyncio.create_task(worker(i)) for i in range(5)]

    await stop.wait()       # wait for signal

    # Cancel all tasks
    for task in tasks:
        task.cancel()

    # Wait for completion with cleanup
    await asyncio.gather(*tasks, return_exceptions=True)
    print("Shut down cleanly")

asyncio.run(main())

return_exceptions=True in gather() matters: without it the first CancelledError will interrupt waiting for the other tasks.

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

📝

Event Loop in Python: How asyncio Achieves "Paral…

Event loop is the heart of asyncio. It doesn't run code in parallel across multiple...

📅 30.06.2026 👁️ 123
📝

pytest-django: Testing Django

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

📅 30.06.2026 👁️ 132
📝

pip: Python Package Manager

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

📅 30.06.2026 👁️ 120

Did you like the article?

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