PYTHON Contents

IO-bound vs CPU-bound (Choosing the Right Tool)

Choose the right concurrency tool by workload: I/O-bound vs CPU-bound, and avoid architecture decisions based on guesswork.

On this page

Classify the Work

  • I/O-bound: waiting on network/disk dominates
  • CPU-bound: computation dominates
  • Mixed: needs separation (offload CPU work)

Decision Table

  • I/O-bound: threads or asyncio
  • CPU-bound: multiprocessing or native extensions
  • Mixed: async for I/O + process pool for CPU tasks

Mixed Example: Offload CPU

import asyncio
from concurrent.futures import ProcessPoolExecutor

def cpu(x: int) -> int:
    return x * x

async def main():
    loop = asyncio.get_running_loop()
    with ProcessPoolExecutor(max_workers=4) as ex:
        result = await loop.run_in_executor(ex, cpu, 10)
        return result

print(asyncio.run(main()))

Operational Checklist

  • Measure under realistic load before committing to a concurrency model.
  • Bound concurrency and add timeouts around external calls.
  • Design shutdown behavior (cancellation, draining queues) explicitly.

Failure Modes

  • Complexity tax: mixing models without need increases incident risk.
  • Overload: fan-out without limits saturates CPU, memory, or dependencies.