Automation

Reliable async Python patterns and pitfalls

Build resilient concurrent Python applications by avoiding common async antipatterns — blocking IO in the event loop, unstructured gather, unbounded concurrency, and leaked resources.

Outcome

Keep the event loop unblocked, replace bare gather with TaskGroup, bound concurrency with Semaphore, and release resources on cancellation.

Prerequisites
  • Python 3.11 or newer
  • Comfort with async and await basics
  • One IO-bound workload to apply the patterns to

Asynchronous Python (asyncio) offers high throughput for IO-bound applications, such as web services built with FastAPI or batch pipelines using HTTPX. However, AI coding agents frequently introduce subtle concurrency bugs.

Never invoke blocking IO inside the event loop

Calling synchronous filesystem or network methods (such as time.sleep or standard sync file reads) blocks the entire event loop, starving other concurrent coroutines. Offload unavoidable blocking operations to worker threads via asyncio.to_thread():

import asyncio

def blocking_io_task(): ...

async def handle_request():
    result = await asyncio.to_thread(blocking_io_task)

Prefer TaskGroup over bare gather

In Python 3.11+, use asyncio.TaskGroup for structured concurrency instead of asyncio.gather. TaskGroup guarantees that if any child task raises an unhandled exception, all sibling tasks are immediately cancelled and cleaned up, preventing orphan runaway tasks.

import asyncio

async def main():
    async with asyncio.TaskGroup() as tg:
        task1 = tg.create_task(fetch_user(1))
        task2 = tg.create_task(fetch_orders(1))

Bound concurrency with Semaphore

Never launch unbounded coroutines on large datasets. Always wrap concurrent operations in an asyncio.Semaphore to cap open file descriptors and avoid rate-limiting triggers.

Handle cancellation and cleanup

Always use try...finally blocks or async context managers to release database connections, network sessions, and lock resources when an async operation is cancelled.

Sources

Verification record

Documentation review

Editorial review of the async patterns against the asyncio, FastAPI, and HTTPX documentation. Verified 2026-09-02.

About the author

Organizational byline for FlyPython guides, verification records, and corrections. Editorial standards and contact details →