Show me how the concurrency limiter actually queues tasks.
Show me how the concurrency limiter actually queues tasks.
About sindresorhus/p-limit · 2 messages · last activity 6/29/2026
The concurrency limiter uses a queue-based architecture to manage task execution. Here's how it works:
Task Queueing Process
When you call the limit function with a task, the enqueue function handles queuing [index.js:L50-L62]:
const enqueue = (function_, resolve, reject, arguments_) => {
const queueItem = {reject};
// Queue the internal resolve function instead of the run function
// to preserve the asynchronous execution context.
new Promise(internalResolve => { // eslint-disable-line promise/param-names
queueItem.run = internalResolve;
queue.enqueue(queueItem);
}).then(run.bind(undefined, function_, resolve, arguments_)); // eslint-disable-line promise/prefer-await-to-then
// Start processing immediately if we haven't reached the concurrency limit
if (activeCount < concurrency) {
resumeNext();
}
};
The Queue Data Structure
The queue stores queueItem objects, each containing a reject function and a run function. The run function is set to internalResolve when the item is enqueued.
Task Execution Flow
-
Immediate Start: If
activeCount < concurrency,resumeNext()is called immediately [index.js:L61-L62] -
resumeNext Logic [index.js:L18-L22]:
const resumeNext = () => {
// Process the next queued function if we're under the concurrency limit
if (activeCount < concurrency && queue.size > 0) {
activeCount++;
queue.dequeue().run();
}
};
-
Task Execution: When
queue.dequeue().run()is called, it triggers therunfunction [index.js:L27-L44], which:- Executes the actual function
- Resolves the promise immediately (without waiting)
- Awaits completion internally
- Calls
next()to decrementactiveCountand process the next queued task
-
Cleanup: The
next()function [index.js:L24-L26] decrements the active count and callsresumeNext()to process the next item if queue space is available.
This creates a pipeline where tasks are queued until concurrency slots open up, maintaining the concurrency limit throughout execution.
FOLLOW_UPS:
- How does the clearQueue method work exactly?
- What happens if concurrency limit is changed dynamically?
- How does the map function leverage the queue system?
Want to ask your own question?
Open chat for sindresorhus/p-limitPublic Q&A. Generated by RepoPilot from the actual source of sindresorhus/p-limit. AI answers can be incomplete or stale — verify before relying on them.