๐Ÿ“ Python

run_in_executor and anyio: Sync Libraries in Async Code

P
Author
PyLand Team
๐Ÿ“…
Published
30.06.2026
โฑ๏ธ
Reading time
1 min
๐Ÿ‘๏ธ
Views
368
๐Ÿ†
Level
Expert

Sometimes you need to call a synchronous library from async code without blocking the event loop.

The problem: blocking call in async function

import asyncio, requests

async def bad_fetch(url):
    # BAD: requests.get blocks the event loop for the entire request duration
    # All other coroutines freeze and wait
    return requests.get(url).text

run_in_executor โ€” run in thread pool

import asyncio
from concurrent.futures import ThreadPoolExecutor
import requests

executor = ThreadPoolExecutor(max_workers=10)

async def fetch_sync(url: str) -> str:
    loop = asyncio.get_running_loop()
    # requests.get runs in a separate thread, event loop is not blocked
    return await loop.run_in_executor(executor, requests.get, url)

async def main():
    results = await asyncio.gather(
        fetch_sync("https://httpbin.org/get"),
        fetch_sync("https://httpbin.org/post"),
    )

ProcessPoolExecutor โ€” for CPU-bound tasks

from concurrent.futures import ProcessPoolExecutor

def heavy_computation(data: list) -> float:
    return sum(x ** 2 for x in data)  # CPU-intensive

async def main():
    loop = asyncio.get_running_loop()
    with ProcessPoolExecutor() as pool:
        result = await loop.run_in_executor(
            pool, heavy_computation, list(range(10_000_000))
        )
    print(result)

anyio โ€” universal async backend

anyio works on top of asyncio or trio โ€” same code:

import anyio

async def main():
    # to_thread.run_sync โ€” sync code in a thread
    result = await anyio.to_thread.run_sync(blocking_function, arg1, arg2)

    # Parallel tasks via TaskGroup
    async with anyio.create_task_group() as tg:
        tg.start_soon(fetch, url1)
        tg.start_soon(fetch, url2)

# Run under asyncio or trio
anyio.run(main)

When to use what

Scenario Solution
Sync I/O library run_in_executor + ThreadPoolExecutor
CPU-intensive task run_in_executor + ProcessPoolExecutor
New async project httpx, aiosqlite instead of requests, sqlite3
Backend portability anyio

Your reaction to the article

๐Ÿ’ฌ Comments (0)

๐Ÿ” Sign in to leave a comment
๐Ÿšช Login
๐Ÿ’ญ

No comments yet

Be the first to share your opinion about this article!

๐Ÿ”— Similar

Similar articles

Continue learning with these materials

๐Ÿ“

Event Loop in Python: How asyncio Enables Concurrโ€ฆ

Event loop is the heart of asyncio. It doesn't run code in parallel across multiple...

๐Ÿ“… 30.06.2026 ๐Ÿ‘๏ธ 387
๐Ÿ“

Async Context Managers: async with and @asynccontโ€ฆ

Async context managers manage resources in async code โ€” connections, files, transactions.

๐Ÿ“… 30.06.2026 ๐Ÿ‘๏ธ 392
๐Ÿ“

asyncio: Timeouts, Task Cancellation and Gracefulโ€ฆ

Three things you absolutely need in production async code.

๐Ÿ“… 30.06.2026 ๐Ÿ‘๏ธ 607

Did you like the article?

Subscribe to our updates and be the first to receive new articles. Grow with PyLand!