Python Async

Installation
SKILL.md

Python Async

Asyncio gives one thread the throughput of hundreds of connections, but only if nothing on the event loop ever blocks - a single stray time.sleep or requests.get freezes every coroutine in the process. The costly mistakes this skill prevents are the silent ones: code that runs correctly but sequentially (awaiting in a loop), tasks that vanish mid-flight (un-referenced fire-and-forget), and a "fast" service whose p99 collapses because one handler does CPU work on the loop.

Mental model

One event loop runs many coroutines cooperatively on a single thread. await is the only place control can switch; between awaits, your code has an exclusive lock on the whole process. Concurrency comes from running tasks, not from awaiting sequentially - await a(); await b() is exactly as slow as sync code.

Operating procedure

Step 1: Gather inputs

  1. Python version - 3.11+ unlocks TaskGroup and asyncio.timeout; below that, use gather and wait_for.
  2. The workload type per operation: network I/O (async-friendly), disk/blocking-library I/O (needs to_thread), or CPU-bound (needs a process pool).
  3. Every library on the I/O path, checked for an async API: httpx/aiohttp not requests, asyncpg not psycopg2, asyncio.sleep not time.sleep. If unsure whether a call blocks, treat it as blocking.
  4. The concurrency target and the downstream limits (DB pool size, API rate limits).

Step 2: Choose the concurrency primitive

Installs
GitHub Stars
10
First Seen
Python Async — skillmedev/skills