← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Python async/await & asyncio

python Python 3.5+ Intermediate

Also Known As

Python asyncio async await Python coroutines Python

TL;DR

Python's native async framework — coroutines, event loop, and asyncio — for concurrent I/O without threads.

Explanation

Python's asyncio provides a single-threaded event loop similar to Node.js. async def functions are coroutines — they don't run until awaited or scheduled. await suspends the coroutine until the awaited coroutine/task finishes. asyncio.gather(*coros) runs coroutines concurrently. asyncio.run(main()) starts the event loop. For CPU-bound work, asyncio doesn't help — use multiprocessing or ThreadPoolExecutor (loop.run_in_executor). Key difference from threading: no GIL contention, but no true parallelism either — only concurrency for I/O. Libraries: httpx (async HTTP), asyncpg (async PostgreSQL), aiofiles (async file I/O), FastAPI (async web framework). Comparable to PHP's Fibers + Revolt, but asyncio is a mature standard library with rich ecosystem support.

Diagram

flowchart TD
    subgraph Sync_Python
        S1[Task A runs] --> S2[Task A waits for IO<br/>thread blocked]
        S2 --> S3[Task A resumes]
        S3 --> S4[Task B runs]
    end
    subgraph Async_Python
        A1[Task A starts] --> A2[await IO - suspended]
        A2 --> B1[Task B runs during A wait]
        B1 --> A3[Task A resumes]
        A3 & B1 -->|interleaved| FAST[Both complete faster]
    end
    subgraph asyncio
        LOOP2[Event loop<br/>asyncio.run]
        GATHER[asyncio.gather<br/>run concurrently]
        LOOP2 --> GATHER
    end
style A2 fill:#d29922,color:#fff
style FAST fill:#238636,color:#fff
style GATHER fill:#1f6feb,color:#fff

Common Misconception

Python async/await provides true parallelism. Python's asyncio is single-threaded cooperative concurrency — one coroutine runs at a time, yielding control at await points. For CPU-bound parallelism, use multiprocessing; for I/O-bound concurrency, asyncio is ideal.

Why It Matters

Python's asyncio enables concurrent I/O-bound operations in a single thread — async/await syntax makes concurrent HTTP calls and database queries readable without threads or callbacks.

Common Mistakes

  • Using blocking I/O inside async functions — blocks the entire event loop.
  • Not awaiting coroutines — calling an async function without await returns a coroutine object, not the result.
  • Using asyncio.run() inside an already-running event loop — raises RuntimeError.
  • CPU-bound work in async functions — use ProcessPoolExecutor, not asyncio, for CPU-heavy tasks.

Code Examples

✗ Vulnerable
# Blocking call inside async — freezes event loop:
async def fetch_data():
    time.sleep(2)  # Blocks! Use: await asyncio.sleep(2)
    data = requests.get(url)  # Blocks! Use: await aiohttp session
    return data
✓ Fixed
import asyncio
import aiohttp

# Async function — returns a coroutine
async def fetch_user(session: aiohttp.ClientSession, user_id: int) -> dict:
    async with session.get(f'https://api.example.com/users/{user_id}') as resp:
        return await resp.json()

# Fetch multiple users concurrently
async def fetch_all_users(user_ids: list[int]) -> list[dict]:
    async with aiohttp.ClientSession() as session:
        tasks = [fetch_user(session, uid) for uid in user_ids]
        return await asyncio.gather(*tasks)  # run concurrently

# Run:
users = asyncio.run(fetch_all_users([1, 2, 3, 4, 5]))

# async with — async context manager
# async for  — async iteration (e.g. streaming responses)
async def stream_lines(url: str):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as resp:
            async for line in resp.content:
                yield line.decode('utf-8').strip()

Added 15 Mar 2026
Edited 22 Mar 2026
Views 42
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 1 ping F 0 pings S 0 pings S 1 ping M 0 pings T 0 pings W 0 pings T 1 ping F 2 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 3 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 1 ping F 2 pings S
Amazonbot 1
Amazonbot 16 Perplexity 8 ChatGPT 4 Unknown AI 4 Google 3 Ahrefs 2 Meta AI 1
crawler 36 crawler_json 1 pre-tracking 1
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: High
⚡ Quick Fix
Use asyncio.gather() for concurrent I/O operations and async with for context managers in async code — synchronous blocking calls inside async functions block the entire event loop
📦 Applies To
python 3.5 web cli
🔗 Prerequisites
🔍 Detection Hints
time.sleep() or requests.get() in async function blocking event loop; missing await before coroutine call
Auto-detectable: ✓ Yes pylint ruff mypy asyncio-mode-pytest
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✗ Manual fix Fix: High Context: Function Tests: Update

✓ schema.org compliant