3.3 KiB
3.3 KiB
Warmup Recipes
Four recipes control how many emails the primary receives/sends per day over the campaign duration.
Global constraints (all recipes)
| Parameter | Default | Min | Max |
|---|---|---|---|
| Duration | 30 days | 14 | 45 |
| Min emails/day | 1 | 1 | — |
| Max emails/day | 40 | — | 50 |
| Reply rate | 30% | 10% | 45% |
| Volume change cap | +20% / 48h | — | Industry best practice |
1. Grow — Progressive (recommended)
Use when: New domain or cold mailbox. Safest default.
Behavior
- Start at
minEmailsPerDay(default 1) on day 1 - Increase daily toward
maxEmailsPerDayoverdurationDays - Never increase more than 20% vs prior 48h average
- After reaching max, hold flat until campaign end
- Optionally continue background warmup post-campaign at 20% of max
Algorithm (pseudocode)
totalGrowthDays = durationDays * 0.7 // reach max by ~70% of campaign
dailyIncrement = (maxEmails - minEmails) / totalGrowthDays
for day in 1..durationDays:
target = minEmails + floor(dailyIncrement * min(day, totalGrowthDays))
target = min(target, maxEmails)
target = cap48hIncrease(previousTargets, target, 0.20)
schedule[day] = target
Example (30 days, min=1, max=40)
| Day | Planned sends |
|---|---|
| 1 | 1 |
| 7 | ~8 |
| 14 | ~18 |
| 21 | ~30 |
| 24+ | 40 |
2. Flat
Use when: Mailbox already warm; maintain reputation during live outreach.
Behavior
- Constant
maxEmailsPerDayevery day - No ramp
- Same reply rate and rescue rules
schedule[day] = maxEmailsPerDay // for all days
3. Randomized
Use when: Experimentation; avoid perfectly predictable patterns.
Behavior
- Daily volume random within
[minEmailsPerDay, maxEmailsPerDay] - Weighted toward middle of range (normal distribution)
- 48h spike cap still applies
- Seed per campaign for reproducibility (debugging)
schedule[day] = randomInt(min, max, seed=campaignId+day)
schedule[day] = cap48hIncrease(...)
4. Custom
Use when: Expert operators want per-day control.
Behavior
- User defines array:
[{ day: 1, sends: 2 }, { day: 2, sends: 5 }, ...] - Validate: each value within [min, max], length ≤ durationDays
- Missing days: hold last defined value or interpolate (configurable)
- UI: spreadsheet-style editor + import CSV
Recipe selection API (future)
{
"recipe": "grow",
"durationDays": 30,
"minEmailsPerDay": 1,
"maxEmailsPerDay": 40,
"replyRatePercent": 30
}
Dispatcher integration
- Load active campaigns
- For each campaign, read
DailySchedulefor today - If
actualSends < plannedSends, schedule next send slot with jitter - Pick satellite from
CampaignSatellite(weighted random) - Primary is always receiver for satellite→primary sends; primary may send replies back
Post-campaign
| Mode | Behavior |
|---|---|
| Complete | Stop sends; mark campaign completed |
| Maintenance | Switch to Flat at 20% of max (recommended) |
| Pause | Operator pause; resume later |
UI copy (recommended labels)
| Recipe | Label | Subtitle |
|---|---|---|
| grow | Grow | Progressive ramp — recommended for new mailboxes |
| flat | Flat | Steady volume — for already-warm inboxes |
| randomized | Randomized | Variable daily volume — for testing |
| custom | Custom | Define your own day-by-day schedule |