warmbox/docs/04-warmup-recipes.md

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

Use when: New domain or cold mailbox. Safest default.

Behavior

  • Start at minEmailsPerDay (default 1) on day 1
  • Increase daily toward maxEmailsPerDay over durationDays
  • 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 maxEmailsPerDay every 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

  1. Load active campaigns
  2. For each campaign, read DailySchedule for today
  3. If actualSends < plannedSends, schedule next send slot with jitter
  4. Pick satellite from CampaignSatellite (weighted random)
  5. 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
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