Agent-skills-standard nestjs-bullmq
Implement BullMQ job workflows in NestJS. Use when building queue processors, redis-throttler, Upstash limits, idle polling, stalled jobs, and retention policies. (triggers: **/*.processor.ts, **/*.module.ts, **/bull-queue.constants.ts, **/redis-throttler*.ts, queue, background job, worker, processor, bullmq, drainDelay, stalledInterval, removeOnComplete, redis limit, upstash, fail-open, throttler)
install
source · Clone the upstream repo
git clone https://github.com/HoangNguyen0403/agent-skills-standard
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/HoangNguyen0403/agent-skills-standard "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/nestjs/nestjs-bullmq" ~/.claude/skills/hoangnguyen0403-agent-skills-standard-nestjs-bullmq && rm -rf "$T"
manifest:
skills/nestjs/nestjs-bullmq/SKILL.mdsource content
NestJS BullMQ Implementation
Priority: P0 (Critical)
Guidelines
- Set idle polling: Add
+drainDelay
+stalledInterval
to everymaxStalledCount
. Default@Processor
(5 ms) burns 570M Redis commands/day at idle. See patterns.md.drainDelay - Throttle worker error logs: BullMQ workers emit raw unhandled ReplyErrors on Redis failure (e.g. Upstash rate limits). Always extend
instead ofBaseProcessor
to rate-limit these logs. See patterns.md.WorkerHost - Set job retention: Add
,removeOnComplete
,removeOnFail
,attempts
to everybackoff
. See patterns.md.BullModule.registerQueue - Use shared constants: All numeric options live in
. Key constants:src/common/constants/bull-queue.constants.ts
(10 000 ms),QUEUE_DRAIN_DELAY_MS
(60 000 ms). UseQUEUE_STALLED_INTERVAL_MS
helper forgetSharedBullQueueOptions
. Queue/job names go inregisterQueue
. Never inline magic numbers.{feature}.constants.ts - Wrap every
: Persist DB record first, then enqueue inside try-catch. Redis errors must not surface as 500s. See patterns.md.queue.add() - Throttler fail-open:
registered as globalThrottlerGuard
— Redis blip propagates errors to ALL HTTP routes.APP_GUARD
must catch all Redis errors and return fail-open pass-through record. Redis blip must not kill all HTTP routes. See patterns.md.RedisThrottlerStorage.increment() - Guard new queues: Follow
conditional + mock token pattern in every module. NestJS DI throws on startup without mock.isRedisEnabled() - Keep processor and cron: Cron schedules; processor executes. Both always required — they complementary. See patterns.md.
- Use local Redis in dev: Never point dev machines at Upstash — idle workers exhaust free tier (500K/day) in minutes.
Anti-Patterns
- No bare
: Always pass worker options object with@Processor(NAME)
anddrainDelay
.stalledInterval - No bare
extension: Always extendWorkerHost
instead to intercept and rate-limit worker errors.BaseProcessor - No
withoutregisterQueue
: Omitting causes unbounded Redis memory growth.defaultJobOptions - No inline numbers: Use
— never writebull-queue.constants.ts
,10_000
,60_000
,50
,20
, or3
directly.5_000 - No unguarded
: Wrap in try-catch; persist DB state first.queue.add() - No throws in throttler increment: Catch Redis errors; return fail-open record.
- No missing mock token: Provide
mock whengetQueueToken
.redisEnabled = false - No removing processor because cron exists: They serve different roles.
- No cloud Redis in dev: Use local Docker Redis.