Run MR refs cleanup scheduler hourly and allow higher capacity

What does this MR do and why?

Changes the schedule_merge_request_cleanup_refs_worker cron default from every minute to hourly, and adds an ops feature flag (increased_merge_request_cleanup_refs_capacity, default off) that raises the MergeRequestCleanupRefsWorker concurrency cap from 4 to 6.

Context in gitlab-org/gitlab#634146: GitLab.com overrides this cron to once a year (Jan 1), a 2021 incident stopgap that was never removed. The result is that MR refs cleanup on GitLab.com is dead most of the year — ~53M cleanup schedules are currently waiting, and refs of merged/closed MRs stay in Gitaly for up to a year instead of ~14 days.

Why hourly instead of every minute

MergeRequestCleanupRefsWorker is a LimitedCapacity::Worker: once kicked it re-enqueues itself while due work remains, so the cron's only job is restarting idle chains. Hourly keeps cleanup timely on every distribution (self-managed, charts, Dedicated — none of them override this value) while removing the every-minute scheduler churn, and makes removing the GitLab.com override an easier conversation with infra.

Why the capacity flag

The concurrency cap is what actually bounds Gitaly load (the cron cadence does not change it). The January–April 2026 drain on GitLab.com completed ~105M cleanups at ~13 jobs/second with the cap of 4, without incident. Raising the cap to 6 during the backlog drain shortens it from ~2 months to ~4–6 weeks; the ops flag keeps it toggleable (and off by default) so it can be backed off instantly if Gitaly shows strain.

Rollout plan (tracked in #634146)

  1. This MR merges: all distributions move to the hourly default; nothing changes on GitLab.com yet (the yearly override still shadows it, and the flag is off).
  2. gitlab-com/gl-infra/k8s-workloads/gitlab-com!5918 (draft) removes the yearly override — that is the activation step for GitLab.com, held until this MR ships to production and coordinated with infra/Gitaly on the issue.
  3. Optionally enable increased_merge_request_cleanup_refs_capacity on GitLab.com during the backlog drain, then disable it once drained.

References

How to set up and validate locally

  1. bin/rspec spec/workers/merge_request_cleanup_refs_worker_spec.rb
  2. In a Rails console: MergeRequestCleanupRefsWorker.new.max_running_jobs returns 4; after Feature.enable(:increased_merge_request_cleanup_refs_capacity) it returns 6.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist.

🤖 Generated with claude-flow

Edited by zli

Merge request reports

Loading
Loading