Python has had async for 10 years — why isn't it more popular? By Anthony Shaw, September 2, 2025 --- Overview Python introduced async/await in version 3.5 (2015). Ten years later, Python 3.14 (upcoming) includes major concurrency features: PEP 779: Official support for free-threaded Python (GIL improvements). PEP 734: Multiple interpreters in the standard library. Despite async’s presence, its popularity remains limited, particularly outside web development. --- Why Async is Mostly Used for Network I/O Coroutines are great for I/O-bound tasks where operations can be started and awaited without blocking the whole program. Classic example: asynchronous HTTP requests using asyncio or aiohttp. Parallel HTTP requests allow starting many at once and processing responses as they come. However, many other I/O scenarios (disk I/O, subprocesses) don’t natively support async in Python. Filesystem async is mostly implemented via thread pools (e.g., aiofiles), not true async. Underlying OS support (iouring on Linux, IoRing on Windows) exists but has security or availability issues. Hence, async in Python really excels only with network sockets, which were already non-blocking. --- The Global Interpreter Lock (GIL) and Async Challenges Python’s GIL allows only one thread to execute Python bytecode at a time. Async in Python runs on a single event loop tied to one thread — blocking code inside async functions blocks the whole loop. This limits true parallelism and requires developers to carefully avoid blocking calls in async code. C#’s async model differs by using a managed thread pool, allowing easier parallelism. Free-threaded Python (partial removal of GIL) is arriving in Python 3.14 but not yet stable. This may unlock more powerful parallelism scenarios and simplify concurrent programming. --- Maintaining Separate Synchronous and Asynchronous APIs is Difficult Library authors must often maintain two codebases: sync and async versions. This leads to: Large code duplication and maintenance overhead. Complex testing requirements (mocks, async test frameworks). Confusing async usage patterns (e.g., async properties that need await). Popular projects like the Azure Python SDK automate this but require large teams. Async HTTP clients and frameworks differ (requests vs aiohttp), causing fragmentation. --- Current Async Support in Popular Web Frameworks FastAPI: fully async from the ground up, growing in popularity (~38% share). Django: partial async support; key parts like ORM remain synchronous. Flask: remains synchronous; async alternatives like Quart exist. SQLAlchemy only recently added asyncio support (2023). --- New Features in Python 3.14 Related to Concurrency PEP 779 — Free-Threaded Python Improved threading model replacing GIL with finer locks. PEP 734 — Multiple Interpreters in stdlib Support multiple interpreters, enabling more concurrency. These can enable better parallel execution without relying solely on async/await. --- Asyncio Supported Operations Summary | Operation | Asyncio API | Notes | |-----------------|----------------------------------|--------------------------------| | Sleep | asyncio.sleep() | Non-blocking delay | | TCP/UDP Streams | asyncio.openconnection() | Async socket connections | | HTTP client | aiohttp.ClientSession() | Async web requests | | Subprocesses | asyncio.subprocess | Async external process management | | Queues | asyncio.Queue | Concurrent task queue | --- Summary and Outlook Async is widely recognized as useful mainly for network I/O. The GIL and blocking operations limit async’s applicability. Maintaining dual sync/async APIs