Summary
WordPress’s built-in wp-cron.php only fires when a request hits the site. Low-traffic sites miss scheduled events; high-priority work (SMS retries, push queue draining) stalls. mam-main delegates cron to FastCron — a third-party service that pings a known AJAX endpoint on a fixed schedule, decoupling cron from site traffic.
Implementation is in includes/setcron-manager/.
Components
| Class | Role |
|---|---|
mam_fastcron_api |
Wrapper around the FastCron REST API: create / enable / disable / list cron jobs |
mam_setcron_manager |
Orchestrates the AJAX cron processor; fires per-cron callbacks |
mam_setcron_manager_admin_settings |
Admin page — UI for the API token + per-cron toggles |
Cron_List |
WP_List_Table subclass — admin grid of registered crons (cron-list.php) |
How sibling plugins register crons
add_filter( 'mam_cron_manager', function ( array $crons ): array {
$crons[] = array(
'action' => 'my_plugin_nightly_sync', // hook id, fired via apply_filters()
'name' => 'Nightly Sync', // human label for the admin grid
'frequency' => '60', // interval in MINUTES
'run_at' => '0200', // optional daily time, HHMM (padded to 4)
);
return $crons;
} );
Each entry is an array with action (the hook id that gets fired), name (label), frequency (interval in minutes), and an optional run_at daily time. Schedules are not cron-expression syntax. The orchestrator collects entries from all subscribers; on each tick it walks the registered crons, and for each one whose stored next_run (kept in an option named after action) is overdue, it fires the hook and advances next_run by frequency minutes (or to the next run_at time).
AJAX endpoint
GET | POST /wp-admin/admin-ajax.php?action=mam_setcron_processor
Auth: both (logged-in + nopriv) — FastCron pings as an unauthenticated request.
This is the entry point FastCron pings on every tick. The handler:
- Resolves the active timezone (
wp_timezone_string()) - Walks the registered crons
- For each schedule that matches “now”, invokes
apply_filters( $cron_id, array() )
Per-cron callback dispatch
apply_filters( $action, array() ); // $action = sanitize_key( $cron['action'] )
Note: apply_filters (not do_action). The hook fired is the entry’s action value. The processor does use the return value — it merges last_run / next_run into it and stores the result in the option named after action — so a callback should return an array (return $data unchanged if you have nothing to persist).
Reads / writes
- Option
tsl-setting-setcron-api— FastCron API token (a value of'1'is treated as disabled) - Option
tsl-setting-setcron-id— FastCron job id once created wp_timezone_string()— for schedule evaluation
Common cron registrations
| Cron | Purpose | Subsystem |
|---|---|---|
mam_mail_handler |
Drain wp_mam_mail_queue and wp_mam_pn_text_queue |
mail-cron-manager |
mam_custom_notifications |
Scheduled custom notifications (registration currently commented out in source) | notifications-manager |
| (sibling-plugin specific) | Per-plugin scheduled work | various |
25+ subscribers across mam-suite-hold, mam-use-case, and the sibling plugins.
Gotchas
- API-token sentinel value
'1'means “feature disabled”. A real API token is a non-numeric string. Writing1as a token silently disables cron without an obvious error. - FastCron pings the public site URL — if the site is behind basic auth or IP allow-list, FastCron must be allow-listed.
- Per-cron callbacks use
apply_filters, notdo_action— and the return value is used: the processor writes it (pluslast_run/next_run) into the option named afteraction. Return an array (the passed-in one is fine) rather than a scalar ornull. - Time-zone handling for offsets like
+05:30falls back through twotimezone_name_from_abbrattempts (DST + non-DST). Failed lookups silently fall through to UTC. Use named timezones (e.g.,Asia/Kolkata) where possible. - Callbacks are dispatched serially per tick. A long-running callback can prevent later callbacks from running on the same tick.
Related articles
- Notification queue and cron
- Recipe: Register a scheduled cron task
- Hook: mam_cron_manager
Metadata
| Field | Value |
|---|---|
| Article type | Plugin Overview |
| Plugin slug | mam-main |
| Applies to plugin version | 2.1.11+ |
| Category | Plugin Reference |
| Audience | PHP developer |
| Last verified | 2026-05-02 |
