AceDevHub
Advanced JavaScript Interview QuestionsAdvancedPractical

JavaScript · Question 89

How would you limit concurrency when processing thousands of asynchronous operations instead of calling Promise.all() on all of them?

Direct answer

Use a bounded worker pool, semaphore, queue, or chunking strategy so only a controlled number of operations are in flight at once; this preserves concurrency without overwhelming remote services, memory, sockets, or the browser.

Calling Promise.all(items.map(doWork)) starts every mapped operation immediately if doWork initiates work synchronously. For a few items this is ideal. For tens of thousands of network or resource-heavy operations it can create a burst far beyond what the service or client should handle.

A bounded approach might start, for example, eight worker loops. Each worker takes the next item, awaits it, records the result, then takes another. At most eight operations are active. Another common abstraction is a semaphore that requires acquiring a permit before starting work and releases it in finally.

  • Choose the limit based on the bottleneck: API rate limits, browser connection behavior, memory, CPU, or downstream capacity.
  • Preserve result ordering separately if callers require outputs aligned with the original input order.
  • Decide failure semantics explicitly: fail fast, collect all errors, retry selected failures, or continue best-effort.