---
title: "WP-CLI commands"
description: "The three wp hivemail commands: worker runs the scheduler from a cron, status prints queue and system state, migrate updates the tables."
url: "https://hiveplugins.com/docs/hive-mail-wp-cli-commands/"
updated: "2026-10-28"
category: Hive Mail
---

# WP-CLI commands

Hive Mail adds one command group, `wp hivemail`, with three commands. They need [WP-CLI](https://wp-cli.org/) 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](/docs/hive-mail-scheduled-sending-and-cron/)).

> **Tip:** `--seconds` should 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](/docs/hive-mail-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.

Next: [Scheduled sending and cron](/docs/hive-mail-scheduled-sending-and-cron/), [Settings: Scheduler](/docs/hive-mail-settings-scheduler/).
