.ai/principles/distilled/workers.md
ApplicationWorker instead of Sidekiq::Worker in all workers.data_consistency explicitly on every worker (RuboCop enforces this).feature_category on every Sidekiq worker.idempotent! unless there is a documented reason they cannot be.deduplicate :until_executing (default) or :until_executed alongside idempotent!; pass including_scheduled: true if future-scheduled jobs should also be deduplicated.urgency :high and worker_has_external_dependencies!.urgency :high and worker_resource_boundary :memory.::Geo::SkipSecondary to workers that attempt database writes if they can be enqueued on Geo secondary sites.Sidekiq::Client.via(pool) using Gitlab::SidekiqSharding::Router.get_shard_instance.Gitlab::SidekiqSharding::Validator.allow_unrouted_sidekiq_calls only for components that do not affect GitLab.com; add a comment explaining why it is safe.find_by_id (not find) for database lookups in perform, and return early if the record is nil, to guard against state changes between scheduling and execution.Gitlab::SidekiqMiddleware::RetryError when retrying without tracking in Sentry.sidekiq_retries_exhausted, not inline in perform.concurrency_limit for all workers to prevent system overload.Feature.current_request.nil or 0 to disable the limit; use a negative number to pause execution.max_concurrency_limit_percentage to override the default shard capacity percentage when the GitLab.com default is not appropriate for the worker.urgency :high only for jobs where median execution time is under 1 second and 99th percentile is under 10 seconds.@gitlab-com/gl-infra/data-access/durability on the MR when changing a queue's urgency if the expected shard load increase exceeds 5%.data_consistency :sticky for jobs that must execute quickly.data_consistency :delayed for jobs where delayed execution is acceptable (cache expiration, webhooks); DO NOT use :delayed for cron jobs where retry is disabled.data_consistency :always only for jobs with documented edge cases around primary stickiness; it is strongly discouraged.overrides: keyword with data_consistency when a worker's database usage is skewed toward a specific decomposed database (e.g., ci).feature_flag: property with data_consistency to safely toggle load balancing for a specific job; DO NOT use actor-based feature gates (project, group, user) — use percentage-of-time rollout only.param_containing_valid_native_json_types matcher for code that generates worker parameters.perform parameters: highest-level resource IDs → user IDs → lower-level resource IDs → optional config hash.params = {}) rather than as positional arguments.perform with a default value first (Release M), update call sites in Release M+1, remove the default in Release M+2.nil and a comment before removing them across two releases.perform a no-op in Release M, add a migration using sidekiq_remove_jobs in Release M+1, delete the class in Release M+2.sidekiq_queue_migrate in a post-deployment migration (not a standard migration) when renaming queues.perform in Release M, enable scheduling of the new worker in Release M+1, remove the old class in Release M+2.bin/rake gitlab:sidekiq:all_queues_yml:generate and bin/rake gitlab:sidekiq:sidekiq_queues_yml:generate after adding a new worker.sidekiq_options queue: unless there is a specific documented reason.queue_namespace :cronjob (via CronjobQueue) for cron-scheduled workers.version on the worker class when changing perform arguments, and ensure the worker handles all prior argument formats.loggable_arguments to explicitly allowlist non-numeric arguments that are safe to log; DO NOT rely on default logging for string arguments containing sensitive data.with_context or use bulk_perform_async_with_contexts / bulk_perform_in_with_contexts when scheduling from cron workers to propagate correct context..with_route) before passing them to context helpers.defer_on_database_health_signal with gitlab_schema, delay_by, and tables parameters to opt in to automatic deferral based on database health indicators.perform_work, remaining_work_count, and max_running_jobs when using LimitedCapacity::Worker.LimitedCapacity::Worker subclasses via perform_with_capacity, not perform_async; always pass the same *args on every invocation.perform_work; DO NOT let the job raise, as retries are disabled and failures reduce running capacity until the cron worker refills slots.perform_with_capacity periodically when the worker consumes a workload stored outside Sidekiq (for example, in PostgreSQL).ttl: on deduplicate only for jobs that can tolerate some duplication; the default is 10 minutes, during which duplicate jobs are suppressed even if the first job never ran.spec/workers using RSpec.it_behaves_like 'an idempotent worker' shared example without stubbing service side-effects.For the full picture, see: