@devxcommerce/strapi-middlewares
v2.2.0
Published
Reusable Strapi 5 middlewares as an auto-discovered plugin (concurrency limiter with bounded-queue load-shedding, …)
Readme
@devxcommerce/strapi-middlewares
Reusable Strapi 5 app middlewares.
Install
bun add @devxcommerce/strapi-middlewares
# or: npm install @devxcommerce/strapi-middlewaresconcurrency
Per-instance inbound concurrency gate with bounded-queue load-shedding. Processes at most limit requests concurrently on the gated paths; the rest queue FIFO. Once more than maxQueue are waiting, new requests get a fast 503 Retry-After instead of growing an unbounded queue — bounding memory and giving clients a quick, honest failure rather than a slow upstream timeout.
Built on p-limit (which owns the queue mechanics); this adds the shedding guard on top.
Usage
This package is an auto-discovered Strapi plugin (via its strapi.kind marker) — installing it is enough, no config/plugins.ts entry needed. Reference the middleware by name in config/middlewares.ts to place it in the chain and pass config (bind env vars here — the package never reads process.env). No shim file, no resolve path.
export default ({ env }) => [
'strapi::logger',
{
name: 'plugin::devx-middlewares.concurrency',
config: {
limit: env.int('STRAPI_MAX_CONCURRENCY', 15),
// maxQueue defaults to limit * 10; override or set 0 to disable shedding
maxQueue: env.int('STRAPI_MAX_QUEUE', 150),
},
},
'strapi::errors',
// …rest of the default stack
];Config
| Option | Type | Default | Description |
|---|---|---|---|
| limit | number | 15 | Max requests processed at once, per instance. |
| paths | string[] | ['/api', '/graphql'] | Path prefixes to gate (health/admin/plugin routes bypass). |
| maxQueue | number | limit * 10 | Max requests allowed to wait before shedding with 503. 0 = unbounded (disable shedding). |
| retryAfter | number | 1 | Retry-After header (seconds) sent with the 503. |
Total capacity across a fleet =
instances × limit. SetmaxQueuein production so a spike/retry storm can't grow the queue (and heap) without bound.
Uses
p-limit@3(the last CommonJS release) so itrequire()s cleanly in Strapi's CJS runtime on Node 20+. Do not bump to v4+ (ESM-only).
Config is validated at construction (
limitinteger ≥ 1,maxQueue≥ 0,retryAfter≥ 0) — a bad value fails the boot with a clear message instead of crashing inside p-limit. Shed events are logged at most once per 10s with an aggregated count, so a retry storm can't turn the gate into a log-flood.
Requirements
- Strapi
^5 - Node
>=20 <=24
Links
License
MIT
