Python async patterns
Production-ready asyncio patterns for high-concurrency Python services.
Structured concurrency with TaskGroup
Python 3.11 introduced asyncio.TaskGroup, bringing structured concurrency to asyncio. All child tasks are awaited or cancelled together — no orphaned coroutines.
async with asyncio.TaskGroup() as tg:
tg.create_task(fetch_users())
tg.create_task(fetch_orders())
# Both complete or both cancelledSemaphore-bounded fan-out
Cap concurrent I/O with asyncio.Semaphore. Prevents connection pool exhaustion when fanning out to hundreds of endpoints.
sem = asyncio.Semaphore(20)
async def bounded_get(url):
async with sem:
return await aiohttp.get(url)Gather with return_exceptions
asyncio.gather(*tasks, return_exceptions=True) collects exceptions as results instead of short-circuiting. Inspect each outcome after the gather completes.
Timeout with asyncio.timeout
Python 3.11's asyncio.timeout(seconds) context manager raises TimeoutError if the block exceeds the deadline. Prefer it over wait_for for scoped deadlines.
Meridian tip: Combine TaskGroup + Semaphore + timeout for resilient data pipelines. See thefull reference.