Async #8 — Concurrency Control & Retry Patterns

Execute async tasks sequentially, with a concurrency pool, retry with exponential backoff, and cancel in-flight operations — all with runnable examples.

12 min read
JavaScript
Async
Concurrency
Patterns

TABLE OF CONTENTS
Async #8 — Concurrency Control & Retry Patterns

Running 1000 fetch calls in parallel can overwhelm your server or hit rate limits. This article covers three patterns: sequential execution, pooled concurrency (N at a time), and retry with exponential backoff.

Prerequisites: Async #3 — Promises


1. Execute Async Tasks in Sequence

Run an array of async functions one after another — each waits for the previous to complete:

Loading editor...

Promise.all would run them concurrently (~300ms) but with no concurrency control.


2. Concurrency Pool — Run N at a Time

Run tasks with a maximum concurrency limit:

Loading editor...


3. Simpler Pool Using Promise.race

An alternative implementation — start limit tasks, then replace each as it completes:

Loading editor...


4. Retry with Exponential Backoff

When an operation can fail transiently (network, rate limits), retry with increasing delays:

Loading editor...


5. Retry + Concurrency Pool Combined

Real-world scenario: process a list of URLs with concurrency control AND per-item retry:

Loading editor...


6. Timeout Wrapping

Add a timeout to any async operation — reject if it takes too long:

Loading editor...


Key Takeaways

  • Sequential: for...of + await — simplest, preserves order, no concurrency overhead.
  • Pool (N at a time): worker pattern — good when you need to limit load on server/DB.
  • Promise.race approach: start tasks, replace as they complete — elegant alternative to worker pattern.
  • Retry with backoff: exponential delay + jitter prevents thundering herd on recovery.
  • Timeout wrapping: Promise.race(promise, timeoutPromise) — reject if the operation exceeds the limit.

Next: Async #9 — AbortController & Cancelable Async — cancel fetch requests, remove listeners, and abort async work.


Let's Connect

© 2026 Naveen Karthik // Built with React & MUI