Summary
The notification dispatcher decides per batch whether to send immediately (wp_mail() / $sms->SendSMS() / APNs/FCM directly) or to queue for cron processing. Queueing kicks in for batches of >10 messages when the global mam_notification_use_cron option is on.
mail-cron-manager (includes/mail-cron-manager/) owns the queue tables and the cron processor.
Queueing decision
$use_cron_if_available = count( $messages ) > 10;
$use_global_cron = get_option( 'mam_notification_use_cron' ) == 1;
$use_cron = $use_cron_if_available && $use_global_cron;
Both conditions must be true. A 5-message batch always sends immediately. A 50-message batch on a site with cron disabled also sends immediately (and likely overruns PHP’s request timeout — turn cron on for any site with regular bulk sends).
Queue tables
| Table | Channels | Owner repository |
|---|---|---|
wp_mam_mail_queue |
MAM_Mail_Queue_Repository |
|
wp_mam_mail_attachments |
Email attachments | MAM_Mail_Attachments_Repository |
wp_mam_sms_queue |
SMS + PN (unified, channel flag) | MAM_Sms_Queue_Repository |
All three were renamed from wp_tsl_* in PR #31. Frozen — do not rename in place.
The wp_mam_sms_queue row carries a flag indicating channel: send_text=1 for SMS, send_pn=1 for push. A single row with both flags isn’t supported — fire one row per channel.
Cron processor
mam_cron_mail::mail_cron() (includes/mail-cron-manager/mam-mail-manager.php):
- Pulls a batch of 50 from
wp_mam_mail_queue - Sends each via
wp_mail(); success → mark sent, failure → increment retry count - Pulls a batch of 20 from
wp_mam_sms_queuewheresent=0 - For each row, dispatches per the
send_text/send_pnflag - Updates
sentflag + retry count
Email retry: up to 3 attempts. After that the row is left as failed (audit-trail).
PN/SMS: no retry. A failed dispatch stays failed.
Cron registration
The mail-cron handler is registered with setcron-manager via mam_cron_manager:
add_filter( 'mam_cron_manager', array( $this, 'mam_cron_manager' ) );
mam_setcron_manager then pings the AJAX endpoint on every FastCron tick, which fires mam_mail_handler (registered as add_filter — anti-pattern noted; treat as fire-and-forget).
See FastCron integration.
Tuning batch sizes
The 50/20 split is hardcoded in mam_cron_mail::mail_cron(). To change for a high-volume site:
- Increase 50 (email) carefully —
wp_mail()is synchronous; large batches risk PHP timeout - Increase 20 (PN/SMS) carefully — APNs HTTP/2 connection isn’t pooled; high counts pay TCP setup per send
Either change is a code edit, not a setting.
Reads / writes
- Tables:
wp_mam_mail_queue,wp_mam_mail_attachments,wp_mam_sms_queue,wp_mam_notification_history - Options:
tsl_mam_mail_manager,mam_notification_use_cron - Hooks:
mam_mail_handler(cron tick),wp_mail_failed,wp_mail_from,wp_mail_from_name
Gotchas
mam_mail_handleris registered asadd_filtereven though it’s effectively an action — anti-pattern preserved for return-value compat with older callers.- No partial-failure retry semantics across channels. If a row’s email succeeds and SMS fails, the SMS portion is lost.
- The shared
wp_mam_sms_queuefor PN+SMS means a sustained PN load slows SMS draining and vice versa. Heavy senders should consider splitting via custom processors. - Cron disabled = synchronous everything. A site with
mam_notification_use_cron = 0and a 1000-message custom-notification job will block the request that triggered it.
Related articles
- Notifications overview
- Notification channels: email, SMS, push
- FastCron integration
- Hook: mam_cron_manager
- Frozen public contracts reference
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 |
