background-jobs-and-cachinglisted
Install: claude install-skill kennguyen887/agent-foundation
# Background jobs & caching
In-process async work (Bull + Redis) and a Redis cache for a backend service. Examples NestJS/TS,
neutral `listing`/`payment` domain. principle → **▸ Example** → **▸ Other stacks**. Cross-service
async (vs this in-process Bull) → the SQS events pattern in `write-service-code` §6.
## When to use
Time-critical, in-process async (reminders, expiry/timeout actions, retries, fan-out) and caching hot
reads. **Bull (this skill) = in-process, Redis-backed, supports delays + per-queue retry; SQS =
cross-service.** Complementary — don't merge them.
## 1. Bull job queues
- **One named queue per job type**, not a single mega-queue — independent concurrency + retry:
```ts
BullModule.registerQueue({ name: REMINDER_QUEUE }, { name: PAYMENT_EXPIRY_QUEUE });
```
Set **default job options** centrally: `removeOnComplete: true`, `removeOnFail: { age: <1h>, count: <N> }`
(so Redis doesn't fill with finished jobs), plus a **retry policy** — `attempts: <n>` with
`backoff: { type: 'exponential', delay: <ms> }` — so a transient failure retries with growing delay
instead of dying on the first error or hammering the dependency instantly.
- **Producer** injects the queue; **processor** handles it:
```ts
@InjectQueue(PAYMENT_EXPIRY_QUEUE) private queue: Queue;
await this.queue.add(JOB.expirePayment, { paymentId }, opts);
@Processor(PAYMENT_EXPIRY_QUEUE)
class PaymentExpiryProcessor {
@Process(JOB.expirePayment) async handle(job: Job) { await thi