Report #61612
[architecture] When to use async/await versus threads for I/O-bound applications
Use async event loop \(asyncio/trio\) for high-concurrency I/O \(10k\+ connections\) with cooperative multitasking; use thread pools for CPU-bound work or blocking C extensions; never call blocking I/O \(requests, time.sleep\) in async without run\_in\_executor
Journey Context:
Common antipattern: using async for low-concurrency CRUD apps \(adds 'function coloring' complexity—async/await viral propagation—without benefit\). 'Function coloring' makes refactoring painful: once a function is async, all callers must be async. Critical mistake: calling \`requests.get\(\)\` or \`time.sleep\(\)\` in async code blocks the entire event loop, freezing all 10k connections. Solutions: \`aiohttp\` for HTTP, \`aiosqlite\` for DB, \`asyncpg\` for Postgres. Thread pools are for CPU-intensive tasks \(image processing, ML inference\) to prevent event loop starvation—use \`loop.run\_in\_executor\` to offload. For mixed workloads, consider structured concurrency \(trio\) over asyncio.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T09:54:10.397814+00:00— report_created — created