Sidekiq-Cron Upgrade Guide (1.10.1 → 2.3.1)
This guide documents the upgrade of sidekiq-cron from version 1.10.1 to 2.3.1 in the Reports application.
Summary
On October 29, 2024, we upgraded sidekiq-cron from version 1.10.1 to 2.3.1. This major version upgrade brings several improvements and requires awareness of breaking changes, though our application code did not require modifications.
What Changed
Gem Versions Updated
| Gem | Old Version | New Version |
|---|---|---|
| sidekiq-cron | 1.10.1 | 2.3.1 |
| sidekiq | 7.1.4 | 7.3.9 |
| fugit | 1.11.1 | 1.12.1 |
| et-orbi | 1.2.11 | 1.4.0 |
| globalid | 1.2.1 | 1.3.0 |
| redis-client | 0.17.0 | 0.26.1 |
| connection_pool | 2.4.1 | 2.5.4 |
| minitest | 5.25.5 | 5.26.0 |
New Dependency
- cronex (0.15.0) - A new dependency added in sidekiq-cron 2.x for enhanced cron expression parsing
Breaking Changes
1. Minimum Sidekiq Version
Requirement: Sidekiq 6.5.0 or higher
Our application was already using Sidekiq 7.1.4, so this requirement was already met.
2. Minimum Redis Version
Requirement: Redis 4.0 or higher
Ensure your Redis server is at least version 4.0.
3. New Configuration Options
Sidekiq-cron 2.x introduces new configuration options that can be used in job definitions:
Retry Configuration
You can now specify retry behavior directly in your cron job definition:
Sidekiq::Cron::Job.new(
name: 'my_job',
cron: '0 * * * *',
class: 'MyJob',
retry: 5 # or false to disable retries
)
Namespace Support
Jobs can now be organized into namespaces:
Sidekiq::Cron::Job.new(
name: 'my_job',
cron: '0 * * * *',
class: 'MyJob',
namespace: 'default' # organize jobs by namespace
)
4. Enhanced Cron Expression Support
Sidekiq-cron 2.x uses fugit 1.11.1+ which provides improved natural language support for cron schedules. Our existing cron expressions continue to work without modification.
Impact on Our Application
Configuration Files
- config/schedule.yml: No changes required. All existing cron job definitions work without modification.
- config/initializers/sidekiq.rb: Schedule loading had to be reworked, see Schedule loading per environment.
Schedule loading per environment
In 1.x, cron_schedule_file in config/sidekiq.yml was enough to keep the gem from autoloading the
schedule, which let the initializer load config/schedule.yml explicitly in production only.
In 2.x that key is no longer read from sidekiq.yml. The gem reads it from its own configuration
object and loads the schedule from an :startup hook on the Sidekiq server, so the entry became dead
configuration and the production schedule was registered on every environment running a Sidekiq
server — staging and review apps included.
The gem is now the only thing that loads the schedule, gated by environment:
# config/initializers/sidekiq.rb
Sidekiq::Cron.configure { |config| config.enabled = Reports.production? }
Because cron jobs are persisted in Redis, disabling the load does not remove entries registered
while the schedule was still loading everywhere: those keep firing until they are deleted. Clear
them once per affected environment, from the Sidekiq Cron web UI at /jobs/cron or from a console:
Sidekiq::Cron::Job.all('*').select { |job| job.source == 'schedule' }.each(&:destroy)
Filter on source rather than using Sidekiq::Cron::Job.destroy_all!: jobs registered dynamically
by EmailCampaign are dynamic and must survive.
Application Code
- app/models/email_campaign.rb: No changes required. The
_scheduleand_unschedulemethods continue to work as expected.
Tests
All existing tests pass without modification:
spec/models/email_campaign_spec.rb(37 examples, 0 failures)spec/controllers/email_campaigns_controller_spec.rb
Verification Steps
To verify the upgrade was successful:
-
Check gem version:
bundle show sidekiq-cron
# Should output: .../sidekiq-cron-2.3.1 -
Run tests:
bundle exec rspec spec/models/email_campaign_spec.rb -
Verify scheduled jobs load correctly:
bundle exec rails console
> Sidekiq::Cron::Job.all -
Check Sidekiq Web UI:
- Navigate to
/sidekiq/cronin your application - Verify all scheduled jobs are listed and active
- Navigate to
Migration Checklist
- Verify Sidekiq version >= 6.5.0 (We had 7.1.4)
- Update Gemfile to specify
sidekiq-cron ~> 2.3 - Run
bundle update sidekiq-cron - Review cron job definitions (No changes needed)
- Run test suite (All tests pass)
- Verify jobs load in console (Confirmed)
- Document breaking changes (This guide)
Recommendations for Future Jobs
When creating new cron jobs, consider using the new features:
-
Explicit Retry Configuration: Set the
retryoption to control retry behavior:job = Sidekiq::Cron::Job.new(
name: 'my_job',
cron: '0 * * * *',
class: 'MyJob',
active_job: true,
retry: 3 # Retry up to 3 times on failure
) -
Namespaces for Organization: Use namespaces to group related jobs:
job = Sidekiq::Cron::Job.new(
name: 'import_job',
cron: '0 * * * *',
class: 'ImportJob',
active_job: true,
namespace: 'imports' # Group import-related jobs
)
Resources
Support
If you encounter issues related to scheduled jobs after this upgrade, check:
- Redis server logs for connection issues
- Sidekiq logs for job execution errors
- Sidekiq Web UI (
/sidekiq/cron) for job status - Rails logs for application-specific errors
Rollback Procedure
If you need to rollback to the previous version:
-
Update Gemfile to use the old version:
gem 'sidekiq-cron', '~> 1.10' -
Run bundle update:
bundle update sidekiq-cron -
Restart the application and Sidekiq workers
Note: Rolling back is not recommended as version 2.x is actively maintained and includes security updates.