WarmupRamp
\Benecaster\Email\Warmup\WarmupRamp
Paces a new sending address. While a From domain has little recent sending history, the ramp limits how many standard-priority emails it sends per day and raises the limit each sending day. The email queue fetches the batch that Emails per hour allows and then asks the ramp how many of those rows may go; the rest stay pending. Emails per hour is the ceiling and the ramp sits beneath it.
On plain host mail a domain starts at 50 on its first sending day and doubles each sending day to a hard 2,400 a day, whatever Emails per hour says. With a mail service detected it starts at 500 and doubles to the configured rate. Only days that actually send count. A domain that sends nothing for 30 days moves two steps back down its ladder and climbs again, which takes three sending days. High-priority email (feed URL resets, password resets, security alerts, mail to admins) is exempt and not counted.
The ramp is open loop. Benecaster has no bounce or placement feedback, so it reads only the install’s own sending history and setup. There is no filter to change it. The full-rate override on Settings → Email is honoured only while a mail service is detected. Add-ons read the ramp through describe(), posture() and capacity_over_next_days(); get it from the container.
Constructor Dependencies
| Type | Description |
|---|---|
?\Benecaster\Email\Warmup\WarmupState |
Optional, defaulted. Per-domain sending history. |
?\Benecaster\Email\Warmup\PostureDetector |
Optional, defaulted. Whether a mail service handles mail, and SPF/DMARC. |
?\Benecaster\Admin\DebugLog |
Optional, defaulted. Records when the ramp held mail back, at info level. |
Methods
| Method | Visibility | Since | Description |
|---|---|---|---|
allowed_sends_today( string $domain ): int |
Public | — | The whole of today's allowance for the domain: the lower of its ramp step and its ceiling. Not what is left of it; use remaining_today() for that. |
remaining_today( string $domain ): int |
Public | — | How many more emails the domain may send today. |
is_warm( string $domain ): bool |
Public | — | True once the domain has reached its ceiling and has had a sending day there without being held back. A day counts even when the queue ran dry, so a show that sends a few emails a day still graduates. A cooled domain is not warm. |
capacity_over_next_days( int $messages, string $domain = '', int $max_days = 365 ): array |
Public | — | Projects when $messages enqueued now would finish, walking the ramp forward the way it will advance. Returns days, finish_day (Y-m-d, UTC), per_day (day, allowance, sends) and complete, which is false when $max_days ran out first. It is a best case, because WP-Cron fires only on traffic, and it counts what the domain has already sent today. An empty $domain means the site's From domain. See the recipe show-an-honest-finish-date. |
posture( string $domain = '' ): SendingPosture |
Public | — | The sending-setup reading for a domain (the site's From domain when empty). Reuse it rather than doing your own DNS lookup. |
describe( string $domain = '' ): array |
Public | — | Everything a screen needs in one call: the posture fields plus sending_days (days that actually sent), first_sent_on and days_since_first_send (the sending age, a different number), allowed_today, remaining_today, ceiling_per_day, is_warm, override_available and override_active. This is the warmup block of GET /email-settings. |
record_tick( string $domain, int $sent, int $wanted ): void |
Public | — | Called by the email queue each tick with what it sent and what it would have sent without the ramp. The difference is how the ramp knows it held mail back. Not for add-ons. |
Constants
| Name | Value | Description |
|---|---|---|
HOST_FIRST_DAY |
50 |
First sending day's allowance on plain host mail. |
SERVICE_FIRST_DAY |
500 |
First sending day's allowance with a mail service detected. |
HOST_DAILY_CEILING |
2400 |
The most plain host mail sends in a day, whatever Emails per hour says. |
COOL_STEPS_BACK |
2 |
Steps down its own ladder a domain drops after 30 days without sending. |
OPTION_OVERRIDE |
'benecaster_email_warmup_override' |
The full-rate override switch. Honoured only with a mail service detected. |
Notes
Don't estimate a send's duration by dividing by Emails per hour. On a new or cooled domain that promises a date the queue can't meet; use capacity_over_next_days().