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
94%
AGPL 3.0

Papra

Bookmarks Archiving

5,587

Self-hosted document archiving with email ingestion, OCR full-text search, and pluggable storage — store once, find anything.

View details
86
Repo Health
82
Technical
69
Dependency
Built with
TypeScript 94%
Updated 1 weeks ago
TypeScript
98%
AGPL 3.0

paseo

AI Agents · AI Code Assistants

21,830

One unified interface to orchestrate Claude Code, Codex, Copilot, OpenCode, and Pi agents in parallel from desktop, mobile, or the terminal.

View details
88
Repo Health
83
Technical
66
Dependency
Built with
TypeScript 98%
Updated 6 days ago
TypeScript
96%
MIT

Payload CMS

Blogging · CMS · Developer Tools

45,458

The open-source, Next.js-native headless CMS that lives inside your /app folder and gives you a full TypeScript backend instantly.

View details
92
Repo Health
88
Technical
65
Dependency
Built with
TypeScript 96%
Updated 6 days ago
Clojure
73%
MPL 2.0

Penpot

Design Tools

61,563

Open-source design platform with GPU-accelerated canvas, native design tokens, and MCP-powered AI workflows for teams that ship fast.

View details
91
Repo Health
83
Technical
72
Dependency
Built with
Clojure 73%
Updated 1 weeks ago
Python
55%
Other

PostHog

Ab Testing Experimentation · Analytics · Developer Tools

40,397

The all-in-one open source product platform combining analytics, session replay, feature flags, error tracking, AI observability, and a built-in data warehouse in a single self-hostable stack.

View details
92
Repo Health
80
Technical
65
Dependency
Built with
Python 55%
TypeScript 36%
Updated 6 days ago
TypeScript
81%
AGPL 3.0

Postiz

Automation · Social Media

37,683

The agentic social media scheduler — AI-powered content creation, 33-platform posting, and team workflows, all self-hosted.

View details
92
Repo Health
70
Technical
63
Dependency
Built with
TypeScript 81%
JavaScript 11%
Updated 1 weeks ago
TypeScript
99%
Apache 2.0

reader

Data Engineering · Developer Tools

562

Production-grade open source web scraping engine that turns any URL into clean markdown for AI agents — with built-in anti-bot bypass, proxy rotation, and browser session management.

View details
55
Repo Health
79
Technical
75
Dependency
Built with
TypeScript 99%
Updated 3 weeks ago
TypeScript
96%
Other

Refly

AI Development · Automation · No Code Platforms

7,537

Build deterministic, versioned agent skills from natural language—run them anywhere from Claude Code to Slack.

View details
68
Repo Health
76
Technical
63
Dependency
Built with
TypeScript 96%
Updated 1 weeks ago
TypeScript
97%
Other

Rocket.Chat

Team Chat

46,304

The secure, self-hosted team communications platform for organizations that cannot compromise on data sovereignty.

View details
96
Repo Health
79
Technical
63
Dependency
Built with
TypeScript 97%
Updated 6 days 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