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

Sink

Analytics · Bookmarks Archiving

7,231

Serverless link shortener with real-time analytics, powered by Cloudflare

View details
84
Repo Health
80
Technical
0
Dependency
Built with
TypeScript 51%
Vue 47%
Updated 1 months ago
Python
100%
Other

Sourcebot

AI Code Assistants · Developer Tools · Search

4,005

A self-hosted, AI-powered code search engine that indexes every repo across GitHub, GitLab, Bitbucket, Gitea, Gerrit, and Azure DevOps, so both engineers and coding agents can search, browse, and ask questions about your codebase from one place.

View details
86
Repo Health
83
Technical
61
Dependency
Built with
Python 100%
Updated 1 weeks ago
Go
66%
GPL 3.0

Stormkit

Devops · Hosting Control Panel

264

Self-hostable platform for deploying and hosting modern web apps with automated CI/CD, custom domains, and a built-in serverless runtime — a true open-source alternative to Vercel and Netlify.

View details
80
Repo Health
79
Technical
67
Dependency
Built with
Go 66%
TypeScript 31%
Updated 1 weeks ago
TypeScript
99%
Other

Teable

Databases · No Code Platforms

21,920

A no-code PostgreSQL database with spreadsheet UX, real-time collaboration, and native AI agents — built for teams that outgrow Airtable.

View details
78
Repo Health
76
Technical
62
Dependency
Built with
TypeScript 99%
Updated 1 weeks ago
TypeScript
99%
Apache 2.0

Trigger.dev

AI Development · Automation · Developer Tools

16,606

Build and deploy fully-managed AI agents and background jobs in TypeScript — with no timeouts, durable retries, real-time observability, and elastic scaling built in.

View details
90
Repo Health
9
Technical
63
Dependency
Built with
TypeScript 99%
Updated 6 days ago
TypeScript
65%
Other

Typebot

AI Assistants · AI Development · Developer Tools

10,576

Build sophisticated chatbots visually, embed them anywhere without iframes, and own your data — fully self-hostable with a modular block system and 30+ integrations.

View details
94
Repo Health
82
Technical
64
Dependency
Built with
TypeScript 65%
MDX 34%
Updated 1 weeks ago
TypeScript
87%
Other

Webiny JS

Blogging · CMS · Ecommerce

8,047

Open-source, self-hosted CMS on AWS serverless — a TypeScript framework you extend with code, not a product you configure through a UI.

View details
90
Repo Health
86
Technical
61
Dependency
Built with
TypeScript 87%
JavaScript 12%
Updated 1 weeks ago
TypeScript
99%
AGPL 3.0

Webstudio

Design Tools · No Code Platforms

9,103

Open source visual development platform with complete CSS control, headless CMS integration, and full infrastructure ownership

View details
91
Repo Health
79
Technical
60
Dependency
Built with
TypeScript 99%
Updated 1 weeks ago
Rust
33%
Other

Windmill

Automation · Developer Tools

18,257

Turn scripts into webhooks, workflows, and auto-generated UIs — the fastest self-hostable workflow engine, 13x faster than Airflow.

View details
91
Repo Health
82
Technical
64
Dependency
Built with
Rust 33%
TypeScript 24%
Svelte 22%
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