MailWizz Cron Job Reference: Complete 2026 Operator Guide

← Downloads

MailWizz Cron Job Reference: Complete 2026 Operator Guide

July 8, 2026·12 min read·Marcus Webb

Why this reference exists

MailWizz cron jobs are the single most common source of MailWizz operational problems in production. Operators install the cron jobs once during setup, walk away, and discover six months later that campaigns have not been sending because cron silently stopped running. The pattern is universal across operators: the cron jobs work fine until they do not, and when they break the diagnostic path is non-obvious because MailWizz surfaces only vague warning messages about commands not running in the last X hours.

This reference exists because the MailWizz backend shows the cron commands during installation but never again, and because the official documentation lists frequencies but rarely explains the failure modes operators actually encounter. The structure: the complete cron set with frequencies that match production needs, each command explained with what it actually does and why the frequency matters, the PHP binary path issue that breaks cron on hosts where path autodetection fails, the console.php permissions trap that breaks cron after MailWizz upgrades, installation patterns for plain cron and control panels, the warning messages MailWizz produces and what they actually mean, verbose debugging mode that operators consistently underutilize, and the common failure modes that produce vague symptoms.

Verified against MailWizz 2.5+ as of mid-2026. The cron command set has been stable across recent versions though specific frequencies may differ slightly between releases.

The complete cron job set

The full production cron set for MailWizz in 2026:

CommandFrequencyPurpose
send-campaigns* * * * * (every minute)Processes pending campaign sends
send-transactional-emails*/2 * * * * (every 2 min)Handles transactional queue
bounce-handler*/10 * * * * (every 10 min)Parses bounce mailboxes
feedback-loop-handler*/20 * * * * (every 20 min)Parses FBL mailboxes
process-delivery-and-bounce-log*/3 * * * * (every 3 min)Processes delivery and bounce logs
process-email-box-monitors*/10 * * * * (every 10 min)Handles inbox monitoring
queue* * * * * (every minute)Queue processor (newer MailWizz)
hourly0 * * * * (top of hour)General hourly tasks
daily0 0 * * * (midnight)General daily tasks and cleanup
daily-process-subscribers0 0 * * * (midnight)Subscriber maintenance
list-import folder*/5 * * * * (every 5 min, optional)Folder-based CSV imports

All commands follow the pattern:

FREQUENCY PHP_BINARY -q PATH_TO_MAILWIZZ/apps/console/console.php COMMAND >/dev/null 2>&1

A complete production crontab for a typical Ubuntu installation:

# MailWizz cron jobs - production
* * * * * /usr/bin/php -q /var/www/mailwizz/apps/console/console.php send-campaigns >/dev/null 2>&1
* * * * * /usr/bin/php -q /var/www/mailwizz/apps/console/console.php queue >/dev/null 2>&1
*/2 * * * * /usr/bin/php -q /var/www/mailwizz/apps/console/console.php send-transactional-emails >/dev/null 2>&1
*/3 * * * * /usr/bin/php -q /var/www/mailwizz/apps/console/console.php process-delivery-and-bounce-log >/dev/null 2>&1
*/10 * * * * /usr/bin/php -q /var/www/mailwizz/apps/console/console.php bounce-handler >/dev/null 2>&1
*/10 * * * * /usr/bin/php -q /var/www/mailwizz/apps/console/console.php process-email-box-monitors >/dev/null 2>&1
*/20 * * * * /usr/bin/php -q /var/www/mailwizz/apps/console/console.php feedback-loop-handler >/dev/null 2>&1
0 * * * * /usr/bin/php -q /var/www/mailwizz/apps/console/console.php hourly >/dev/null 2>&1
0 0 * * * /usr/bin/php -q /var/www/mailwizz/apps/console/console.php daily >/dev/null 2>&1
0 0 * * * /usr/bin/php -q /var/www/mailwizz/apps/console/console.php daily-process-subscribers >/dev/null 2>&1

Each command explained

send-campaigns is the most important cron. It processes pending regular campaigns by querying for active campaigns past their scheduled start time, selecting subscribers per campaign batching rules, rendering content with merge tag substitution, handing messages to configured delivery servers. Runs every minute and is expected to complete in seconds or low minutes depending on volume. If send-campaigns stops running, campaigns sit pending indefinitely and the entire MailWizz operation halts visibly.

send-transactional-emails processes the transactional email queue used by the API and by features that send individual transactional messages (welcome emails, password resets, custom notifications). Runs every 2 minutes which is fast enough for most transactional needs while not duplicating effort with send-campaigns.

bounce-handler connects to bounce processing mailboxes (configured under Servers then Bounce Servers), retrieves new messages, parses them to identify hard versus soft bounces, updates subscriber status accordingly. Runs every 10 minutes which matches typical bounce-back delays from receiving MTAs. Faster frequency wastes IMAP connections; slower frequency delays bounce-driven suppression.

feedback-loop-handler connects to FBL processing mailboxes (configured under Servers then Feedback Loop Servers), parses ARF (Abuse Reporting Format) messages from ISP complaint feedback loops, updates subscriber status to suppress complainers. Runs every 20 minutes because FBL volume is typically low and complaints are not extremely time-sensitive.

process-delivery-and-bounce-log handles asynchronous processing of delivery and bounce log records that accumulate from send-campaigns. The separation allows send-campaigns to complete quickly without blocking on log processing. Runs every 3 minutes to keep up with typical sending rates.

process-email-box-monitors handles MailWizz email box monitoring features where MailWizz watches configured mailboxes for specific patterns and triggers automation. Less commonly used but required if email box monitors are configured.

queue is an additional queue processor introduced in newer MailWizz versions that handles miscellaneous queued operations. Runs every minute alongside send-campaigns to keep queue depth manageable.

hourly runs once per hour for tasks that need hourly cadence: cache cleanup, scheduled report generation, hourly subscriber operations.

daily runs once per day at midnight for cleanup tasks: log rotation, expired record cleanup, daily report generation, suppression list deduplication.

daily-process-subscribers runs once per day for subscriber-specific maintenance: updating engagement scores, processing inactive subscriber rules, applying scheduled subscriber operations.

list-import folder is optional. If configured, runs every 5 minutes to check a designated folder for CSV files and imports any new files into the configured subscriber list. Only needed if folder-based bulk import workflow is used; the standard upload-based import does not require this cron.

PHP path and permissions

Two issues consistently break MailWizz cron in production: wrong PHP binary path and incorrect console.php permissions.

The PHP binary path issue: MailWizz tries to detect the PHP binary path during installation by calling the PHP exec() function, but exec() is disabled on many shared hosts for security reasons. When detection fails, MailWizz falls back to /usr/bin/php-cli which does not exist on most modern systems where PHP is installed at /usr/bin/php or version-specific paths like /usr/bin/php8.1. Operators copy the cron commands from MailWizz installation screen and the wrong path silently fails.

The fix: identify your actual PHP CLI binary path with which php or which php-cli, then update all cron jobs to use the correct path. Common paths by environment:

EnvironmentCommon PHP path
Ubuntu 22.04 with default PHP/usr/bin/php
Ubuntu with PHP 8.1 from ondrej PPA/usr/bin/php8.1
Debian 12 default/usr/bin/php
CentOS/RHEL with Remi/usr/bin/php
cPanel with PHP Selector/opt/cpanel/ea-php81/root/usr/bin/php
Plesk PHP versions/opt/plesk/php/8.1/bin/php
CyberPanel PHP versions/usr/local/lsws/lsphp81/bin/php

The console.php permissions issue: after MailWizz upgrades, the apps/console/console.php file occasionally gets reset to 000 permissions (no execute, no read, no write) which makes it impossible for cron to execute. The fix: chmod 0644 /var/www/mailwizz/apps/console/console.php and verify with ls -l. Add a periodic permission check to your monitoring to catch this if it recurs.

The path detection trap

Operators frequently copy the cron commands from MailWizz installation screen exactly as shown without verifying that the PHP binary path actually exists. The path /usr/bin/php-cli is correct on some systems (CentOS/RHEL with EOL versions) but wrong on most modern Ubuntu/Debian systems where it should be /usr/bin/php. The cron jobs run, fail silently because the binary does not exist, cron logs the failure but operators do not check cron logs, and weeks later the MailWizz backend shows "send-campaigns command did not run in last 12 hours" warning. Always verify your actual PHP path with which php before installing cron jobs.

Installing cron jobs correctly

The standard installation pattern for production:

  1. Identify the correct user to own cron jobs: typically the web server user (www-data on Debian/Ubuntu, apache on RHEL/CentOS, or the specific user that owns MailWizz files in shared hosting)
  2. Identify the correct PHP binary path: which php as the cron user
  3. Open the user's crontab: sudo -u www-data crontab -e (or for control panels, use their cron management UI)
  4. Add all cron lines from the production set above with paths adapted to your installation
  5. Save and exit the crontab editor
  6. Verify cron jobs registered: sudo -u www-data crontab -l
  7. Wait 2-3 minutes and check MailWizz console log: tail -50 /var/www/mailwizz/apps/common/runtime/console.log
  8. Look for recent timestamps showing send-campaigns and other commands executing successfully
  9. Check MailWizz backend under Misc then Cron Jobs to verify no warnings about commands not running

For shared hosting or environments where the web server user cannot edit crontab, the cron jobs may need to be installed in root crontab with explicit user switching:

* * * * * www-data /usr/bin/php -q /var/www/mailwizz/apps/console/console.php send-campaigns >/dev/null 2>&1

Note the user (www-data) inserted after the schedule when using /etc/crontab or /etc/cron.d files (which require explicit user) but NOT in user crontabs (which implicitly run as the user). Mixing these patterns produces "permission denied" errors.

The 'command did not run' warning

MailWizz backend periodically displays warning messages like:

  • "The send-campaigns command did not run in the last 12 hours"
  • "The queue command did not run in the last 12 hours"
  • "The bounce-handler command did not run in the last 1 day"
  • "The daily command did not run in the last 2 days"

These warnings mean MailWizz has not seen successful execution records for the named command in the expected timeframe. The threshold varies by command frequency: high-frequency commands (send-campaigns) trigger warnings after 12 hours of silence; medium-frequency commands trigger after 1 day; daily commands trigger after 2 days.

Diagnostic procedure when a warning appears:

  1. Check whether cron daemon is running: systemctl status cron (should show active/running)
  2. Check whether cron is finding the jobs: sudo -u www-data crontab -l
  3. Check cron logs for execution attempts: grep CRON /var/log/syslog | tail -20 (or /var/log/cron on RHEL)
  4. Check console log for MailWizz output: tail -100 /var/www/mailwizz/apps/common/runtime/console.log
  5. Run the failing command manually as the cron user to see direct error: sudo -u www-data /usr/bin/php -q /var/www/mailwizz/apps/console/console.php send-campaigns
  6. If manual execution succeeds but cron does not, the issue is in cron configuration (user, PATH, environment variables)
  7. If manual execution fails, the error message identifies the underlying problem

Debugging with verbose mode

The send-campaigns command supports a verbose mode that exposes every operation it performs. This is the single most valuable debugging tool MailWizz provides and operators consistently underutilize it.

To debug a stuck campaign, first temporarily disable the send-campaigns cron to prevent concurrent execution, then run:

/usr/bin/php -q /var/www/mailwizz/apps/console/console.php send-campaigns --verbose=1

MailWizz will output timestamped information about every task: database queries to identify pending campaigns, subscriber selection logic, content rendering, delivery server selection, SMTP connection establishment, message delivery, log writes. The output typically reveals the bottleneck immediately. Common patterns the verbose output exposes:

  • "Database query timed out" indicates missing index on subscribers table or substantial table size
  • "SMTP connection failed" indicates delivery server configuration or network problem
  • "Authentication failed" indicates wrong delivery server credentials
  • "PHP Fatal error: Allowed memory size" indicates memory_limit too low for content rendering
  • "Suppression list query taking 47 seconds" indicates missing index on suppression table
  • "Delivery server quota exceeded" indicates SES sandbox or quota limits hit

Note: the verbose flag is --verbose=1 not verbose=1 (missing dashes is the most common syntax error operators encounter when trying to use verbose mode for the first time).

The verbose flag that saves hours of debugging

An operator we worked with spent 4 hours debugging why campaigns were sitting "pending sending" after a server migration. They tested SMTP credentials manually (worked), verified database connectivity (worked), restarted services (no change). The solution was 30 seconds of verbose mode: --verbose=1 showed PHP fatal error about missing imap extension which had been omitted during PHP reinstall on the new server. apt install php8.1-imap and the campaigns resumed sending within 60 seconds. Always try verbose mode first when MailWizz behaves unexpectedly. The output reveals causes that hours of manual testing miss because the manual tests do not exercise the exact code path MailWizz uses internally.

Plesk, cPanel, CyberPanel patterns

Control panel environments require slightly different cron patterns because of how they package PHP and structure the filesystem.

Plesk pattern. Plesk packages multiple PHP versions under /opt/plesk/php/ and the correct binary path includes the specific version:

* * * * * /opt/plesk/php/8.1/bin/php -q /var/www/vhosts/example.com/httpdocs/apps/console/console.php send-campaigns >/dev/null 2>&1

Plesk users add cron jobs through Subscriptions then Scheduled Tasks UI which generates the correct user context automatically. Avoid editing the crontab directly on Plesk because Plesk overwrites it during configuration changes.

cPanel pattern. cPanel uses /usr/local/bin/php as the default or version-specific paths under /opt/cpanel/ea-phpXX/root/usr/bin/php when PHP Selector is in use:

* * * * * /usr/local/bin/php -q /home/username/public_html/apps/console/console.php send-campaigns >/dev/null 2>&1

cPanel users add cron jobs through Cron Jobs UI in the cPanel dashboard. The UI generates correct user context.

CyberPanel pattern. CyberPanel uses OpenLiteSpeed PHP under /usr/local/lsws/lsphpXX/bin/php:

* * * * * /usr/local/lsws/lsphp81/bin/php -q /home/example.com/public_html/apps/console/console.php send-campaigns >/dev/null 2>&1

CyberPanel users can add through Manage Cron Jobs UI or edit crontab directly as the appropriate user.

The substantive point across all control panels: the PHP path is environment-specific and copying cron commands between environments without adjusting paths is the most common cause of cron failures after server migration. Always verify with which php as the cron-executing user before installing.

systemd-timers as alternative

Some operators prefer systemd-timers over traditional cron for better integration with system logging and dependency management. Implementing MailWizz cron as systemd-timers:

Create the service unit at /etc/systemd/system/mailwizz-send-campaigns.service:

[Unit]
Description=MailWizz send-campaigns

[Service]
Type=oneshot
User=www-data
ExecStart=/usr/bin/php -q /var/www/mailwizz/apps/console/console.php send-campaigns
StandardOutput=null
StandardError=journal

Create the timer unit at /etc/systemd/system/mailwizz-send-campaigns.timer:

[Unit]
Description=MailWizz send-campaigns timer

[Timer]
OnCalendar=*-*-* *:*:00
Persistent=true

[Install]
WantedBy=timers.target

Enable and start the timer:

systemctl daemon-reload
systemctl enable --now mailwizz-send-campaigns.timer
systemctl list-timers | grep mailwizz

Repeat the pattern for each MailWizz cron command. The systemd-timers approach has advantages: better logging through journalctl, dependency management between units, status visibility through systemctl, integration with systemd's failure handling. Disadvantages: more files to manage compared to a single crontab, slight learning curve for operators familiar only with cron.

For most operators traditional cron is fine and the systemd-timers approach adds complexity without proportional benefit. The pattern is documented here because operators who prefer systemd elsewhere in their stack frequently want consistency for MailWizz cron as well.

Common failure modes

A consolidated list of MailWizz cron failure modes and their fixes:

Cron daemon not running. Symptom: no commands execute at all. Fix: systemctl start cron and systemctl enable cron.

Wrong PHP binary path. Symptom: send-campaigns warning despite jobs registered. Fix: identify correct path with which php, update all cron lines.

console.php permissions 000. Symptom: cron silently fails after MailWizz upgrade. Fix: chmod 0644 /var/www/mailwizz/apps/console/console.php.

Wrong user owns cron. Symptom: permission denied errors in cron log. Fix: install cron as the user that owns MailWizz files (typically www-data).

PHP memory_limit too low. Symptom: cron starts then dies, partial campaign sending. Fix: increase memory_limit to 512M minimum in CLI php.ini.

PHP max_execution_time too restrictive. Symptom: long-running jobs killed mid-execution. Fix: set max_execution_time to 0 (unlimited) in CLI php.ini.

SELinux blocking cron. Symptom: cron registered but never runs. Fix: check audit logs with ausearch -m AVC -ts recent, adjust SELinux contexts or set permissive mode for cron.

Database connection failure. Symptom: console log shows MySQL connection errors. Fix: verify database credentials in config, ensure database server is running and accepting connections.

Disk full. Symptom: cron silently fails on writes. Fix: clean up logs, rotate old log files, expand storage.

Server time clock skewed. Symptom: MailWizz warnings about commands not running when they appear to be running. Fix: install and configure NTP, verify time is correct.

Control panel overwrote crontab. Symptom: cron jobs disappeared after panel update. Fix: use the panel's cron management UI rather than editing crontab directly.

cron line syntax error. Symptom: one specific job not running while others work. Fix: verify the cron line matches expected format, look for typos in command or path.

Race conditions during high-volume sending. Symptom: occasional missed minutes of send-campaigns. Fix: ensure only one MailWizz instance writes to the database (not running send-campaigns on multiple servers simultaneously without proper coordination).

This reference covers the substantive cron-related work for MailWizz production deployments. Cron problems account for the substantial majority of MailWizz operational incidents and the verbose mode flag plus the diagnostic procedure outlined here will resolve most situations in under an hour. The investment in understanding cron deeply pays back many times because MailWizz cron failures are silent until they are very loud, and operators who can diagnose quickly avoid the alternative of guessing for days.

M
Marcus Webb

Email Infrastructure Architect at Cloud Server for Email. Debugs MailWizz cron problems for ESP clients and SaaS operators across plain VPS, Plesk, cPanel, and CyberPanel environments. Related: MailWizz Production Setup Checklist, MailWizz PowerMTA vs SMTP Relay, MailWizz vs Sendy.