NeuroAgent

Setting up cron every 10 seconds in CentOS 9 Stream

Solution for running cron tasks every 10 seconds in CentOS 9 Stream. Alternative methods with systemd timers and comparison with cron.

Question

How do I configure a cron task to run every 10 seconds in CentOS 9 Stream? On CentOS 7, I used a method with multiple entries in crontab using the SLEEP command, but in CentOS 9 Stream this approach doesn’t work - cron doesn’t execute and doesn’t write logs. Examples of current crontab entries:

* * * * * sleep 0 ; /usr/bin/php -f /home/bitrix/ext_www/site.com/bitrix/php_interface/cron_events.php >> /home/bitrix/.bx_temp/site.com/log/cron_events.log 2>&1
* * * * * sleep 10 ; /usr/bin/php -f /home/bitrix/ext_www/site.com/bitrix/php_interface/cron_events.php >> /home/bitrix/.bx_temp/site.com/log/cron_events.log 2>&1
* * * * * sleep 20 ; /usr/bin/php -f /home/bitrix/ext_www/site.com/bitrix/php_interface/cron_events.php >> /home/bitrix/.bx_temp/site.com/log/cron_events.log 2>&1
* * * * * sleep 30 ; /usr/bin/php -f /home/bitrix/ext_www/site.com/bitrix/php_interface/cron_events.php >> /home/bitrix/.bx_temp/site.com/log/cron_events.log 2>&1
* * * * * sleep 40 ; /usr/bin/php -f /home/bitrix/ext_www/site.com/bitrix/php_interface/cron_events.php >> /home/bitrix/.bx_temp/site.com/log/cron_events.log 2>&1
* * * * * sleep 50 ; /usr/bin/php -f /home/bitrix/ext_www/site.com/bitrix/php_interface/cron_events.php >> /home/bitrix/.bx_temp/site.com/log/cron_events.log 2>&1

What alternative methods exist for running tasks every 10 seconds in CentOS 9 Stream, and why did the standard approach with SLEEP stop working?

NeuroAgent

The SLEEP Approach in CentOS 9 Stream: Why It No Longer Works and Systemd Timer Solutions

In CentOS 9 Stream, the standard approach using multiple entries in crontab with the SLEEP command has stopped working due to changes in the service management system and cron behavior. The primary alternative is systemd timers, which provide a more modern and reliable mechanism for executing tasks with second-level precision.

Table of Contents

Problem with SLEEP in CentOS 9 Stream

The standard approach that worked in CentOS 7 with multiple crontab entries and the SLEEP command no longer functions correctly in CentOS 9 Stream. As research indicates, cron was originally designed to run tasks every minute, and attempts to bypass this limitation with SLEEP can lead to unpredictable behavior[source].

In your example with six entries, each using a sleep command with delays of 0, 10, 20, 30, 40, and 50 seconds, the system in CentOS 9 Stream either doesn’t execute the tasks at all or doesn’t write logs, indicating changes in the cron daemon’s operation or related system components.

Why the Old Method Doesn’t Work

There are several reasons why the SLEEP approach no longer works in CentOS 9 Stream:

  1. Systemd Changes: CentOS 9 Stream uses a newer version of systemd that manages services and timers differently compared to CentOS 7[source].

  2. Cron Limitations: As noted in research, cron is not designed to run tasks more frequently than once per minute, and all attempts to bypass this limitation are considered “hacks”[source].

  3. Synchronization Issues: Research shows that sleep commands in cron can have synchronization problems, especially when creating crontab files at specific times[source].

  4. Changes in Cron Behavior: CentOS 9 Stream may include changes in how cron handles parallel tasks or delayed tasks.

Solution with Systemd Timers

The most reliable and modern solution for running tasks every 10 seconds in CentOS 9 Stream is to use systemd timers. Systemd timers offer several advantages over cron:

  • Second-level Precision: Unlike cron, which is limited to minute-level precision, systemd timers allow specifying execution with second-level accuracy[source]
  • Reliability: Systemd timers guarantee task execution even if the system was powered off at the scheduled time[source]
  • Dependency Management: Ability to specify dependencies between services and timers
  • Better Parallel Task Management: If a task takes longer than the interval between executions, systemd will delay the next run, unlike cron which might launch multiple instances of the task simultaneously[source]

Creating a Systemd Service and Timer

To run your PHP script every 10 seconds, we’ll create two files: a service and a timer.

1. Create the service file /etc/systemd/system/cron-events.service:

ini
[Unit]
Description=Run cron_events script every 10 seconds
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/php -f /home/bitrix/ext_www/site.com/bitrix/php_interface/cron_events.php
User=bitrix
Group=bitrix
StandardOutput=file:/home/bitrix/.bx_temp/site.com/log/cron_events.log
StandardError=file:/home/bitrix/.bx_temp/site.com/log/cron_events.log

2. Create the timer file /etc/systemd/system/cron-events.timer:

ini
[Unit]
Description=Run cron_events script every 10 seconds
Requires=cron-events.service

[Timer]
Unit=cron-events.service
OnUnitInactiveSec=10s
AccuracySec=1s

[Install]
WantedBy=timers.target

3. Enable and start the timer:

bash
systemctl daemon-reload
systemctl enable cron-events.timer
systemctl start cron-events.timer

4. Check the timer status:

bash
systemctl list-timers --all

Alternative Methods for Executing Tasks Every 10 Seconds

Besides systemd timers, there are other alternative methods:

1. Using a while loop in a separate script

Create a script that runs as a systemd service and contains an infinite loop with a delay:

bash
#!/bin/bash
while true; do
    /usr/bin/php -f /home/bitrix/ext_www/site.com/bitrix/php_interface/cron_events.php
    sleep 10
done

2. Using anacron with modified configuration

Although anacron is typically designed for periodic tasks with day intervals, it can be configured for more frequent runs, but this is not optimal for 10-second intervals.

3. Using external tools

Consider using specialized tools for monitoring and task execution, such as:

  • Supervisor: For process management
  • Runit: For service management
  • Monit: For monitoring and automatic process startup

Configuring and Managing Systemd Timers

For more detailed systemd timer configuration, you can use the following parameters:

ini
[Timer]
# Run the task every 10 seconds
OnUnitInactiveSec=10s

# Execution accuracy (1 second)
AccuracySec=1s

# Random delay to distribute load
RandomizedDelaySec=1s

# Maximum wait time before execution
Persistent=true

# Run on system boot
OnBootSec=10s

For viewing systemd timer logs, use:

bash
journalctl -u cron-events.service -f

For managing timers:

bash
systemctl stop cron-events.timer    # Stop the timer
systemctl start cron-events.timer   # Start the timer
systemctl restart cron-events.timer # Restart the timer
systemctl status cron-events.timer  # Check status

Comparison of Cron and Systemd Timers

Criterion Cron Systemd Timers
Precision Minute-level Second-level
Reliability Misses tasks when system is off Executes missed tasks
Dependency Management Limited Full
Parallel Tasks May launch multiple instances Delays next execution
Configuration Simple but limited More complex but powerful
Logging Standard cron logs Integration with journalctl

Conclusion

  1. Main Problem: The approach using multiple crontab entries with the SLEEP command no longer works in CentOS 9 Stream due to systemd changes and cron behavior modifications.

  2. Optimal Solution: Using systemd timers provides a modern, reliable, and precise mechanism for executing tasks at 10-second intervals.

  3. Systemd Advantages: Second-level precision, reliable execution of missed tasks, better parallel task management, and integration with the modern service management system.

  4. Recommendation: For CentOS 9 Stream, it’s recommended to fully transition to systemd timers for high-frequency tasks, as this is a more reliable and modern solution that will be better supported in future system versions.

  5. Next Steps: When transitioning to systemd timers, it’s also advisable to reconsider the task architecture, possibly combining multiple high-frequency tasks into a single, more efficient service.