How to Run Blocking Code in an Executor with asyncio in Python

This code runs blocking functions concurrently without stalling the event loop by offloading them to thread pool executors via asyncio.

Medium Python 3.9+ Aug 9, 2026 Concurrency & performance 14 views 0 copies

Python code

22 lines
Python 3.9+
import asyncio
import time


def blocking_task(name: str, duration: float) -> str:
    """Simulate a blocking operation."""
    time.sleep(duration)
    return f"Finished {name} after {duration}s"


async def main() -> None:
    loop = asyncio.get_running_loop()
    results = await asyncio.gather(
        loop.run_in_executor(None, blocking_task, "A", 1.0),
        loop.run_in_executor(None, blocking_task, "B", 0.5),
        loop.run_in_executor(None, blocking_task, "C", 0.2),
    )
    print(results)


if __name__ == "__main__":
    asyncio.run(main())

Output

stdout
['Finished A after 1.0s', 'Finished B after 0.5s', 'Finished C after 0.2s']

How it works

asyncio.get_running_loop() retrieves the current event loop. loop.run_in_executor(None, func, *args) schedules func to run in a default thread pool executor, returning a coroutine that you can await. asyncio.gather runs multiple such coroutines concurrently, so the blocking sleeps happen in parallel threads. The event loop stays responsive because time.sleep blocks only the executor threads, not the loop itself.

Common mistakes

  • Using `time.sleep` directly inside an async function, which blocks the event loop.
  • Forgetting to await the result of `run_in_executor`, causing the task never to execute.

Variations

  1. Use `asyncio.to_thread(func, *args)` for a simpler one-liner in Python 3.9+.
  2. Pass a custom executor (e.g., `ThreadPoolExecutor(max_workers=5)`) to control thread count.

Real-world use cases

  • Offloading CPU-bound or blocking database queries from a FastAPI endpoint to keep the server responsive.
  • Performing legacy synchronous file I/O inside an async web crawler without pausing other requests.
  • Running blocking third-party SDK calls (e.g., requests) inside an asyncio-based microservice.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Concurrency & performance

Related tutorials and quizzes for this topic.