Speed Up Your Asyncio Code with Thread Pools

Mar 25, 2024 ยท 2 min read

Asyncio is great for writing non-blocking network code in Python. But sometimes you have CPU-bound tasks that could benefit from parallel execution. That's where thread pools come in handy!

A thread pool allows you to execute CPU-bound functions in separate threads, while keeping your main code asynchronous. Here's how it works...

First you need to create a ThreadPoolExecutor:

import asyncio
from concurrent.futures import ThreadPoolExecutor

pool = ThreadPoolExecutor(max_workers=4)

This will give you a pool with 4 worker threads.

Then you can submit jobs to your pool using loop.run_in_executor():

async def my_cpu_bound_func(data):
    # Do something CPU intensive 

loop = asyncio.get_event_loop()

async def main():
    data = await get_data() 
    await loop.run_in_executor(pool, my_cpu_bound_func, data)

The key thing is that run_in_executor() returns a coroutine, so you use await to get the result. Behind the scenes it runs your function in a separate thread!

This keeps your main code non-blocking while allowing CPU parallelization. Pretty neat!

Some tips:

  • Don't create too many threads - 4-8 is usually ideal
  • Use a concurrent.futures.ProcessPoolExecutor for CPU-intensive parallel tasks
  • Always await the results - don't let threads escape!
  • Thread pools do add complexity, so only use them if you have a clear performance bottleneck. But they're a great tool for optimizing CPU work in asyncio.

    Let me know if any part needs more explanation! Asyncio concurrency takes some practice to master.

    Browse by tags:

    Browse by language:

    The easiest way to do Web Scraping

    Get HTML from any page with a simple API call. We handle proxy rotation, browser identities, automatic retries, CAPTCHAs, JavaScript rendering, etc automatically for you

    Try ProxiesAPI for free

    curl "http://api.proxiesapi.com/?key=API_KEY&url=https://example.com"

    <!doctype html>
        <title>Example Domain</title>
        <meta charset="utf-8" />
        <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />


    Don't leave just yet!

    Enter your email below to claim your free API key: