View Categories

How the Background Worker Runs

Why “scheduled” and “ran” are different things, what one worker pass actually does, and why the heartbeat is the only reading that proves anything.


It Is a Scheduled Callback, Not a Process #

The worker is not a daemon sitting in memory waiting for the clock. It is a WordPress scheduled event that runs when WordPress is invoked and the event is due.

That has three consequences:

  1. WordPress must be invoked. Visits normally spawn WP-Cron when events are due, unless automatic spawning is disabled. With no visits and no server cron, due events simply wait.
  2. A server cron helps, independently of traffic. Running it every minute is fine — it only executes events that are actually due, and this plugin’s event comes due every 15 minutes.
  3. Opening wp-cron.php runs due events only. An HTTP 200 is not proof this worker executed, because its event may not have been due.

Requested, Registered, Observed #

Three separate readings, and they can disagree. That’s why all three are displayed.

Reading What it is What it proves
Requested interval What the plugin asks for (900 s default, 60 s floor) Intent
Registered interval What WordPress has on its schedule Registration succeeded
Last heartbeat When a check last completed PHP actually executed

Only the heartbeat is evidence. A perfectly registered 15-minute event cannot compensate for a server that invokes WordPress once a day.


The Health Threshold #

Attention is raised when the heartbeat is older than two requested intervals — 30 minutes at the default.

  • A new installation gets a two-interval grace period.
  • A heartbeat is recorded even when nothing was due. A successful idle check is still a heartbeat.
  • Recovery is automatic: a completed check restores health without anyone dismissing anything.

This is not WordPress’s browser “Heartbeat API”. Same word, unrelated mechanism.


What One Pass Does #

Step Detail
Claim Takes up to 50 due rows, each with an atomic per-request claim so nothing double-submits.
Process For each: prepare the payload, evaluate conditional logic, submit, record the attempt, calculate the next target.
Budget Stops acquiring additional work when its time budget runs out. Remaining work waits for the next pass.
Unlock Guaranteed lock cleanup, even on failure. Claims older than 30 minutes are recoverable.
Heartbeat Recorded at the end, whether or not anything was due.

The add-on log records each pass: start (with the cron-event timestamp and the previous heartbeat) and finish (with how many series were claimed, succeeded, failed or skipped, how long it took, how many locks were recovered, and how much work was still queued).


Registration and Repair #

Registration checks the recurrence, the effective interval and any duplicate events. Errors surface in worker health.

Behaviour Why
Overdue events are preserved So WordPress can still execute them. Lateness does not invalidate a correctly configured event.
Interval changes are detected An event registered at the wrong interval is repaired.
Repairs are recorded With the previous timestamp, interval and event count, so a change is explainable afterwards.

The most recent worker incident retains its detection state and recovery time, so a “recovered” notice still makes sense later. Incidents from before this telemetry existed can’t be reconstructed from the current event alone.


The Maintenance Scan #

A second, slower event runs twice a day by default and:

  • checks worker health,
  • recovers stale claims,
  • prunes expired operational history.

It never submits a form, and it never independently retries a failed row.


Tuning #

Filter Default Purpose
rfsfgf_worker_interval 900 s How often the worker runs. One-minute floor.
rfsfgf_failed_check_interval 43,200 s How often the maintenance scan runs.
rfsfgf_failed_check_first_run UTC timestamp anchoring the maintenance event’s first run.
rfsfgf_missed_run_grace 2 × worker interval How late an occurrence must be before a skipping feed calls it missed. Never below one interval.

Lowering the worker interval only helps if your host invokes WordPress at least that often. The health threshold follows automatically, since “late” is defined as two intervals.


The Realistic Expectation #

With a healthy worker, an occurrence starts between its target and roughly 15 minutes afterwards, subject to request duration.

That is the contract. If you need tighter timing, shorten the interval and make your host invoke WordPress at least that often — and understand that a shared host may not cooperate.

If you need second-level precision, this is the wrong tool.