How to Control Promise Concurrency in JavaScript

Learn how to limit concurrent API calls in JavaScript using async queues and promise batching — a crucial skill for scalable frontend systems.

advancedAsync and promisesjavascriptpromisesasync-awaitconcurrencyrate limiting
Published: 11/12/2025
Updated: 11/12/2025

Advertisement

Question

You have 100 API calls to make, but you want to run only 5 at a time to avoid hitting rate limits.

How would you control the concurrency of async requests in JavaScript?


Explanation

When you use Promise.all, all promises run concurrently.
But if you call an API too many times simultaneously, you can trigger rate limits or browser connection limits.

A better pattern is to use a task queue or promise pool.


Example: Limited Concurrency with Async Queue

async function asyncPool(limit, tasks) {
  const results = [];
  const executing = new Set();

  for (const task of tasks) {
    const p = task().then((res) => {
      executing.delete(p);
      return res;
    });
    results.push(p);
    executing.add(p);

    if (executing.size >= limit) {
      await Promise.race(executing);
    }
  }

  return Promise.all(results);
}

Usage:

const urls = Array.from({ length: 100 }, (_, i) => `https://api.com/data/${i}`);
const tasks = urls.map((url) => () => fetch(url).then((r) => r.json()));

asyncPool(5, tasks).then(console.log);

Visualization

graph TD A[100 Tasks] -->|Limit 5| B[Run Batch 1] B --> C[Wait for One to Finish] C -->|Next Batch| D[Run Batch 2] D --> E[All Done ✅]

This ensures only 5 concurrent requests at a time.

Real-World Usage

  • API integrations with rate-limits
  • Uploading files in controlled batches
  • Processing long-running tasks efficiently

Summary

  • Promise.all = runs everything at once
  • asyncPool pattern = concurrency-safe
  • Use Promise.race() to know when any async task finishes
  • Great for real-world apps with throttling or large data processing
Related Videos
Watch these videos to learn more about this topic
Frequently Asked Questions

Can Promise.all be used directly for concurrency control?

No, Promise.all triggers all promises at once. You need to batch or queue them manually.

Advertisement


Stay Updated

Get the latest frontend challenges, interview questions and tutorials delivered to your inbox.

Advertisement