Skip to content

python.cpu_in_event_loop

Performance Medium

Detects CPU-bound work (heavy computation, json.loads on large data, cryptographic operations) in async functions without run_in_executor().

The async event loop runs on a single thread. CPU-intensive operations block that thread:

  • All tasks stall — Every concurrent request waits
  • Timeouts cascade — Other operations time out while waiting
  • Async benefits lost — Your “async” code becomes sequential

Even a few hundred milliseconds of CPU work can destroy async performance under load.

# ❌ Before
async def process_large_json(data):
return json.loads(data) # Blocks event loop

If data is 10MB, this blocks the event loop for hundreds of milliseconds.

# ✅ After
async def process_large_json(data):
loop = asyncio.get_event_loop()
return await loop.run_in_executor(None, json.loads, data)

run_in_executor offloads work to a thread pool, freeing the event loop.

  • json.loads() / json.dumps() on potentially large data in async functions
  • Cryptographic operations (hashlib, bcrypt, etc.)
  • Image processing (PIL, cv2)
  • Data parsing (pandas.read_csv, XML parsing)
  • Heavy computation loops

Unfault wraps CPU-bound calls with run_in_executor.

# For CPU-bound work in async code
loop = asyncio.get_event_loop()
result = await loop.run_in_executor(None, cpu_bound_function, arg1, arg2)
# For many CPU-bound tasks, use a ProcessPoolExecutor
from concurrent.futures import ProcessPoolExecutor
executor = ProcessPoolExecutor(max_workers=4)
result = await loop.run_in_executor(executor, heavy_computation, data)