Efficient Python: Mastering Concurrency with Asyncio
Overview of Python Concurrency
Modern applications spend a significant amount of time waiting. Whether it is a database query, an API call, or a file read, your CPU often sits idle while I/O operations complete. Asyncio solves this by allowing a single thread to handle multiple tasks concurrently. Unlike parallelism, which runs tasks on separate cores, concurrency switches between tasks during their waiting periods. This makes your software feel faster and handle more data without needing massive hardware upgrades.
Prerequisites and Core Tools
To follow this guide, you should have a solid grasp of Python 3.10 or later. Understanding the difference between blocking and non-blocking operations is essential. Key libraries include:
- Asyncio: The built-in library for managing event loops and concurrent tasks.
- Aiohttp: A popular third-party library for making asynchronous HTTP requests, superior to the standard Requests library for high-concurrency needs.
- Time: Used here for performance benchmarking using
perf_counter.
Moving from Synchronous to Concurrent Code
Converting a linear script into a concurrent one requires changing function definitions and the execution entry point. By marking a function with async def, you turn it into a coroutine. To execute it, you must use await. When dealing with multiple independent tasks, such as fetching 20 different data points, using a simple loop with await is still slow because it waits for each task to finish before starting the next.
Instead, use asyncio.gather to fire all requests at once. Here is how you implement it with a list comprehension:
import asyncio

async def fetch_data(id): # Simulate API call return f"Data {id}"
async def main(): tasks = [fetch_data(i) for i in range(20)] results = await asyncio.gather(*tasks) print(results)
asyncio.run(main())
This approach can result in a 10x speed increase for I/O-bound tasks.
## Handling Blocking Code with Threads
Sometimes you must use a library that doesn't support `async`. In these cases, the `asyncio.to_thread` function is a lifesaver. It allows you to run blocking functions in a separate thread without halting the main event loop. This effectively turns legacy or synchronous code into something that plays nicely with your concurrent architecture.
```python
import asyncio
import requests
def blocking_get(url):
return requests.get(url).status_code
async def main():
# Run the blocking function in a separate thread
status = await asyncio.to_thread(blocking_get, "https://google.com")
print(status)
asyncio.run(main())
Syntax Notes and Practical Tips
Python's integration of async extends to generators and list comprehensions. An async for loop allows you to iterate over data as it becomes available from a stream. However, remember that asyncio.gather is the tool for speed, while async for is for sequential processing of asynchronous data.
Common Gotchas:
- The GIL: Python’s Global Interpreter Lock means you won't get true multi-core speedups for CPU-heavy tasks with threads; use
multiprocessingfor that. - Forgotten Awaits: If you call an
asyncfunction withoutawait, it returns a coroutine object instead of the result. - Nested Context Managers: While
aiohttpusesasync withfor sessions, it can lead to deeply nested code. Useto_threadfor simpler tasks if the complexity of session management isn't required.
- Aiohttp
- 17%· products
- ArjanCodes
- 17%· websites
- Asyncio
- 17%· products
- Python
- 17%· products
- Requests
- 17%· products
- Stack%20Overflow
- 17%· websites

Next-Level Concurrent Programming In Python With Asyncio
WatchArjanCodes // 19:19
On this channel, I post videos about programming and software design to help you take your coding skills to the next level. I'm an entrepreneur and a university lecturer in computer science, with more than 20 years of experience in software development and design. If you're a software developer and you want to improve your development skills, and learn more about programming in general, make sure to subscribe for helpful videos. I post a video here every Friday. If you have any suggestion for a topic you'd like me to cover, just leave a comment on any of my videos and I'll take it under consideration. Thanks for watching!