TaskGroups & structured concurrency
P33.structured-concurrency.01 · Audience: guest, it-ml, language-pro · Prerequisites: Tasks, gather & timeouts
gather runs tasks, but it leaks them on failure: if one coroutine raises, the
others keep running, orphaned. asyncio.TaskGroup (Python 3.11+) makes concurrent
work behave like a function call — it does not return until every task is done,
and a failure cancels the siblings. The kernel rung runs real TaskGroups.
ⓘ Concept: A scope tasks cannot outlive
async with asyncio.TaskGroup() as tg: is a scope. Tasks you start with tg.create_task(...) are all awaited before the block exits — so concurrent work has the same lifetime as the block, exactly like local variables. Nothing leaks past it.Why it matters — Leaked background tasks are a classic async bug — they run after the code that started them has moved on, holding resources and hiding errors.
Ask the mentor about this module
Ask a question about this content. The mentor explains and grounds its answer in what you are studying; asking is recorded as a learning signal, not a grade.
🎓 Practice ladder
2 graded rungs · ~22 minRun tasks under a real TaskGroup on the kernel, then explain why
structured concurrency beats a bag of loose futures.
Rung 1 — run tasks under a TaskGroup (kernel)
Loading exercise…
Rung 2 — why structured concurrency? (interview)
Loading exercise…
Structured concurrency keeps async code honest. The last track handles the moment async meets the blocking, CPU-bound world — without freezing the loop.