Hive Mail adds one command group, wp hivemail, with three commands. They need WP-CLI on the server. Run them from the WordPress folder, or add --path=/path/to/wordpress. No other wp hivemail command exists.
wp hivemail worker #
Runs one scheduler tick now. It is the same tick WordPress runs every minute: it sends due emails, starts due campaigns and automation steps, advances background jobs and does the other minute work. It also counts as a run on Settings > Scheduler. A lock keeps two ticks from running at once.
wp hivemail worker [--seconds=<n>] [--limit=<n>] [--ignore-rate-limit]
| Option | Meaning | Default |
|---|---|---|
--seconds=<n> |
Time budget for the tick, in seconds | 45 |
--limit=<n> |
Most messages to process in this run | no limit |
--ignore-rate-limit |
Ignore the sending speed set in Settings > Sending | off |
On success it prints Success: and one line of JSON with the counts (all zero here, because nothing was due): processed, sent, failed, retried, skipped, released, stopped and took_ms. stopped says why the run ended: empty (nothing left), time, limit, memory or rate_limited.
wp hivemail worker
Success: {"processed":0,"sent":0,"failed":0,"retried":0,"skipped":0,"released":0,"stopped":"empty","took_ms":20}
If another tick is already running, it stops with Error: Another worker tick is already running.
Run it from a real cron #
Add this to the server's crontab (crontab -e) so the tick runs every minute, whether or not anyone visits the site:
* * * * * wp hivemail worker --seconds=50 --quiet --path=/var/www/html
Keep a call for WordPress's own cron too. Hive Mail's daily clean-up and other WordPress jobs run through it. Either of these works:
*/5 * * * * wp cron event run --due-now --quiet --path=/var/www/html
* * * * * curl -s 'https://example.com/wp-cron.php' > /dev/null 2>&1
Add define( 'DISABLE_WP_CRON', true ); to wp-config.php only when a real cron also calls wp-cron.php or runs wp cron event run --due-now. Settings > Scheduler has a step-by-step guide per host (see Scheduled sending and cron).
Tip:
--secondsshould be a little under the interval between runs, so two runs do not overlap. The lock handles it if they do.
wp hivemail status #
Prints the state of the queue and the system as indented JSON. It changes nothing.
wp hivemail status
{
"version": "1.0.0",
"db_version": "1.13.0",
"db_expected": "1.13.0",
"tables_missing": [],
"scheduler": "action-scheduler",
"last_tick_age": 597,
"queue": {
"counts": { "failed": 6, "paused": 682, "sent": 5506, "skipped": 3 },
"oldest_due_age": null
},
"php": "8.2.29",
"wordpress": "7.1.2",
"action_scheduler": "4.0.0"
}
(queue.counts is shortened here to one line.)
Keys in the answer:
| Key | Meaning |
|---|---|
version |
The Hive Mail version |
db_version, db_expected |
The installed and the expected database version. They should match |
tables_missing |
A list of missing tables (empty when all is well) |
scheduler |
action-scheduler or wp-cron: what drives the minute tick |
last_tick_age |
Seconds since the last tick, or null if it never ran |
queue.counts |
Messages by status (queued, sent, failed, …) |
queue.oldest_due_age |
Seconds the oldest due message has waited |
php, wordpress |
Versions |
action_scheduler |
The version of Action Scheduler in use, or null |
A last_tick_age of more than a few minutes, or a growing oldest_due_age, means the scheduler is not running. See A scheduled campaign did not go out.
wp hivemail migrate #
Creates or updates Hive Mail's database tables. Use it after you copy files onto a server without opening the admin, or when status shows tables_missing.
wp hivemail migrate
Success: Database is at version 1.13.0.
The version number printed is the database schema version. It is not the plugin version. Running it again is safe.
Use with other WP-CLI tools #
# Run due WordPress cron events, then the Hive Mail tick, quietly
wp cron event run --due-now --quiet && wp hivemail worker --quiet
# Read one value from the status JSON
wp hivemail status | jq '.queue.counts'
If you get 'hivemail' is not a registered wp command, the plugin is not active on that site: add --path= (or --url= on a multisite network). Error: Another worker tick is already running. is normal when two runs overlap.