Solving the 15-Second Cronjob Challenge: How to Execute CLI Scripts at Sub-Minute Intervals


2 views

The standard Unix cron utility operates with a minimum granularity of 1 minute, which stems from its original design for system maintenance tasks. When we need to run tasks more frequently - especially in modern application scenarios like real-time monitoring or queue processing - we hit this fundamental limitation.

Here are three practical approaches to achieve 15-second execution:

Method 1: Sleep-Based Loop in Your Script

The simplest approach modifies your PHP script to handle the timing internally:


#!/usr/bin/env php
<?php
while (true) {
    // Your task logic here
    execute_your_function();
    
    // Wait for 15 seconds
    sleep(15);
}

Then set up a standard cron job to ensure the script keeps running:


* * * * * /usr/bin/flock -n /tmp/your_script.lock /usr/bin/php /path/to/your_script.php

Method 2: Multiple Cron Entries per Minute

For more precise timing without modifying your script:


* * * * * /usr/bin/php /path/to/script.php
* * * * * (sleep 15 && /usr/bin/php /path/to/script.php)
* * * * * (sleep 30 && /usr/bin/php /path/to/script.php)
* * * * * (sleep 45 && /usr/bin/php /path/to/script.php)

Method 3: Systemd Timer Units

For Linux systems using systemd, create a more modern solution:


# /etc/systemd/system/your-script.service
[Unit]
Description=15-second PHP job

[Service]
ExecStart=/usr/bin/php /path/to/your_script.php

# /etc/systemd/system/your-script.timer
[Unit]
Description=Run PHP script every 15 seconds

[Timer]
OnBootSec=15
OnUnitActiveSec=15
AccuracySec=1ms

[Install]
WantedBy=timers.target

Consider these factors when selecting an approach:
- System Impact: Sleep loops consume resources continuously
- Precision: Systemd timers offer microsecond accuracy
- Maintainability: Multiple cron entries are simple but repetitive
- Logging: Built-in logging differs between methods

For production systems, implement:
- Proper lock mechanisms to prevent overlapping executions
- Health monitoring to restart failed processes
- Log rotation for frequent executions
- Resource limits to prevent system overload


Traditional cron jobs operate with a minimum granularity of 1 minute (via the */1 syntax in the time fields). This becomes problematic when you need sub-minute execution intervals for tasks like:

  • Real-time monitoring systems
  • High-frequency data processing
  • Queue workers with rapid polling
  • Micro-batch operations

Method 1: Sleep-Based Looping Within a Minute

Create a wrapper script that executes your PHP command in a loop:


#!/bin/bash
for i in {1..4}
do
  /usr/bin/php /path/to/your/script.php
  sleep 15
done

Then set your cron to run this wrapper every minute:


* * * * * /path/to/wrapper.sh

Method 2: Systemd Timer Alternative

For modern Linux systems using systemd:


# /etc/systemd/system/15sec-job.service
[Unit]
Description=15 Second PHP Job

[Service]
ExecStart=/usr/bin/php /path/to/your/script.php

# /etc/systemd/system/15sec-job.timer
[Unit]
Description=Run PHP script every 15 seconds

[Timer]
OnBootSec=15
OnUnitActiveSec=15
AccuracySec=1ms

[Install]
WantedBy=timers.target

Enable with:
systemctl enable --now 15sec-job.timer

When implementing sub-minute cron alternatives:

  • Monitor script execution time to prevent overlap
  • Implement proper locking (flock) for critical operations
  • Consider using a dedicated job queue for high-frequency tasks
  • Log script execution times to detect drift

For production environments requiring reliability:


[program:php_15sec]
command=/usr/bin/php /path/to/script.php
autostart=true
autorestart=true
startretries=3
startsecs=0
process_name=%(program_name)s_%(process_num)02d
numprocs=1

Configure with:
supervisorctl reload

Always verify your implementation:


# For cron-based solutions:
tail -f /var/log/syslog | grep CRON

# For systemd timers:
journalctl -u 15sec-job.timer -f

# For supervisor:
supervisorctl tail php_15sec stderr