From 979a1ebbed9d756ac938ffbe5b1be55c3a0b1e61 Mon Sep 17 00:00:00 2001 From: Dan Fuller Date: Fri, 16 Oct 2026 17:40:59 -0700 Subject: [PATCH 1/8] docs(crons): Add BullMQ job scheduler setup for Node Co-Authored-By: Claude --- ...-crons-automatic-crons-instrumentation.mdx | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/includes/javascript-crons-automatic-crons-instrumentation.mdx b/includes/javascript-crons-automatic-crons-instrumentation.mdx index 8b78d165e0cf2..5d3f267b15eb0 100644 --- a/includes/javascript-crons-automatic-crons-instrumentation.mdx +++ b/includes/javascript-crons-automatic-crons-instrumentation.mdx @@ -1,4 +1,4 @@ -If you're using the [`cron`](https://www.npmjs.com/package/cron), [`node-cron`](https://www.npmjs.com/package/node-cron) or [`node-schedule`](https://www.npmjs.com/package/node-schedule) libraries to run your periodic tasks, you can use our instrumentation functions in the `Sentry.cron` export to monitor your cron jobs. These functions send the job's schedule with each check-in, so Sentry creates the monitor for you. +If you're using the [`cron`](https://www.npmjs.com/package/cron), [`node-cron`](https://www.npmjs.com/package/node-cron) or [`node-schedule`](https://www.npmjs.com/package/node-schedule) libraries to run your periodic tasks, or [BullMQ](https://www.npmjs.com/package/bullmq) job schedulers, you can use our instrumentation functions in the `Sentry.cron` export to monitor your cron jobs. These functions send the job's schedule with each check-in, so Sentry creates the monitor for you. ### Cron @@ -64,3 +64,32 @@ scheduleWithCheckIn.scheduleJob( } ); ``` + +### BullMQ + + + +BullMQ support ships in the next release of `@sentry/node`. + + + +Use `Sentry.cron.instrumentBullMQWorker` to send check-ins for every job a BullMQ `Worker` runs from a [job scheduler](https://docs.bullmq.io/guide/job-schedulers). The job scheduler ID is the monitor slug, and the scheduler's `pattern` or `every` is sent as the monitor schedule. Jobs that weren't created by a job scheduler aren't monitored. + +```JavaScript +import { Queue, Worker } from "bullmq"; + +const queue = new Queue("reports", { connection }); +await queue.upsertJobScheduler( + "daily-report", + { pattern: "0 9 * * 1-5", tz: "Europe/Vienna" }, + { name: "report" } +); + +const worker = new Worker("reports", processor, { connection }); +Sentry.cron.instrumentBullMQWorker(worker, { + // job scheduler IDs or regular expressions to skip + excludeJobSchedulers: ["cache-warmup", /^tmp-/], +}); +``` + +Sentry creates the monitor from `pattern` schedules and from `every` intervals that are a whole number of minutes. For schedules that can't be expressed in the Crons schedule format (for example, a job that runs every 10 seconds), schedulers with a `limit` or `endDate`, and time zones given as an offset like `UTC+5` rather than an IANA name like `Europe/Vienna`, the SDK sends check-ins without a monitor config, and you need to create the monitor in Sentry with the same slug. Repeatable jobs added with `queue.add` and the `repeat` option aren't monitored. From c6e37844d5ea67e4349582af74c44db8bae4edf7 Mon Sep 17 00:00:00 2001 From: Dan Fuller Date: Tue, 20 Oct 2026 11:29:55 -0700 Subject: [PATCH 2/8] docs(crons): Use the SDK version line for BullMQ like the other sections Co-Authored-By: Claude --- .../javascript-crons-automatic-crons-instrumentation.mdx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/includes/javascript-crons-automatic-crons-instrumentation.mdx b/includes/javascript-crons-automatic-crons-instrumentation.mdx index 5d3f267b15eb0..6cda48bed48df 100644 --- a/includes/javascript-crons-automatic-crons-instrumentation.mdx +++ b/includes/javascript-crons-automatic-crons-instrumentation.mdx @@ -67,11 +67,7 @@ scheduleWithCheckIn.scheduleJob( ### BullMQ - - -BullMQ support ships in the next release of `@sentry/node`. - - +Requires SDK version `11.9.0` or higher and `bullmq` version `5.16.0` or higher. Use `Sentry.cron.instrumentBullMQWorker` to send check-ins for every job a BullMQ `Worker` runs from a [job scheduler](https://docs.bullmq.io/guide/job-schedulers). The job scheduler ID is the monitor slug, and the scheduler's `pattern` or `every` is sent as the monitor schedule. Jobs that weren't created by a job scheduler aren't monitored. From 932ccff98920ec4ccf1fbba944c4c515a7ff397f Mon Sep 17 00:00:00 2001 From: Dan Fuller Date: Thu, 29 Oct 2026 11:03:58 -0700 Subject: [PATCH 3/8] fix(js): Say jobs with unsupported schedules aren't monitored --- includes/javascript-crons-automatic-crons-instrumentation.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/javascript-crons-automatic-crons-instrumentation.mdx b/includes/javascript-crons-automatic-crons-instrumentation.mdx index 6cda48bed48df..873da47e64c8f 100644 --- a/includes/javascript-crons-automatic-crons-instrumentation.mdx +++ b/includes/javascript-crons-automatic-crons-instrumentation.mdx @@ -88,4 +88,4 @@ Sentry.cron.instrumentBullMQWorker(worker, { }); ``` -Sentry creates the monitor from `pattern` schedules and from `every` intervals that are a whole number of minutes. For schedules that can't be expressed in the Crons schedule format (for example, a job that runs every 10 seconds), schedulers with a `limit` or `endDate`, and time zones given as an offset like `UTC+5` rather than an IANA name like `Europe/Vienna`, the SDK sends check-ins without a monitor config, and you need to create the monitor in Sentry with the same slug. Repeatable jobs added with `queue.add` and the `repeat` option aren't monitored. +Sentry creates the monitor from `pattern` schedules and from `every` intervals that are a whole number of minutes. Schedulers with schedules that can't be expressed in the Crons schedule format (for example, a job that runs every 10 seconds), with a `limit` or `endDate`, or with a time zone given as an offset like `UTC+5` rather than an IANA name like `Europe/Vienna` aren't monitored. Repeatable jobs added with `queue.add` and the `repeat` option aren't monitored. From 72ee282f1cb7b3a7b97ebb86fe0f83e62f0785a6 Mon Sep 17 00:00:00 2001 From: Dan Fuller Date: Wed, 11 Nov 2026 10:31:06 -0800 Subject: [PATCH 4/8] docs(crons): Match BullMQ section to the SDK's retry and version behavior Co-Authored-By: Claude --- ...ascript-crons-automatic-crons-instrumentation.mdx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/includes/javascript-crons-automatic-crons-instrumentation.mdx b/includes/javascript-crons-automatic-crons-instrumentation.mdx index 873da47e64c8f..a5ff4f856453c 100644 --- a/includes/javascript-crons-automatic-crons-instrumentation.mdx +++ b/includes/javascript-crons-automatic-crons-instrumentation.mdx @@ -67,7 +67,7 @@ scheduleWithCheckIn.scheduleJob( ### BullMQ -Requires SDK version `11.9.0` or higher and `bullmq` version `5.16.0` or higher. +Requires the next SDK release after `11.12.0`, and `bullmq` version `5.16.0` or higher. Use `Sentry.cron.instrumentBullMQWorker` to send check-ins for every job a BullMQ `Worker` runs from a [job scheduler](https://docs.bullmq.io/guide/job-schedulers). The job scheduler ID is the monitor slug, and the scheduler's `pattern` or `every` is sent as the monitor schedule. Jobs that weren't created by a job scheduler aren't monitored. @@ -88,4 +88,12 @@ Sentry.cron.instrumentBullMQWorker(worker, { }); ``` -Sentry creates the monitor from `pattern` schedules and from `every` intervals that are a whole number of minutes. Schedulers with schedules that can't be expressed in the Crons schedule format (for example, a job that runs every 10 seconds), with a `limit` or `endDate`, or with a time zone given as an offset like `UTC+5` rather than an IANA name like `Europe/Vienna` aren't monitored. Repeatable jobs added with `queue.add` and the `repeat` option aren't monitored. +Patterns use the scheduler's `tz` time zone, or the server's time zone without one. A job that BullMQ retries shows as one check-in, which fails only if the last attempt fails. + +These aren't monitored: + +- Schedules Sentry can't express, like an `every` interval that isn't a whole number of minutes or a pattern that runs every few seconds +- Time zones given as an offset like `UTC+5` rather than an IANA name like `Europe/Vienna` +- Schedulers with a `limit` or `endDate` +- Patterns on a worker with a custom `repeatStrategy` +- Repeatable jobs added with `queue.add` and the `repeat` option From 873a0c4f20bb1594403651d0716f445f568ce2f9 Mon Sep 17 00:00:00 2001 From: Dan Fuller Date: Wed, 11 Nov 2026 11:09:58 -0800 Subject: [PATCH 5/8] docs(crons): Use the queue name in BullMQ monitor slugs Co-Authored-By: Claude --- includes/javascript-crons-automatic-crons-instrumentation.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/javascript-crons-automatic-crons-instrumentation.mdx b/includes/javascript-crons-automatic-crons-instrumentation.mdx index a5ff4f856453c..28485d575ac88 100644 --- a/includes/javascript-crons-automatic-crons-instrumentation.mdx +++ b/includes/javascript-crons-automatic-crons-instrumentation.mdx @@ -69,7 +69,7 @@ scheduleWithCheckIn.scheduleJob( Requires the next SDK release after `11.12.0`, and `bullmq` version `5.16.0` or higher. -Use `Sentry.cron.instrumentBullMQWorker` to send check-ins for every job a BullMQ `Worker` runs from a [job scheduler](https://docs.bullmq.io/guide/job-schedulers). The job scheduler ID is the monitor slug, and the scheduler's `pattern` or `every` is sent as the monitor schedule. Jobs that weren't created by a job scheduler aren't monitored. +Use `Sentry.cron.instrumentBullMQWorker` to send check-ins for every job a BullMQ `Worker` runs from a [job scheduler](https://docs.bullmq.io/guide/job-schedulers). The monitor slug is the queue name and the job scheduler ID joined by `-`, like `reports-daily-report` in the example below, and the scheduler's `pattern` or `every` is sent as the monitor schedule. Jobs that weren't created by a job scheduler aren't monitored. ```JavaScript import { Queue, Worker } from "bullmq"; From dc0235e0253076667cd4ebe528cbe43ddf8e5895 Mon Sep 17 00:00:00 2001 From: Dan Fuller Date: Wed, 11 Nov 2026 12:02:02 -0800 Subject: [PATCH 6/8] docs(crons): Use bullmqJobSchedulerIntegration for BullMQ job schedulers Co-Authored-By: Claude --- ...-crons-automatic-crons-instrumentation.mdx | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/includes/javascript-crons-automatic-crons-instrumentation.mdx b/includes/javascript-crons-automatic-crons-instrumentation.mdx index 28485d575ac88..adf04ee864381 100644 --- a/includes/javascript-crons-automatic-crons-instrumentation.mdx +++ b/includes/javascript-crons-automatic-crons-instrumentation.mdx @@ -1,4 +1,4 @@ -If you're using the [`cron`](https://www.npmjs.com/package/cron), [`node-cron`](https://www.npmjs.com/package/node-cron) or [`node-schedule`](https://www.npmjs.com/package/node-schedule) libraries to run your periodic tasks, or [BullMQ](https://www.npmjs.com/package/bullmq) job schedulers, you can use our instrumentation functions in the `Sentry.cron` export to monitor your cron jobs. These functions send the job's schedule with each check-in, so Sentry creates the monitor for you. +If you're using the [`cron`](https://www.npmjs.com/package/cron), [`node-cron`](https://www.npmjs.com/package/node-cron) or [`node-schedule`](https://www.npmjs.com/package/node-schedule) libraries to run your periodic tasks, you can use our instrumentation functions in the `Sentry.cron` export to monitor your cron jobs. These functions send the job's schedule with each check-in, so Sentry creates the monitor for you. ### Cron @@ -67,9 +67,20 @@ scheduleWithCheckIn.scheduleJob( ### BullMQ -Requires the next SDK release after `11.12.0`, and `bullmq` version `5.16.0` or higher. +Requires the next SDK release after `11.12.0`, and `bullmq` version `5.16.0` or a later `5.x` version. -Use `Sentry.cron.instrumentBullMQWorker` to send check-ins for every job a BullMQ `Worker` runs from a [job scheduler](https://docs.bullmq.io/guide/job-schedulers). The monitor slug is the queue name and the job scheduler ID joined by `-`, like `reports-daily-report` in the example below, and the scheduler's `pattern` or `every` is sent as the monitor schedule. Jobs that weren't created by a job scheduler aren't monitored. +Add `bullmqJobSchedulerIntegration` to send check-ins for every job a BullMQ `Worker` runs from a [job scheduler](https://docs.bullmq.io/guide/job-schedulers). Every worker in your app is monitored, without changes to your worker code: + +```JavaScript +Sentry.init({ + dsn: "___PUBLIC_DSN___", + integrations: [ + Sentry.bullmqJobSchedulerIntegration({ + excludeJobSchedulers: ["cache-warmup", /^tmp-/], // Optional. + }), + ], +}); +``` ```JavaScript import { Queue, Worker } from "bullmq"; @@ -82,12 +93,10 @@ await queue.upsertJobScheduler( ); const worker = new Worker("reports", processor, { connection }); -Sentry.cron.instrumentBullMQWorker(worker, { - // job scheduler IDs or regular expressions to skip - excludeJobSchedulers: ["cache-warmup", /^tmp-/], -}); ``` +The monitor slug is the queue name and the job scheduler ID joined by `-`, like `reports-daily-report` in this example, and the scheduler's `pattern` or `every` is sent as the monitor schedule. Jobs that weren't created by a job scheduler aren't monitored. `excludeJobSchedulers` skips job schedulers whose ID matches a string exactly or a regular expression. + Patterns use the scheduler's `tz` time zone, or the server's time zone without one. A job that BullMQ retries shows as one check-in, which fails only if the last attempt fails. These aren't monitored: @@ -97,3 +106,4 @@ These aren't monitored: - Schedulers with a `limit` or `endDate` - Patterns on a worker with a custom `repeatStrategy` - Repeatable jobs added with `queue.add` and the `repeat` option +- Workers in a server build that bundles BullMQ instead of loading it from `node_modules` From b0e1168a81d700208d3fba0f77200a5a3b6e1973 Mon Sep 17 00:00:00 2001 From: Dan Fuller Date: Wed, 11 Nov 2026 15:07:48 -0800 Subject: [PATCH 7/8] docs(crons): Cover BullMQ 6, Next.js externals, and init order Hide the BullMQ section on Bun, which doesn't export the integration. Co-Authored-By: Claude Opus 5.5 --- ...-crons-automatic-crons-instrumentation.mdx | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/includes/javascript-crons-automatic-crons-instrumentation.mdx b/includes/javascript-crons-automatic-crons-instrumentation.mdx index adf04ee864381..0de73c4240f1c 100644 --- a/includes/javascript-crons-automatic-crons-instrumentation.mdx +++ b/includes/javascript-crons-automatic-crons-instrumentation.mdx @@ -1,5 +1,11 @@ If you're using the [`cron`](https://www.npmjs.com/package/cron), [`node-cron`](https://www.npmjs.com/package/node-cron) or [`node-schedule`](https://www.npmjs.com/package/node-schedule) libraries to run your periodic tasks, you can use our instrumentation functions in the `Sentry.cron` export to monitor your cron jobs. These functions send the job's schedule with each check-in, so Sentry creates the monitor for you. + + +If you run jobs from [BullMQ](https://docs.bullmq.io) job schedulers, add `bullmqJobSchedulerIntegration` to monitor them, as described in [BullMQ](#bullmq) below. + + + ### Cron Requires SDK version `7.92.0` or higher. @@ -65,9 +71,11 @@ scheduleWithCheckIn.scheduleJob( ); ``` + + ### BullMQ -Requires the next SDK release after `11.12.0`, and `bullmq` version `5.16.0` or a later `5.x` version. +Requires the next SDK release after `11.12.0`, and `bullmq` version `5.16.0` to `6.x`. Add `bullmqJobSchedulerIntegration` to send check-ins for every job a BullMQ `Worker` runs from a [job scheduler](https://docs.bullmq.io/guide/job-schedulers). Every worker in your app is monitored, without changes to your worker code: @@ -95,7 +103,25 @@ await queue.upsertJobScheduler( const worker = new Worker("reports", processor, { connection }); ``` -The monitor slug is the queue name and the job scheduler ID joined by `-`, like `reports-daily-report` in this example, and the scheduler's `pattern` or `every` is sent as the monitor schedule. Jobs that weren't created by a job scheduler aren't monitored. `excludeJobSchedulers` skips job schedulers whose ID matches a string exactly or a regular expression. + + +Like the SDK's other auto-instrumentation, this only works if `Sentry.init()` runs before your app imports `bullmq`, so load your instrument file with `--import`. If `bullmq` is imported first, no check-ins are sent. + + + + + +Next.js bundles `bullmq` into your server build by default, which stops this integration from working. Add it to `serverExternalPackages` in your `next.config.js` (`experimental.serverComponentsExternalPackages` on Next.js 14): + +```JavaScript {filename:next.config.js} +const nextConfig = { + serverExternalPackages: ["bullmq"], +}; +``` + + + +The monitor slug is the queue name and the job scheduler ID joined by `-`, like `reports-daily-report` in this example, and the scheduler's `pattern` or `every` is sent as the monitor schedule. Each monitored job scheduler creates its own monitor, and each monitor is billed. Jobs that weren't created by a job scheduler aren't monitored. `excludeJobSchedulers` skips job schedulers whose ID matches a string exactly or a regular expression. Patterns use the scheduler's `tz` time zone, or the server's time zone without one. A job that BullMQ retries shows as one check-in, which fails only if the last attempt fails. @@ -104,6 +130,9 @@ These aren't monitored: - Schedules Sentry can't express, like an `every` interval that isn't a whole number of minutes or a pattern that runs every few seconds - Time zones given as an offset like `UTC+5` rather than an IANA name like `Europe/Vienna` - Schedulers with a `limit` or `endDate` +- On BullMQ 5, patterns with an `nthDayOfWeek` and anything but a single day of the week - Patterns on a worker with a custom `repeatStrategy` - Repeatable jobs added with `queue.add` and the `repeat` option - Workers in a server build that bundles BullMQ instead of loading it from `node_modules` + + From 6355f6aa0f2ca292d7113cc12f8805b802e4d133 Mon Sep 17 00:00:00 2001 From: Dan Fuller Date: Wed, 11 Nov 2026 16:04:38 -0800 Subject: [PATCH 8/8] docs(crons): Cover BullMQ utc, the dropped-seconds margin, manual workers, and CommonJS init Co-Authored-By: Claude Opus 5.5 --- .../javascript-crons-automatic-crons-instrumentation.mdx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/includes/javascript-crons-automatic-crons-instrumentation.mdx b/includes/javascript-crons-automatic-crons-instrumentation.mdx index 0de73c4240f1c..0195936b649d4 100644 --- a/includes/javascript-crons-automatic-crons-instrumentation.mdx +++ b/includes/javascript-crons-automatic-crons-instrumentation.mdx @@ -105,7 +105,7 @@ const worker = new Worker("reports", processor, { connection }); -Like the SDK's other auto-instrumentation, this only works if `Sentry.init()` runs before your app imports `bullmq`, so load your instrument file with `--import`. If `bullmq` is imported first, no check-ins are sent. +Like the SDK's other auto-instrumentation, this only works if `Sentry.init()` runs before your app loads `bullmq`. Load your instrument file with `--import`, or in CommonJS, `require("./instrument")` before any other module. If `bullmq` is loaded first, no check-ins are sent. @@ -123,7 +123,7 @@ const nextConfig = { The monitor slug is the queue name and the job scheduler ID joined by `-`, like `reports-daily-report` in this example, and the scheduler's `pattern` or `every` is sent as the monitor schedule. Each monitored job scheduler creates its own monitor, and each monitor is billed. Jobs that weren't created by a job scheduler aren't monitored. `excludeJobSchedulers` skips job schedulers whose ID matches a string exactly or a regular expression. -Patterns use the scheduler's `tz` time zone, or the server's time zone without one. A job that BullMQ retries shows as one check-in, which fails only if the last attempt fails. +Patterns use the scheduler's `tz` time zone, or the server's time zone without one. On BullMQ 5, `utc: true` sends UTC. If a pattern's seconds field isn't `0`, a check-in margin of 2 minutes is sent too, since the job checks in up to 59 seconds after the minute Sentry expects. This replaces a margin set in Sentry. A job that BullMQ retries shows as one check-in, which fails only if the last attempt fails. These aren't monitored: @@ -133,6 +133,7 @@ These aren't monitored: - On BullMQ 5, patterns with an `nthDayOfWeek` and anything but a single day of the week - Patterns on a worker with a custom `repeatStrategy` - Repeatable jobs added with `queue.add` and the `repeat` option +- Workers created without a processor that fetch jobs themselves with `getNextJob` - Workers in a server build that bundles BullMQ instead of loading it from `node_modules`