Async/await maps coroutines onto event loops. The basic example is easy; production patterns (cancellation, concurrent operations, error handling, backpressure) are where teams get tangled. The good patterns are language-agnostic.

Advertisement

Concurrent independent operations

await Promise.all([fetchA(), fetchB(), fetchC()]) in JS, asyncio.gather in Python, structured concurrency in Kotlin. Sequence requests in parallel when their inputs are independent. Easy 3x speedup; commonly missed.

Cancellation

Long async operations need to be cancellable: timeout, user cancels, parent cancels. Use AbortSignal (JS), CancellationToken (.NET), structured concurrency scopes (Kotlin, Java). Don't ignore cancellation — leaks zombie operations.

Advertisement

Error handling

Errors in async operations propagate through await. Uncaught rejected promises crash the process (in modern Node). Test the error paths; they're harder to reproduce than sync errors.

Parallelize independent ops, design for cancellation from day 1, test error paths. Async ≠ free correctness.