Guides / Monitoring
A queue backlog is usually a leading indicator of a bigger problem: a worker crashed, a downstream service is slow, or a deploy introduced a bug that causes jobs to fail and retry. Logging depth metrics lets you catch this before users see delays.
// jobs/queue-depth-check.ts (runs every 5 minutes via cron)
import { logit } from "@/lib/logit";
import { Queue } from "bullmq";
const emailQueue = new Queue("email-jobs", { connection: redisClient });
export async function checkQueueDepths() {
const waiting = await emailQueue.getWaitingCount();
const active = await emailQueue.getActiveCount();
await logit.now("queue-health", {
event: "Queue depth check",
description: `email-jobs: ${waiting} waiting, ${active} active`,
icon: waiting > 100 ? "🔴" : waiting > 20 ? "🟡" : "🟢",
notify: false,
tags: {
queue: "email-jobs",
severity: waiting > 100 ? "high" : waiting > 20 ? "medium" : "low",
},
metadata: {
queue: "email-jobs",
waiting,
active,
checkedAt: new Date().toISOString(),
},
});
}
The depth check runs every 5 minutes. If the queue stays backed up, you'll see consecutive "high" severity events. Smart Actions detects the pattern:
| Field | Value |
|---|---|
| Name | Email queue backlog |
| Channel | queue-health |
| Event name | Queue depth check |
| Threshold | 3 |
| Window | 15 minutes |
| Cooldown | 30 minutes |
| Action | Push notification |
emailQueue.on("failed", async (job, err) => {
await logit.now("queue-failures", {
event: "Job failed",
description: `[${job?.name}] ${err.message}`,
icon: "❌",
notify: false,
tags: { queue: "email-jobs", jobName: job?.name ?? "unknown" },
metadata: { jobId: job?.id, error: err.message, attempts: job?.attemptsMade },
});
});
queue-health every 5 minutes for depth snapshots, and queue-failures on every failure — different channels, different signal types.severity tag to filter in the dashboard for only "high" events.queue-failures with threshold 10/5min catches worker crashes early.Try LogIt free
7-day trial. No credit card required.