Skip to content

fix(sidekiq): Start a new trace for each sidekiq-scheduler enqueue - #3159

Merged
sl0thentr0py merged 1 commit into
masterfrom
fix/sidekiq-scheduler-fresh-trace
Oct 27, 2026
Merged

sl0thentr0py merged 1 commit into
masterfrom
fix/sidekiq-scheduler-fresh-trace

Conversation

@sentry-junior

@sentry-junior sentry-junior Bot commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

Description

Jobs enqueued by sidekiq-scheduler all reuse the propagation context of the scheduler's long-lived thread. Every scheduled job in a process therefore shares one trace_id. Since 6.0 (propagated sample_rand, #2671) they also share one sample_rand, so with a sample rate of 0.5 each boot traces either all scheduled runs or none of them.

This wraps SidekiqScheduler::Scheduler#enqueue_job the same way Sentry::Sidekiq::Cron::Job wraps enqueue! (#2446). It clones the hub, opens a fresh scope and starts a transaction (op: queue.sidekiq-scheduler, origin: auto.queue.sidekiq.scheduler) named after the job class. Each scheduled run gets its own trace and sampling decision, and the job's queue.publish span is recorded under that transaction.

The change lives in the existing opt-in :sidekiq_scheduler patch. enqueue_job also handles manual enqueues, such as "Enqueue now" in the sidekiq-scheduler web UI, so those get a fresh trace too.

Verification

  • New specs in spec/sentry/sidekiq-scheduler/scheduler_spec.rb check that enqueue_job produces a transaction with a queue.publish span. They also check that two enqueues get different trace_ids and sample_rands in the job's propagation headers. Both specs fail without the fix and pass with it.
  • The full sentry-sidekiq suite passes on ruby-3.4_sidekiq-7.0 (sidekiq-scheduler 5.0) and ruby-3.4_sidekiq-8.0.0 (sidekiq-scheduler 6.0): 80 examples, 0 failures.
  • RuboCop reports no offenses on the changed files.
  • End to end, I ran a real Sidekiq 8 process with sidekiq-scheduler running a job every second and a traces_sampler returning 0.5. Before the fix, each boot had exactly one trace_id and one sample_rand, so sampling was all-or-nothing. With this branch, every job got its own trace and sampling was mixed within each boot (3/7, 5/7 and 2/7 sampled).

via @sl0thentr0py.

--

View Junior Session [Sentry]

@linear-code

linear-code Bot commented Oct 27, 2026

Copy link
Copy Markdown

RUBY-230

Jobs enqueued by sidekiq-scheduler all continued the scheduler thread's
long-lived propagation context, so every scheduled job in a process shared
one trace_id and, since 6.0, one sample_rand (an all-or-nothing sampling
decision per boot).

Wrap SidekiqScheduler::Scheduler#enqueue_job in a fresh hub, scope and
transaction, mirroring the sidekiq-cron patch.

Fixes #3144

Co-Authored-By: Neel Shah <6536764+sl0thentr0py@users.noreply.github.com>
@sl0thentr0py
sl0thentr0py force-pushed the fix/sidekiq-scheduler-fresh-trace branch from d38abad to 012a303 Compare October 27, 2026 13:22
@sl0thentr0py
sl0thentr0py merged commit d3a1bdf into master Oct 27, 2026
157 checks passed
@sl0thentr0py
sl0thentr0py deleted the fix/sidekiq-scheduler-fresh-trace branch October 27, 2026 13:36
@Trolorol

Copy link
Copy Markdown

Thanks for the work on this! Do you know when this change is expected to be included in a release?

@sl0thentr0py

Copy link
Copy Markdown
Member

@Trolorol will likely release by tomorrow

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

sidekiq-scheduler jobs share one trace per process, and since 6.0 one sampling decision per process

2 participants