CLI Commands¶
v3 ships five Spark commands, all in the Jobs group. Run them with
php spark <command>. This page is the complete reference: arguments, options, examples, exit codes
and graceful-shutdown behaviour.
| Command | Purpose |
|---|---|
jobs:queue:work |
Run a queue worker (long-running or one-shot). |
jobs:queue:reap |
Reclaim messages whose visibility timeout expired (crashed-worker recovery). |
jobs:cronjob:run |
Evaluate the schedule and run/enqueue due jobs (wire to system cron every minute). |
jobs:queue:purge |
Maintenance: delete completed/failed rows from the database backend table. |
jobs:publish |
Publish the Config\Jobs file into the application namespace for customization. |
Note — retired commands. The v1 commands
jobs:queue:run,jobs:redis:reap-stuck,jobs:cronjob:enable,jobs:cronjob:disable,jobs:cronjob:list,jobs:cronjob:historyandjobs:healthwere removed in v3.0 and no longer exist as commands. Usejobs:queue:workinstead ofjobs:queue:run, andjobs:queue:reapinstead ofjobs:redis:reap-stuck. The v1 global on/off mechanism (thejobs_activecache flag, set byjobs:cronjob:enable/disable) is gone too:jobs:cronjob:runnow evaluates the schedule on every invocation, out of the box. Per-job enable/disable is a property on the definition (enabled()/disable()— see Scheduling). See the Migration guide for the full mapping.
jobs:queue:work¶
Starts a queue worker. It pulls messages from the configured backend and drives each one through the worker pipeline:
| Argument / Option | Description |
|---|---|
queue |
Queue name. Defaults to the first queue in Config\Jobs::$queues. |
--once |
Process a single cycle and exit (equivalent to --max 1). |
--max N |
Process at most N cycles then exit (0 / omitted = unlimited / run forever). |
--backend name |
Override the configured default backend (Config\Jobs::$worker). |
Behaviour¶
- Graceful shutdown. On
SIGTERM/SIGINT(POSIX, requires thepcntlextension) the worker sets a stop flag, finishes the current cycle, printsgraceful shutdown complete.and exits. A job in flight is never aborted mid-execution — the worker simply stops fetching the next one. On platforms withoutpcntl(e.g. Windows) signal handling is skipped; bound the run with--once/--maxor stop the process externally. - Circuit breaker. Backend errors are tracked per queue. After
Config\Jobs::$circuitBreakerThresholdconsecutive failures the circuit opens and the worker skips attempts forConfig\Jobs::$circuitBreakerCooldownseconds (then probes once). Reported as[Circuit Open] .... - Rate limiting. Per-queue caps from
Config\Jobs::$queueRateLimits(jobs/minute) are honoured; a throttled cycle reports[Rate Limited] .... - Idle polling. When a cycle yields nothing actionable (
empty,rate-limited,circuit-open,error) the worker sleepsmax(1, Config\Jobs::$pollInterval)seconds before the next cycle.
Each non-empty cycle prints a line like [acked] reports (attempt 1) or
[requeued] reports (attempt 2) - <error>.
Examples¶
# Long-running worker on the first configured queue, default backend
php spark jobs:queue:work
# Named queue, single cycle then exit (cron-friendly / one-shot)
php spark jobs:queue:work reports --once
# Bound to 500 cycles on the redis backend
php spark jobs:queue:work emails --max 500 --backend redis
Note: For production, run a long-running worker under a process supervisor (systemd or Supervisor) so it is restarted on exit. For cron-style processing use
--onceor--max N. See Operations for full supervisor/systemd examples.
Exit codes¶
| Code | Meaning |
|---|---|
0 (SUCCESS) |
The worker stopped normally (reached --once/--max, or shut down gracefully). |
The command always returns SUCCESS on a clean stop; transient backend errors are handled
internally by the circuit breaker rather than aborting the process.
jobs:queue:reap¶
Reclaims queue messages whose visibility timeout expired (a worker crashed or stalled between
fetch() and ack()), returning them to the ready state via QueueBackend::reapExpired().
| Argument / Option | Description |
|---|---|
queue |
Queue name to reap (required). |
--backend name |
Override the configured default backend. |
The visibility timeout applied is Config\Jobs::$redisProcessingVisibilityTimeout when the backend
is redis, and Config\Jobs::$databaseVisibilityTimeout otherwise (both default to 300 seconds).
Needed for the database and redis backends. beanstalk and serviceBus recover
in-flight messages natively when their reservation/lock expires, so reaping them is a harmless no-op
(returns 0). Run it periodically via system cron:
# Every minute, recover stranded messages on the 'reports' queue
* * * * * cd /path/to/project && php spark jobs:queue:reap reports >> /dev/null 2>&1
# Explicit backend
php spark jobs:queue:reap emails --backend redis
On success it prints Reaped N expired message(s) from queue '<queue>'.
Exit codes¶
| Code | Meaning |
|---|---|
0 (SUCCESS) |
Reaping completed (zero or more messages recovered). |
1 (FAILURE) |
No queue name was provided. |
jobs:cronjob:run¶
Evaluates the scheduled definitions registered in Config\Jobs::init() and acts on the due ones —
enqueuing those that declare a queue() and running inline those that do not. Wire it to
system cron to run every minute.
| Option | Description |
|---|---|
-testTime <iso> |
Evaluate the schedule against a frozen ISO datetime (deterministic dry-run / testing). |
# Run due jobs now
php spark jobs:cronjob:run
# Crontab: every minute
* * * * * cd /path/to/project && php spark jobs:cronjob:run >> /dev/null 2>&1
# Evaluate against a frozen time (does not change the system clock; only affects which jobs are "due")
php spark jobs:cronjob:run -testTime "2026-06-03 02:00:00"
See Scheduling for registering jobs, frequency helpers, enabled()/disable(),
environments, dependencies and the queued-vs-inline rule.
Behaviour¶
- Evaluates the schedule on every run. The command loads
Config\Jobs::init(), builds theScheduler, and evaluates every registered definition against the current minute on each invocation — out of the box, with no global flag to enable first. Govern which jobs run on a per-job basis withenabled()/disable()andenvironments()on the definition (see Scheduling).
Exit codes¶
| Code | Meaning |
|---|---|
0 (SUCCESS) |
The run completed (due jobs were enqueued / run inline). |
jobs:queue:purge¶
Deletes completed and/or failed rows from the database backend table (Config\Jobs::$database['table'],
default queues). Essential maintenance, since the table grows indefinitely otherwise (acked rows
become completed, abandoned rows become failed).
| Option | Description |
|---|---|
--status |
completed, failed, or all. Default completed. (all matches both completed and failed.) |
--queue |
Restrict to a single queue. |
--before |
Only rows created before this date — any strtotime()-parseable value (e.g. "2026-01-01" or "-7 days"). |
--dry-run |
Show the matching count without deleting. |
--force |
Skip the interactive confirmation prompt. |
# Preview how many completed jobs would be removed (no deletion)
php spark jobs:queue:purge --status completed --dry-run
# Purge failed jobs older than 7 days in the 'reports' queue, no prompt
php spark jobs:queue:purge --status failed --queue reports --before "-7 days" --force
# Purge everything terminal (completed + failed) across all queues, with confirmation prompt
php spark jobs:queue:purge --status all
Behaviour:
- An invalid
--statusvalue, or an unparseable--beforevalue, prints an error and exits without deleting. - When no rows match, it prints
No matching jobs found to purge.and exits. - Without
--forceit asksAre you sure you want to delete these records?and cancels unless you answery.
Warning:
jobs:queue:purgeonly operates on the database backend table. It does not touch redis keys, beanstalkd tubes or Service Bus entities. It targets terminal rows (completed,failed) — it never deletespendingorin_progressrows, so an in-flight or queued job is safe.Note: This command extends
CodeIgniter\CLI\BaseCommandand returnsvoid(no explicit exit code); it terminates with the default success status. Schedule it from system cron for routine maintenance — see Operations.
jobs:publish¶
Copies the package's Config\Jobs file into your application's namespace (app/Config/Jobs.php) so
you can customize it. The published class extends Daycry\Jobs\Config\Jobs, so it inherits every
default and only overrides what you change. Run it once after installing the package.
This command takes no arguments or options. It prompts Publish Config file? (y/n); answer y
to write the file. On success it prints the created path (e.g. created: Config/Jobs.php).
Note: Like
jobs:queue:purge, this command returnsvoid(no explicit exit code) and terminates with the default success status. See Configuration for every setting you can override in the published file.
See also¶
- Queues & Backends — the worker pipeline, lease semantics and backends.
- Scheduling — registering and evaluating cron jobs.
- Operations — supervisors, the reaper, scaling and observability.
- Configuration — every worker, reaper and backend setting referenced above.