p-limit

A tiny, battle-tested utility for running async functions with a strict concurrency limit.

Library
npm
v7.3.3
2,934 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
58 /100 Fair
Development Activity 48
Maintenance 36
Community 48
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
78 /100 Good
Architecture 78
Code Quality 88
Innovation 92
Learning Curve 55

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 manual Promise.all plus .map() boilerplate.
  • Live introspection - activeCount and pendingCount getters let you report progress or debug queue backpressure while tasks are running.
  • Runtime-adjustable concurrency - The concurrency property 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 optional rejectOnClear mode that rejects them with an AbortError instead 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 45 apps in this directory

TypeScript
84%
Apache 2.0

ktx

AI Development · Analytics · Data Engineering

1,623

ktx builds a self-improving context layer over your data warehouse so AI agents like Claude Code and Codex query it with approved metric definitions instead of reinventing SQL logic from scratch.

View details
52
Repo Health
85
Technical
71
Dependency
Built with
TypeScript 84%
Updated 1 weeks ago
TypeScript
96%
Other

Langfuse

AI Development · Monitoring

36,276

Open source AI engineering platform for LLM observability, prompt management, evaluation, and debugging — self-host in minutes or use Langfuse Cloud.

View details
92
Repo Health
81
Technical
65
Dependency
Built with
TypeScript 96%
Updated 6 days ago
TypeScript
97%
Other

Lightdash

Analytics · Data Engineering

6,196

The open-source Looker alternative that turns your dbt project's metrics and dimensions into governed, self-serve charts and dashboards — no license key required.

View details
93
Repo Health
84
Technical
64
Dependency
Built with
TypeScript 97%
Updated 6 days ago
TypeScript
96%
MIT

likec4

Developer Tools · Devops

5,954

Define your software architecture as code and get always up-to-date, interactive C4 diagrams generated automatically from a DSL.

View details
89
Repo Health
83
Technical
78
Dependency
Built with
TypeScript 96%
Updated 6 days ago
TypeScript
98%
MPL 2.0

Logto

Authentication

14,769

Open-source auth infrastructure for SaaS and AI apps with OIDC, SAML, and RBAC

View details
92
Repo Health
83
Technical
63
Dependency
Built with
TypeScript 98%
Updated 1 weeks ago
TypeScript
92%
Other

n8n

Automation · No Code Platforms

208,437

Code when you need it, UI when you don't — the workflow automation platform built for technical teams who refuse to choose.

View details
95
Repo Health
87
Technical
62
Dependency
Built with
TypeScript 92%
Updated 1 weeks ago
TypeScript
90%
MIT

OpenClaw

AI Agents · AI Assistants

392,894

An open-source AI assistant that runs on your own hardware and meets you in Discord, Slack, WhatsApp, iMessage, Telegram, and 20+ other channels, with native apps for every major platform.

View details
88
Repo Health
88
Technical
66
Dependency
Built with
TypeScript 90%
Updated 6 days ago
JavaScript
90%
Other

OpenSign

Digital Signiture

7,163

Self-host a full-featured DocuSign alternative with unlimited e-signatures, multi-signer workflows, and cryptographic PDF signing.

View details
83
Repo Health
61
Technical
69
Dependency
Built with
JavaScript 90%
Updated 1 weeks ago
JavaScript
64%
AGPL 3.0

overleaf

Collaboration · Productivity

18,266

Open-source, real-time collaborative LaTeX editor with sandboxed compilation and full TeXLive support for self-hosted academic and research teams.

View details
84
Repo Health
80
Technical
59
Dependency
Built with
JavaScript 64%
TypeScript 30%
Updated 1 months ago

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers