p-limit
A tiny, battle-tested utility for running async functions with a strict concurrency limit.
Repository Health
Technical Analysis
p-limit is a minimal utility for controlling how many promise-returning or async functions run at once. Instead of firing off every task simultaneously and overwhelming an API, database, or file system, you wrap each call with a limit() function that queues work beyond a fixed concurrency ceiling and lets it through as earlier tasks finish.
Created by Sindre Sorhus and used across a huge share of the JavaScript ecosystem, p-limit has become a de facto way to throttle concurrent async work in Node.js and the browser. The current version adds a map() helper for batch processing, an options object with rejectOnClear, and a runtime-adjustable concurrency setter, while keeping the core API to a single function call.
What You Get
- Simple wrapper API - Call
limit(fn, ...args)to schedule any async function under the concurrency ceiling; no class instantiation or setup required. - Built-in
map()helper -limit.map(iterable, mapperFunction)batches an iterable through the same limiter in one call, replacing manualPromise.allplus.map()boilerplate. - Live introspection -
activeCountandpendingCountgetters let you report progress or debug queue backpressure while tasks are running. - Runtime-adjustable concurrency - The
concurrencyproperty is a live setter, so you can raise or lower the limit in response to rate-limit responses without rebuilding the limiter. - Graceful shutdown support -
clearQueue()discards pending (not yet started) tasks, with an optionalrejectOnClearmode that rejects them with anAbortErrorinstead of leaving them unresolved.
Common Use Cases
- Throttling third-party API calls - Cap concurrent HTTP requests to an external service so you don’t trip its rate limiter.
- Batch file or database operations - Process large lists of files, rows, or records without opening thousands of simultaneous file handles or DB connections.
- Web scraping and crawling - Limit how many pages a crawler fetches at once to avoid overwhelming the target server or the local network.
- Bounding fan-out in serverless functions - Keep concurrent downstream calls under a function’s connection or memory limits.
Under The Hood
Architecture
p-limit is a single ~130-line ESM module (index.js) built as a closure-based state machine rather than a class. The pLimit(concurrency) factory returns a generator function decorated via Object.defineProperties with activeCount, pendingCount, clearQueue, a live concurrency getter/setter, and map. Internally, enqueue pushes a {reject, run} item onto a yocto-queue instance and calls resumeNext, which dequeues and runs items while activeCount is under the limit; run invokes the wrapped function, resolves the caller’s promise immediately with the inner result promise (so callers don’t wait for scheduling), then awaits completion before calling next to decrement activeCount and pull the next item. This inversion — resolving with a promise-of-a-promise rather than the awaited value — is what lets p-limit preserve async execution context (verified in tests via AsyncLocalStorage) without extra bookkeeping.
Tech Stack
The package ships pure ESM ("type": "module") with a single runtime dependency, yocto-queue, a linked-list-based FIFO queue chosen to avoid the O(n) cost of Array.prototype.shift() on large backlogs. It targets Node.js >=20 and browsers with no transpilation or bundling step — index.js and a hand-written index.d.ts are published as-is. Development tooling is Sindre Sorhus’s standard set: xo for linting (a strict, zero-config ESLint preset), ava for tests, and tsd for type-level tests against index.d.ts.
Code Quality
test.js is extensive relative to the module’s size, covering concurrency limits under real timing assertions (time-span, in-range), async-context propagation, error propagation through Promise.all, clearQueue with and without rejectOnClear, dynamic concurrency changes (both raising and lowering mid-run), and every map() variant (arrays, Set, iterators, detached from limit). Type safety is enforced separately via index.test-d.ts and tsd. No swallowed errors: the one catch {} in run() is deliberately commented as intentional, to prevent unhandled rejections while preserving the original rejection for the caller’s own promise.
API Design
The public surface is deliberately tiny: a single default export function that returns a callable object, plus one named export (limitFunction) for the single-function-owns-its-concurrency case. Optional behavior (rejectOnClear) is exposed through an options object rather than extra positional parameters, and state is exposed as plain getters/setters (activeCount, concurrency) instead of methods. Getting started requires one line (const limit = pLimit(5)), and recipes.md documents eight real-world patterns (batch processing, graceful shutdown, dynamic concurrency, shared context, progress reporting) beyond the core README, which is unusually thorough documentation for a package this small.
Used by 43 apps in this directory
Activepieces
Automation · AI Assistants
Open-source AI automation platform that converts 280+ workflow integrations into MCP servers for LLMs, with no-code builders and TypeScript extensibility.
Actual
Invoicing Finance
Local-first personal finance with envelope budgeting, end-to-end encryption, and multi-device sync — no subscription required.
Botpress
AI Assistants · AI Development · Customer Support
The open-source hub for building and deploying LLM-powered AI agents with TypeScript-first tooling, 40+ integrations, and a revolutionary code-execution agent framework.
Bun
Developer Tools
An all-in-one JavaScript and TypeScript toolkit — one Rust-and-JavaScriptCore binary that replaces Node.js, npm, a bundler, and a test runner with faster equivalents.
Cal.diy
Scheduling
The 100% MIT-licensed, community-driven scheduling platform — self-host your own booking infrastructure with no enterprise strings attached.
Codebuff
AI Code Assistants
An open-source AI coding assistant that coordinates specialized agents to edit your codebase from natural language — including Freebuff, a free, ad-supported version powered entirely by open-source models like DeepSeek and Kimi.
Continue
Developer Tools · AI Development · AI Code Assistants
Open-source coding agent for VS Code, JetBrains, and CLI with support for 30+ LLM providers.
Directus
CMS · Low Code Platforms
Connect any SQL database and get instant REST and GraphQL APIs, a visual management Studio, and a native MCP server for AI agents — free for most organizations.
Dittofeed
Marketing · Automation
Open-source omni-channel customer engagement platform for automating transactional and marketing messages via email, SMS, WhatsApp, Slack, and mobile push.