---
title: "WP-CLI Commands - Manage Translations from CLI - PerfLocale"
description: "PerfLocale WP-CLI commands for managing languages, translations, strings, caches, addons, and database integrity."
canonical: "https://perflocale.com/docs/wp-cli/"
source: "https://perflocale.com/docs/wp-cli/"
format: "markdown"
---
# WP-CLI Commands

PerfLocale provides WP-CLI commands for managing languages, translations, strings, caches, and database integrity from the command line.

**Namespace:** `wp perflocale`

## Languages

### List Languages

```bash
wp perflocale languages list
```

Displays all configured languages in a table.

**Options:**

-   `--format=<format>` - Output format: `table` (default), `json`, `csv`, `yaml`, `count`, `ids`.

**Example:**

```bash
$ wp perflocale languages list
+----+------+--------+-----------+---------+--------+-----------+
| ID | Slug | Locale | Name | Default | Active | Direction |
+----+------+--------+-----------+---------+--------+-----------+
| 1 | en | en_US | English | No | Yes | ltr |
| 2 | fr | fr_FR | French | Yes | Yes | ltr |
| 3 | de | de_DE | German | No | Yes | ltr |
| 4 | ar | ar | Arabic | No | Yes | rtl |
+----+------+--------+-----------+---------+--------+-----------+

$ wp perflocale languages list --format=json
[{"ID":"1","Slug":"en","Locale":"en_US",...}]
```

### Add Language

```bash
wp perflocale languages add <locale> [--default]
```

Adds a new language.

**Arguments:**

-   `<locale>` (required) - WordPress locale code (e.g. `fr_FR`, `es_ES`, `ar`).

**Options:**

-   `--default` - Set as the default language.

RTL languages (Arabic, Hebrew, Farsi, Urdu, etc.) are auto-detected.

**Examples:**

```
# Add French
$ wp perflocale languages add fr_FR
Success: Language fr_FR added with ID 7 (direction: ltr).

# Add Arabic (RTL auto-detected)
$ wp perflocale languages add ar
Success: Language ar added with ID 8 (direction: rtl).

# Add as default language
$ wp perflocale languages add en_US --default
```

### Delete Language

```bash
wp perflocale languages delete <slug>
```

Deletes a language. Prompts for confirmation. Cannot delete the default language.

**Arguments:**

-   `<slug>` (required) - Language slug (e.g. `fr`, `de`).

**Example:**

```bash
$ wp perflocale languages delete fr
Warning: 42 translation links use this language. They will be orphaned.
Are you sure you want to proceed? [y/n] y
Success: Language 'fr' deleted.
```

**Safety features:**

-   Warns if translations exist for this language.
-   Requires explicit confirmation (use `--yes` to skip in scripts).
-   Blocks deletion of the default language.

## Translate

### Single Post

```bash
wp perflocale translate <post_id> --to=<lang> [--provider=<provider>]
```

Translates a single post using machine translation.

**Arguments:**

-   `<post_id>` (required) - The post ID to translate.

**Options:**

-   `--to=<lang>` (required) - Target language slug.
-   `--provider=<provider>` - Provider: `deepl`, `google`, `microsoft`, `libretranslate`, `external_agency`, `wp_ai_client`. Uses configured default if omitted.

**Example:**

```bash
$ wp perflocale translate 42 --to=de
Translating post 42 to de...
Success: Translated! New post ID: 99
```

### Bulk Translation

```bash
wp perflocale translate --all --to=<lang> [--post-type=<type>] [--skip-existing]
wp perflocale translate --post-ids=<ids> --to=<lang> [--skip-existing]
```

Translates multiple posts with a progress bar.

**Options:**

-   `--all` - Translate all published posts of the given type.
-   `--post-type=<type>` - Post type for `--all`. Default: `post`.
-   `--post-ids=<ids>` - Comma-separated list of post IDs.
-   `--to=<lang>` (required) - Target language slug.
-   `--skip-existing` - Skip posts that already have a translation in the target language.
-   `--include-meta` - Also machine-translate registered meta fields (SEO titles/descriptions and, when enabled in settings, custom fields).
-   `--dry-run` - Print a character/cost estimate for the selection (items, characters, monthly budget) without translating anything.
-   `--async` - With `--all`: dispatch a resumable chunked background job instead of translating in-process. Track it under PerfLocale → Jobs or `wp perflocale jobs list`.
-   `--provider=<provider>` - Translation provider.

**Examples:**

```
# Translate all posts to German, skipping already translated
$ wp perflocale translate --all --to=de --post-type=post --skip-existing
Translating to de 100% [============================] 50 / 50
Success: Done. Translated: 38, Skipped: 12, Failed: 0.

# Translate specific posts to French
$ wp perflocale translate --post-ids=42,43,44 --to=fr
Translating to fr 100% [============================] 3 / 3
Success: Done. Translated: 3, Skipped: 0, Failed: 0.

# Translate all WooCommerce products
$ wp perflocale translate --all --to=fr --post-type=product --skip-existing
```

**Notes:**

-   Machine translation must be enabled — turn the feature on at PerfLocale → Addons, then configure it at Settings → Addons → Machine Translation.
-   Failed translations are reported individually but don't stop the batch.
-   Progress bar shows real-time progress.

## Translations

### List Translations

```bash
wp perflocale translations list <post_id> [--format=<format>]
```

Shows all translations linked to a post.

**Example:**

```bash
$ wp perflocale translations list 42
+----------+---------+--------------------+---------+
| Language | Post ID | Title | Status |
+----------+---------+--------------------+---------+
| EN * | 42 | Hello World | publish |
| FR | 160 | Bonjour le monde | publish |
| DE | 165 | Hallo Welt | publish |
+----------+---------+--------------------+---------+
```

The `*` marks the current post's language.

### Create Translation

```bash
wp perflocale translations create <post_id> --to=<lang>
```

Creates a new translation post (copies content from source).

**Example:**

```bash
$ wp perflocale translations create 42 --to=fr
Success: Translation created. New post ID: 200
```

### Delete Translation

```bash
wp perflocale translations delete <post_id> --lang=<slug>
```

Permanently deletes a translation post. Prompts for confirmation.

**Example:**

```bash
$ wp perflocale translations delete 42 --lang=fr
Are you sure you want to proceed? Delete fr translation (post 200)? [y/n] y
Success: Translation deleted (post 200).
```

### Set Language

```bash
wp perflocale translations set-language <post_id> --lang=<slug>
```

Changes the language of an existing post. Fails if the language is already used by a sibling in the same translation group.

**Example:**

```bash
$ wp perflocale translations set-language 42 --lang=en
Success: Post 42 language set to en.

$ wp perflocale translations set-language 42 --lang=fr
Error: Failed to set language. The language may already be used by a sibling translation.
```

## Strings

### Scan for Strings

```bash
wp perflocale strings scan [--domain=<domain>] [--dir=<dir>]
```

Scans PHP files for translatable strings (`__()`, `_e()`, `_x()`, `_n()`, `_nx()`, `_n_noop()`).

**Options:**

-   `--domain=<domain>` - Only scan strings for a specific text domain.
-   `--dir=<dir>` - Directory to scan. Default: active theme directory. (Named `--dir` because `--path` is wp-cli’s own global WordPress-root flag and never reaches the command.)

**Examples:**

```
# Scan active theme
$ wp perflocale strings scan
Scanning /var/www/html/wp-content/themes/flavor/flavor...
Success: Found 342 strings, inserted 15 new.

# Scan a specific plugin
$ wp perflocale strings scan --dir=/var/www/html/wp-content/plugins/woocommerce --domain=woocommerce
Scanning /var/www/html/wp-content/plugins/woocommerce...
Success: Found 4821 strings, inserted 4821 new.
```

**Performance:**

-   Batched inserts (500 per batch) - handles large codebases.
-   Skips files over 2 MB to prevent memory exhaustion.
-   Excludes `vendor/`, `node_modules/`, `.git/`, `tests/`, `build/`, `dist/`.

## Slugs

### Backfill Slug Translations

```bash
wp perflocale slugs backfill
```

Populates the slug translation table for all existing term translation groups. This ensures that translated taxonomy URLs work correctly.

**When to run:**

-   After migrating from another multilingual plugin.
-   After creating term translations manually.
-   If taxonomy archive URLs show 404 errors.

**Example:**

```bash
$ wp perflocale slugs backfill
Success: Backfilled 48 slug translation entries.
```

### Verify Slug Translations

```bash
wp perflocale slugs verify
```

Checks if all terms in translation groups have corresponding slug translation entries.

**Example:**

```bash
$ wp perflocale slugs verify
Success: All term translations have slug entries.

$ wp perflocale slugs verify
Warning: 12 terms are missing slug translations. Run 'wp perflocale slugs backfill' to fix.
```

## Cache

### Flush Caches

```bash
wp perflocale cache flush
```

Flushes all three cache layers:

-   **L1:** In-memory static cache.
-   **L2:** WordPress object cache (Redis/Memcached if available).
-   **L3:** Transients (wp\_options table).

**Example:**

```bash
$ wp perflocale cache flush
Success: All PerfLocale caches flushed.
```

## Migrate

### Migrate from another multilingual plugin

```bash
wp perflocale migrate <source> [--dry-run] [--yes] [--force-restart]
```

Imports translation data from another multilingual plugin into PerfLocale’s own tables. The source plugin’s data is not modified or deleted - the importer is read-only on the source side and writes new rows on the PerfLocale side.

**Arguments:**

-   `<source>` (required) - one of `wpml`, `polylang`, `translatepress`.

**Options:**

-   `--dry-run` - confirm the source is detected and importable without writing anything.
-   `--yes` - skip the interactive “Are you sure?” prompt (use for scripting / CI).
-   `--force-restart` - clear the migration source-map for this importer before the run. Use only after a _deliberate_ DB restore to a known-good pre-migration state when you want fresh translation\_groups allocated rather than reusing mappings from the prior run. Running this on a database whose translation\_groups already point at the source plugin’s data WILL orphan those groups. The default (omit) is the safer choice; see the [migration disaster-recovery section](https://perflocale.com/docs/migration/#force-restart) for details.

**Examples:**

```
# Confirm WPML data is detected.
$ wp perflocale migrate wpml --dry-run
Dry run - checking wpml data...
Success: Wpml data detected and ready to import. Run without --dry-run to proceed.

# Run the real import, prompt for confirmation.
$ wp perflocale migrate wpml
Migrate translation data from wpml? This cannot be undone. [y/n] y
Migrating from wpml...
Success: Migration complete. Imported: 234 posts, 89 terms, 1412 strings.

# Scripted (no prompt).
$ wp perflocale migrate polylang --yes
Migrating from polylang...
Success: Migration complete. Imported: 128 posts, 34 terms.

# Operator workflow: restored a clean pre-migration backup, want a fresh
# allocation rather than reusing the prior run’s source-map mappings.
$ wp perflocale migrate wpml --force-restart --yes
--force-restart: cleared 234 source-map row(s) for wpml.
Migrating from wpml...
Success: Migration complete. Imported: 234 posts, 89 terms, 1412 strings.
```

**Per-source guides:** [WPML](https://perflocale.com/docs/migration/wpml/) • [Polylang](https://perflocale.com/docs/migration/polylang/) • [TranslatePress](https://perflocale.com/docs/migration/translatepress/). For the shared pre-flight steps and safety model, see the [migration overview](https://perflocale.com/docs/migration/).

**Memory tuning on very large sites:** all three importers chunk their source-table SELECTs. The default is fine up to tens of thousands of posts (32 MB peak in our 5,000 group × 3 language benchmark). On tighter `memory_limit` hosts you can shrink the chunk size with `perflocale/migration/wpml/batch_size`, `perflocale/migration/polylang/batch_size`, or `perflocale/migration/translatepress/batch_size` filters.

## Database Migrations

### Run pending schema migrations

```bash
wp perflocale db-migrate
```

Applies any pending PerfLocale database schema migrations. Idempotent - safe to run multiple times. Useful in CI/CD pipelines or headless environments where the WordPress admin dashboard is never visited (since the migrator normally runs on `admin_init`).

**Example:**

```bash
$ wp perflocale db-migrate
Success: PerfLocale database migrations completed successfully.
```

## Health Check

### Run Database Integrity Checks

```bash
wp perflocale health-check [--fix]
```

Checks for database inconsistencies and optionally repairs them.

**Options:**

-   `--fix` - Automatically fix found issues.

**Checks performed:**

1.  **Orphaned post links** - Translation links pointing to deleted posts.
2.  **Orphaned term links** - Translation links pointing to deleted terms.
3.  **Invalid language references** - Links referencing deleted languages.
4.  **Widow translation groups** - Non-string groups with zero remaining links. String-type groups are preserved (they are valid with no links until a translation is saved).
5.  **Orphan string groups** - String-type groups whose owning row in the strings table is gone.
6.  **Groupless orphan links** - Translation links whose parent group row no longer exists.

The `--fix` flag removes the offending rows directly and then flushes all PerfLocale caches, so stale cache entries can't resurrect the deleted rows. Running without `--fix` is strictly read-only.

**Examples:**

```
# Report only
$ wp perflocale health-check
Running PerfLocale health checks...

	Orphaned post links: 0
	Orphaned term links: 3
	Invalid language references: 0
	Widow translation groups: 5
	Groupless orphan links: 2

Warning: Found 10 issues. Run with --fix to repair.

# Auto-fix
$ wp perflocale health-check --fix
Running PerfLocale health checks...

	Orphaned post links: 0
	Orphaned term links: 3
	Fixed: removed 3 orphaned term links.
	Invalid language references: 0
	Widow translation groups: 5
	Fixed: removed 5 widow groups.
	Groupless orphan links: 2
	Fixed: removed 2 groupless orphan links.

Success: Fixed 10 issues.
```

## Status

### Translation Completeness Overview

```bash
wp perflocale status [--format=<format>]
```

Displays translation completeness per language.

**Options:**

-   `--format=<format>` - Output format: `table` (default), `csv`, `json`, `yaml`, `count`.

**Example:**

```bash
$ wp perflocale status
+--------------+-----------+------------+-------+---------+--------------+-------+-------+
| Language     | Published | Translated | Draft | Pending | Needs Update | Empty | Total |
+--------------+-----------+------------+-------+---------+--------------+-------+-------+
| English (en) | 12        | 0          | 2     | 0       | 0            | 0     | 14    |
| French (fr)  | 14        | 0          | 0     | 0       | 0            | 0     | 14    |
| German (de)  | 8         | 0          | 1     | 0       | 0            | 5     | 14    |
| Arabic (ar)  | 3         | 0          | 0     | 0       | 0            | 11    | 14    |
+--------------+-----------+------------+-------+---------+--------------+-------+-------+

$ wp perflocale status --format=json
[{"Language":"English (en)","Published":12,...}]
```

## Export & Import

### Export a single site

```bash
wp perflocale export <file>
```

Writes a single JSON envelope containing every PerfLocale-managed surface for the current site — settings, roles & capabilities, languages, translation links, string translations, slug translations, and content hashes. The envelope embeds a `format_version` field so importers refuse payloads written by a newer format. Credential-shaped setting keys (anything ending `_api_key`, `_token`, `_key`, `_secret`, `_password`) are redacted, so a backup never carries API keys.

```bash
$ wp perflocale export /tmp/perflocale-backup.json
Success: Exported to /tmp/perflocale-backup.json (1433.6 KB).
```

### Import into a single site

```bash
wp perflocale import <file> [--mode=<mode>]
```

**Options:**

-   `--mode=merge` (default) - additive; existing rows are kept, new rows are inserted. Conflicts resolved by re-mapping foreign keys via id-maps so cross-site references stay intact.
-   `--mode=replace` - truncates the target tables first (scoped to the current site on multisite) and then writes the envelope verbatim.

```
# Restore from backup, additive
wp perflocale import /tmp/perflocale-backup.json

# Replace everything PerfLocale owns on this site with the envelope
wp perflocale import /tmp/perflocale-backup.json --mode=replace --yes
```

**Exit code.** `import`, `po-import` and `network-import` exit non-zero when the import reports errors, so a restore script can rely on the exit code alone — a malformed file no longer prints a warning and then `Success:`. Ordinary duplicate-key merge skips are not errors and do not affect the exit code.

**Replace is all-or-nothing.** The wipe and the reload run inside one transaction: any row the database refuses rolls the whole import back, including any settings, add-on settings, disabled-add-on list and role grants the bundle carried. You keep your pre-import state and get an error naming the table and the failed-row count.

### Export string translations as PO

```bash
wp perflocale po-export <file> --lang=<slug> [--domain=<domain>]
```

Writes a gettext PO file for one language. Optional `--domain` filters to a single text domain (default: all domains).

```bash
$ wp perflocale po-export /tmp/fr.po --lang=fr
Success: PO exported to /tmp/fr.po (58.3 KB).

$ wp perflocale po-export /tmp/fr-myplugin.po --lang=fr --domain=my-plugin
```

### Import string translations from PO

```bash
wp perflocale po-import <file> --lang=<slug> [--replace]
```

**Options:**

-   `--replace` - wipes every existing translation for this language first (in one transaction), then imports the file; msgids absent from the PO file end up untranslated. Without it, the import is an upsert: new msgids are inserted and existing msgids are updated with the file's translation.

Robust to `\r\n` line endings and gracefully ignores fuzzy / obsolete entries.

```bash
wp perflocale po-import /tmp/fr.po --lang=fr
wp perflocale po-import /tmp/fr.po --lang=fr --replace
```

### Export a multisite network

```bash
wp perflocale network-export <file> [--include-inactive]
```

Multisite only. Walks every site in the network and writes a single envelope keyed by blog ID, marked `network: true`. Inactive sites are skipped unless `--include-inactive` is passed.

```bash
wp perflocale network-export /tmp/network.json
wp perflocale network-export /tmp/network.json --include-inactive
```

### Import a multisite network

```bash
wp perflocale network-import <file> [--mode=<mode>] [--site=<id>]
```

**Options:**

-   `--mode=merge` (default) or `--mode=replace` - same semantics as single-site `import`, applied per site.
-   `--site=<id>` - pick one source `site_id` slice; the current blog receives the data. Required when loading a network envelope outside multisite.
-   `--force` - import a slice even when its recorded `site_url` doesn't match the target blog (by default mismatched slices are skipped with a warning). Use after a domain migration when the blog IDs are known-correct.

```
# Across the whole network (multisite)
wp perflocale network-import /tmp/network.json --mode=replace

# Restore one slice on a non-multisite target
wp perflocale network-import /tmp/network.json --site=42
```

## Addons

Inspection-focused subcommands for the [Addon System](https://perflocale.com/docs/addon-system/). `list`, `info`, `orphans`, `doctor`, and `errors` (without `--clear`) are read-only; `migrate`, `reset-version`, `enable`, `disable`, and `reset-quarantine` write. There is no `uninstall` subcommand by design.

### List Addons

```bash
wp perflocale addon list [--format=<format>] [--fields=<fields>] [--all]
```

**Options:**

-   `--format=table|json|csv|yaml|ids|count` (default: `table`).
-   `--fields=<comma-separated>` - pick specific columns. Available: `id, name, bundled, booted, disabled, compatible, has_schema, schema_target, schema_stored, has_uninstall, has_custom, manifest`. Default: all.
-   `--all` - include orphan manifests (addons whose class is gone but whose manifest is still in the database).

The default table view exposes `disabled` and `booted` alongside `bundled` so you can see lifecycle state in one place without running `doctor` separately.

```bash
wp perflocale addon list
wp perflocale addon list --format=json --all
wp perflocale addon list --fields=id,disabled --format=csv
wp perflocale addon list --format=ids        # plain id list for shell loops
```

### Inspect a Single Addon

```bash
wp perflocale addon info <id> [--format=<format>]
```

Shows the addon's full manifest plus a live `PurgePlan` preview (counts only — no DB mutation). Use this to verify that a custom addon's tables, options, and capabilities are namespaced correctly before relying on the uninstall contract.

```bash
wp perflocale addon info my-addon
wp perflocale addon info my-addon --format=json
```

### List Orphans

```bash
wp perflocale addon orphans
```

Lists addon IDs that still have a manifest row but whose registering class is no longer loaded — typically because the addon's plugin was deactivated or deleted before PerfLocale itself was uninstalled.

### Run Addon Migrations

```bash
wp perflocale addon migrate [<id>] [--force]
```

**Options:**

-   `<id>` - optional; migrate just this addon (default: all).
-   `--force` - reset the stored schema version to `0` and re-run every migration step. Dangerous.

```bash
wp perflocale addon migrate
wp perflocale addon migrate my-addon
wp perflocale addon migrate my-addon --force
```

### Migration / Uninstall Errors

```bash
wp perflocale addon errors [<id>] [--clear]
```

Tail the addon migration / uninstall error log. Pass an addon ID to filter, or `--clear` to empty the log (optionally for one addon).

```bash
wp perflocale addon errors
wp perflocale addon errors my-addon
wp perflocale addon errors --clear
wp perflocale addon errors my-addon --clear
```

### Reset Stored Schema Version

```bash
wp perflocale addon reset-version <id> <version> [--yes]
```

Manual recovery only — sets the stored schema version for one addon to a specific value. Setting it lower than the addon's current target causes the next migration pass to re-run every step in between. Confirms before writing unless `--yes` is passed.

```bash
wp perflocale addon reset-version my-addon 0
wp perflocale addon reset-version my-addon 2 --yes
```

### Health Summary

```bash
wp perflocale addon doctor [--format=<format>]
```

One-shot operator summary: counts of booted / disabled / quarantined / version-mismatched addons in a single table with the affected IDs. The first command to run when an addon isn't behaving as expected.

```bash
wp perflocale addon doctor
wp perflocale addon doctor --format=json
```

### Enable / Disable

```bash
wp perflocale addon enable <id>
wp perflocale addon disable <id>
```

Mirror of the per-card Enable / Disable button on the Addons admin page. Writes the addon ID into the `perflocale_disabled_addons` option and flushes the bootable-addons transient so the change applies on the very next request. Works for both bundled (in-plugin) and external addons — disabling a bundled addon takes effect immediately, so only disable one if you genuinely don't want that integration.

```bash
wp perflocale addon disable my-addon
wp perflocale addon disable woocommerce
wp perflocale addon enable my-addon
```

### Read / Write Addon Settings

```bash
wp perflocale addon settings get <addon-id> <key> [--default=<val>] [--format=scalar|json]
wp perflocale addon settings set <addon-id> <key> <value> [--type=string|bool|int|float|json]
wp perflocale addon settings list <addon-id> [--format=table|json|csv|yaml]
```

Get, set, and list values for an addon’s settings without going through the admin UI. `settings set` coerces the value to the supplied `--type` (default `string`) and returns an error if the addon’s entry would exceed the 16 KiB per-addon cap.

**`'storage' => 'global'` fields.** Some addons (the bundled WooCommerce addon is the canonical example) keep their settings in the main `perflocale_settings` option instead of in the addon-storage option, because the runtime + REST APIs read from there. For those fields the CLI does the right thing automatically:

-   `settings get` transparently reads from `perflocale_settings`, so the value you see is the value the runtime actually uses.
-   `settings set` writes through `Settings::update()` rather than into addon storage, so the full invalidation chain runs (config-cache flush, cron reschedules, settings-updated listeners). Prefer it over `wp option patch update perflocale_settings <key> <value>`, which changes the stored value but leaves all of that stale. If a sanitizer coerces the value — or an environment variable / PHP constant overrides it — the write still happens and the command warns you with the effective value.
-   `settings list` shows addon-storage AND global-storage fields together with a `storage` column on every row, so you can see exactly where each setting lives.

```
# Addon-storage field (lives in perflocale_addon_settings):
wp perflocale addon settings get my-addon batch_size
wp perflocale addon settings set my-addon batch_size 50 --type=int
wp perflocale addon settings set my-addon limits '{"max":100}' --type=json

# Global-storage field (lives in perflocale_settings):
wp perflocale addon settings get woocommerce wc_email_translation     # reads live value
wp perflocale addon settings set woocommerce wc_email_translation false --type=bool
# → Success: Saved wc_email_translation to the global perflocale_settings option.

# settings list shows both kinds, with a `storage` column:
wp perflocale addon settings list woocommerce
# key                          value         storage
# wc_email_translation         true          global
# wc_sync_stock                true          global
# ...
```

### Reset Failure Quarantine

```bash
wp perflocale addon reset-quarantine <id>
```

Clear an addon's failure counter after the underlying boot error has been fixed. Quarantined addons (3 consecutive boot failures) are otherwise skipped until manually cleared — this is the manual-clear path.

```bash
wp perflocale addon reset-quarantine my-addon
```

## Background Jobs

Inspect and control the background-processing queue from the command line. See the [Background Jobs](https://perflocale.com/docs/background-jobs/) doc for the full feature reference.

**Namespace:** `wp perflocale jobs`

### List Jobs

```bash
wp perflocale jobs list [--status=<status>] [--format=<format>]
```

Lists all jobs in the active-jobs index.

**Options:**

-   `--status=<status>` — Filter by status: `queued`, `running`, `complete`, `failed`, `canceled`.
-   `--format=<format>` — Output format: `table` (default), `json`, `csv`, `yaml`.

**Example:**

```bash
$ wp perflocale jobs list
+--------------------------------------+--------------+----------+----------+--------------------+
| id                                   | type         | status   | progress | updated_at         |
+--------------------------------------+--------------+----------+----------+--------------------+
| 5fc94964-29f6-4697-8c4e-64a8ffb5c72d | string_scan  | running  | 47%      | 12 seconds ago     |
| 9d291e3c-3a41-47ab-b3e6-3ba00e88e55a | data_import  | queued   | 0%       | 8 seconds ago      |
+--------------------------------------+--------------+----------+----------+--------------------+

$ wp perflocale jobs list --status=failed --format=json
[{"id":"...","type":"bulk_translate","status":"failed",...}]
```

### Get Job Details

```bash
wp perflocale jobs get <id> [--format=<format>]
```

Prints the full state of one job: type, hook, engine, status, progress, args, log ring buffer, error message, result payload, attempts, created\_at / completed\_at / updated\_at, created\_by user id.

**Arguments:**

-   `<id>` (required) — Job UUID (visible in `jobs list`).

**Options:**

-   `--format=<format>` — Default `yaml` (one key:value per line); `json` for machine-readable.

### Cancel a Job

```bash
wp perflocale jobs cancel <id>
```

Cancels a queued or running job. Sets status to `canceled` and unschedules the worker event. A worker that's currently mid-`execute()` aborts cooperatively on its next progress callback — the delay until that happens depends on the job's batch size (most jobs tick every batch, so the lag is usually brief, but a large batch can hold it open for a few seconds). Very short jobs that complete before any progress tick may still finish naturally.

Refuses jobs that are already `complete` / `failed` / `canceled` with a warning.

### Retry a Job

```bash
wp perflocale jobs retry <id>
```

Re-enqueues a `failed` or `canceled` job. Resets status to `queued`, clears the error and result fields, schedules a new worker event with the original args + hook.

Refuses non-terminal jobs (`queued` / `running` / `complete`) with a warning.

### Delete a Job

```bash
wp perflocale jobs delete <id>
```

Permanently removes a job from the active-jobs index, deletes its per-job state row, and deletes the export file the job produced if it still exists (jobs created before 1.0.1 excepted). Only allowed on jobs that have already finished (`complete`, `failed`, `canceled`) — running/queued jobs must be canceled first so the runner has a chance to unschedule cleanly. Matches the same restriction as the REST `DELETE /jobs/{id}` endpoint.

### Pause / Unpause the Queue

```bash
wp perflocale jobs pause
wp perflocale jobs unpause
```

Toggles the `background_paused` setting. While paused, new dispatches are accepted but workers immediately re-queue them every 5 minutes (configurable) instead of running. Operator brake when something is mis-dispatching.

### Run Garbage Collection

```bash
wp perflocale jobs gc
```

Runs the daily GC sweep right now without waiting for the cron tick. Reports how many jobs were pruned. Performs:

1.  Stuck-job sweep — queued/running jobs with no `updated_at` bump in 6+ hours are marked failed.
2.  Terminal-state prune — complete/failed/canceled jobs older than 24h are deleted.
3.  Stale lock sweep — `perflocale_job_lock_*` and `perflocale_type_lock_*` rows with past expiry are deleted.

### Resume Surviving Jobs

```bash
wp perflocale jobs resume
```

Manually trigger the post-reactivation resume sweep that normally runs automatically on activation. Walks the active-jobs index, finds `queued`/`running` rows that have no scheduled worker event, and re-enqueues each one. Useful if the auto-scheduled `perflocale_resume_jobs` cron event was lost (e.g. `DISABLE_WP_CRON` + no external trigger between activate and the operator noticing). Reports the count re-enqueued.

### CLI runs synchronously — admin honors thresholds

The **Background Thresholds** setting in _Settings → Performance_ only gates **admin-triggered** operations: when an operator clicks Scan, Import, Migrate, etc., or when an external client hits the REST endpoint, the dispatcher compares the work size against the threshold and routes large operations through the queue.

CLI commands deliberately bypass that gate and run the work **inline in the foreground**, regardless of size. This matches Unix conventions for command-line tools: progress streams to stdout, errors stream to stderr, exit code reflects success, and chained scripts (`wp ... && next-step`) behave as expected. Deploy scripts, CI/CD pipelines, and ssh-only servers all rely on this synchronous behavior.

Operations affected: `strings scan`, `translate`, `export`, `import`, `po-import`, `migrate <plugin>`. They will not queue jobs even on very large workloads — you'll see the work happen live and the command will return when it's done. The one explicit opt-out is `translate --all --async`, which dispatches a resumable `site_translate` job and returns immediately.

If you need to dispatch a large operation through the queue from a CLI context (e.g. a server cron that should kick off a job and exit immediately so it doesn't tie up the cron worker), use the dispatcher directly:

```bash
wp eval '\PerfLocale\Background\Dispatcher::dispatch(
    new \PerfLocale\Background\Jobs\BulkTranslateJob(),
    [ "source_ids" => [ 1, 2, 3 ], "target_lang_ids" => [ 2 ] ]
);'
```

That returns a job UUID immediately and exits; the queued job runs on the next worker tick (WP-Cron or Action Scheduler, whichever is active).

## Circuit Breakers

Inspect and manage PerfLocale's circuit breakers (MT providers, webhooks, FX APIs, geo-IP services). Full subsystem reference: [Reliability & Circuit Breakers](https://perflocale.com/docs/reliability/).

### List Breakers

```bash
wp perflocale breakers list [--format=<format>]
```

**Options:**

-   `--format` — `table` (default), `json`, `csv`, `yaml`, `count`. Machine-readable formats always emit valid parseable output, even when no breakers are tripped.

**Examples:**

```bash
$ wp perflocale breakers list
Success: No active breakers — system healthy.

$ wp perflocale breakers list --format=json | jq '.[] | select(.state=="open") | .key'
"mt_deepl"
"webhook_550e8400-e29b"

$ wp perflocale breakers list --format=count
0
```

### Status of One Breaker

```bash
wp perflocale breakers status <key> [--format=<format>]
```

Returns the full state (state, failures, reason, first/last/opened timestamps, cooldown remaining) for a single breaker. Returns the initial "closed" shape if the key has never tripped.

```bash
$ wp perflocale breakers status mt_deepl
+---------------------+---------------------+
| field               | value               |
+---------------------+---------------------+
| key                 | mt_deepl            |
| state               | open                |
| failures            | 5                   |
| reason              | 401_invalid_key     |
| opened_at           | 2026-05-26 10:42:18 |
| cooldown_remaining  | 271s                |
+---------------------+---------------------+
```

### Reset a Breaker

```bash
wp perflocale breakers reset <key>
wp perflocale breakers reset --all
```

Force-closes one breaker (or all of them) immediately. The next call to the underlying service is allowed through; subsequent failures will re-trip the breaker on the normal threshold. Useful when an operator has fixed the upstream problem (e.g. rotated an API key) and doesn't want to wait the full cooldown.

```bash
$ wp perflocale breakers reset mt_deepl
Success: Breaker 'mt_deepl' was OPEN and is now closed.

$ wp perflocale breakers reset --all
Success: Reset 3 breaker(s).
```

## Scripting Tips

### Suppress Confirmation Prompts

Use `--yes` to skip all confirmation prompts (useful in scripts and CI):

```bash
wp perflocale languages delete fr --yes
wp perflocale translations delete 42 --lang=fr --yes
```

### Combine with WordPress CLI

```
# Translate all published pages to German
wp perflocale translate --all --to=de --post-type=page --skip-existing

# Check health and fix issues
wp perflocale health-check --fix

# Full maintenance routine
wp perflocale cache flush && wp perflocale slugs backfill && wp perflocale health-check --fix
```

### JSON Output for Parsing

```
# Get languages as JSON for scripting
wp perflocale languages list --format=json | jq '.[].Slug'

# Get translation status as JSON
wp perflocale status --format=json | jq '.[] | select(.Published < .Total)'
```
