Ultimate Cron
Advanced cron management module that runs cron jobs individually in parallel using configurable rules, pool management and load balancing.
ultimate_cron
Overview
Ultimate Cron is a comprehensive cron management solution for Drupal that replaces the core cron logic with a more powerful and flexible system. While it maintains compatibility with standard Drupal cron invocation methods (drush cron, crontab, etc.), it provides granular control over individual cron jobs.
The module automatically discovers all hook_cron() implementations from enabled modules and creates individual cron job entities for each one. Each job can be configured independently with its own schedule, execution parameters, and logging settings through a plugin-based architecture.
Key architectural components include Schedulers (determining when jobs run), Launchers (controlling how jobs execute), and Loggers (recording execution history). The module supports extended crontab syntax with special operators like skew (@) for load distribution across multiple jobs.
Ultimate Cron also provides optional queue worker integration, exposing each queue worker as a separate configurable cron job. This allows fine-grained control over queue processing frequency and behavior.
Features
- Automatic discovery of all hook_cron() implementations and conversion to individual manageable cron jobs
- Plugin-based architecture with swappable Schedulers, Launchers, and Loggers
- Extended crontab syntax with skew (@) operator for automatic load balancing across jobs
- Database and Cache-based logging with configurable retention policies
- Lock management preventing concurrent execution of the same job
- Manual job execution, enabling/disabling, and unlocking from both UI and Drush
- Detailed execution logs with severity levels, duration tracking, and user attribution
- Optional queue worker integration exposing queue workers as individual cron jobs
- Progress tracking for long-running jobs
- Behind-schedule detection and status reporting
- Draggable job ordering for execution priority control
Use Cases
Running resource-intensive jobs at off-peak hours
Use the Crontab scheduler to schedule heavy jobs like search indexing (search_cron) or sitemap generation (simple_sitemap_cron) to run during low-traffic periods. Example rule: '0 3 * * *' runs at 3 AM daily. The skew operator (@) can distribute multiple heavy jobs: '0+@ 3 * * *' ensures each job runs at a slightly different minute.
High-frequency queue processing
Enable queue worker integration to expose queue workers as individual cron jobs. Configure a queue like 'entity_update' to run every minute while keeping less critical queues at longer intervals. This prevents queue backlogs without overwhelming the server.
Debugging cron issues
Use 'drush cron:list --behind' to identify jobs that haven't run on schedule. Check individual job logs with 'drush cron:logs job_name' to see error messages. The database logger retains detailed execution history including severity levels and stack traces for debugging.
Load balancing across multiple servers
Use the skew (@) operator in scheduling rules to automatically distribute job execution across time. When multiple web servers run cron, the serial launcher's lock mechanism ensures each job only runs on one server at a time, preventing duplicate execution.
Preventing runaway jobs
Configure lock_timeout in the launcher settings to automatically release locks after a specified time. If a job hangs or crashes without unlocking, the lock will expire and allow the job to run again. Administrators can also manually unlock stuck jobs via UI or 'drush cron:unlock'.
Monitoring cron health
The module integrates with Drupal's status report, showing warnings when jobs are behind schedule. This can be integrated with monitoring systems to alert administrators of cron failures.
Custom job creation
Create custom cron jobs by adding configuration entities to your module's config/install or config/optional directory. Specify the callback using various formats: function name, module#hook format for hook implementations, class::method for static methods, or service.name:method for service methods.
Tips
- Use the skew (@) operator in scheduling rules to automatically distribute job execution times and prevent all jobs from running at the same moment
- Disable core's Automated Cron module for production sites and use a proper external cron trigger via crontab or hosting provider
- The 'drush cron:run job_name --force' command is useful for testing jobs without waiting for their schedule
- Job weights (set by dragging in the UI) control execution order - lower weights run first
- The Cache logger is ideal for high-frequency jobs where you only need to see the most recent execution
- Configure generous lock_timeout values for jobs that may take varying amounts of time to prevent premature lock release
- Monitor the status report page for 'jobs behind schedule' warnings as an early indicator of cron issues
Technical Details
Admin Pages 6
/admin/config/system/cron/jobs
Main administrative interface displaying all discovered cron jobs in a draggable table. Shows job title, module, schedule, last run time, duration, and execution status. Provides operations for editing, running, unlocking, enabling/disabling, and viewing logs for each job. Jobs can be reordered by dragging to control execution priority.
/admin/config/system/cron/settings
Queue settings page for configuring how Ultimate Cron handles queue worker integration. When enabled, queue workers are exposed as individual cron jobs with configurable scheduling.
/admin/config/system/cron/jobs/manage/{job_id}
Configuration form for editing an individual cron job. Allows customization of the job's scheduler, launcher, and logger plugins with their respective settings.
/admin/config/system/cron/jobs/logs/{job_id}
Displays execution history for a specific cron job. Shows severity indicator, start time, end time, messages, and duration for each execution.
/admin/config/system/cron/jobs/{job_id}/run
Immediately executes the specified cron job regardless of schedule (respects locks).
/admin/config/system/cron/jobs/{job_id}/unlock
Forcibly unlocks a stuck cron job, allowing it to be run again. Use with caution as the job may still be running.
Permissions 3
Hooks 6
hook_pre_schedule
Invoked just before a job is asked for its schedule. Allows modules to modify scheduling behavior.
hook_post_schedule
Invoked after a job has been asked for its schedule.
hook_pre_launch
Invoked just before a job is launched. Useful for pre-execution setup.
hook_post_launch
Invoked after a job has been launched. May be called before or after hook_post_run depending on launcher implementation.
hook_pre_run
Invoked just before a job callback is executed.
hook_post_run
Invoked after a job callback has completed execution.
Drush Commands 6
drush cron:list
Lists all cron jobs with their status, schedule, and last run information
drush cron:run <name>
Runs a specific cron job immediately
drush cron:logs <name>
Shows execution logs for a specific cron job
drush cron:enable <name>
Enables a cron job
drush cron:disable <name>
Disables a cron job
drush cron:unlock <name>
Unlocks a stuck cron job
Troubleshooting 6
Ensure external cron is configured to trigger Drupal cron frequently enough (at least as often as your most frequent job schedule). Disable core's Automated Cron module as it only runs on page requests. Check 'drush cron:list --behind' for jobs behind schedule.
The previous execution may have crashed without releasing the lock. Use 'drush cron:unlock job_name' or click Unlock in the UI. Investigate the cause by checking recent logs for errors.
This shouldn't happen with Ultimate Cron's lock mechanism. Check if multiple cron triggers are firing simultaneously or if lock_timeout is too short. Increase lock_timeout in launcher settings.
Queue worker integration is disabled by default. Enable it at /admin/config/system/cron/settings by checking 'Override cron queue processing'. Then run 'drush cr' or use the 'Discover jobs' button.
Adjust the database logger's cleanup settings. Change method to 'Retain only a specific amount' and reduce the retain count, or use 'Remove logs older than specified age' with a shorter expire time.
The callback function no longer exists, likely because the providing module was uninstalled or the function was removed. Delete the orphaned job entity or reinstall the module.
Security Notes 4
- The 'administer ultimate cron' permission is restricted and should only be granted to trusted administrators as it allows full control over cron job execution
- Manual job execution via UI or Drush is logged with user attribution for audit purposes
- Jobs always run as anonymous user to ensure consistent permissions regardless of who triggers cron
- Lock IDs are generated using uniqid() for uniqueness but should not be considered cryptographically secure