IP Warmup by ISP — Per-Receiver Ramp Strategy in AcelleMail

Gmail accepts new IPs faster than Microsoft. Yahoo is slower than both. Apple iCloud is the strictest. A uniform warmup misses these per-receiver curves. This guide segments your warmup by recipient ISP for faster reputation building.

Why per-ISP warmup beats uniform warmup

Receiving servers weight your reputation differently. Send 50k emails on Day 14 of warmup:

  • Gmail may accept all 50k inbox if engagement is high (Gmail rewards engagement fast)
  • Outlook treats it as a spike; routes 30% to Junk (Microsoft is volume-sensitive)
  • Yahoo sees an unfamiliar pattern; routes 60% to Junk (Yahoo is conservative)
  • iCloud silently drops 40% (Apple is strictest, gives least feedback)

A uniform warmup curve optimized for Gmail under-warms Outlook/Yahoo/iCloud. A uniform curve optimized for the slowest (iCloud) wastes Gmail's appetite. Per-ISP warmup matches each receiver's curve.

Per-ISP recommended curves

Day Gmail (% of full) Outlook Yahoo iCloud
1 5% (high engagement target) 1% 1% 0.5%
3 15% 3% 2% 1%
7 40% 10% 5% 3%
14 75% 30% 15% 8%
21 100% 60% 35% 20%
30 100% 90% 70% 50%
45 100% 100% 100% 100%

If your audience is 50% Gmail + 30% Outlook + 15% Yahoo + 5% iCloud (typical US mix), uniform warmup at Day 14 = 75% volume. Per-ISP at Day 14 = ~52% volume but ~85% inbox-placement across receivers, vs ~65% uniform. Net more delivered.

Implementation in AcelleMail

Tag subscribers by ISP

The per-ISP segment lives in tags. Apply at import-time or via batch update:

-- Run once via tinker / migration to tag existing subscribers
UPDATE subscribers SET tags = JSON_ARRAY_APPEND(COALESCE(tags, JSON_ARRAY()), '$', 'isp:gmail')
  WHERE email REGEXP '@(gmail|googlemail)\.com$';
UPDATE subscribers SET tags = JSON_ARRAY_APPEND(COALESCE(tags, JSON_ARRAY()), '$', 'isp:outlook')
  WHERE email REGEXP '@(outlook|hotmail|live|msn)\.com$';
UPDATE subscribers SET tags = JSON_ARRAY_APPEND(COALESCE(tags, JSON_ARRAY()), '$', 'isp:yahoo')
  WHERE email REGEXP '@(yahoo|ymail|aol)\.com$';
UPDATE subscribers SET tags = JSON_ARRAY_APPEND(COALESCE(tags, JSON_ARRAY()), '$', 'isp:icloud')
  WHERE email REGEXP '@(icloud|me|mac)\.com$';

For ongoing imports, add the tag-by-ISP step to your import pipeline OR use AcelleMail's import wizard's tag-mapping feature.

Create per-ISP segments

In your list, Segments → New segment with rule:

Tag contains 'isp:gmail'

Repeat for outlook, yahoo, icloud.

Daily warmup campaign per ISP

Day 7 example: send to gmail-segment at 40% volume.

  1. New campaign → recipients = gmail segment only
  2. Sending limit = the day's gmail % × your full-volume target
  3. Launch

Repeat with smaller volumes per outlook + yahoo + icloud segments same day.

Open the sending-server detail

In AcelleMail's sidebar, click Sending → Sending servers. The list shows every server connected to this account with its status chip, sending limit, and last activity:

Customer sending-server list

Click into the row you want to configure. The detail page surfaces Connection settings (host / credentials), Configuration (server name, default from, sending limit, bounce + FBL handler), and the Test connection / Send test email buttons in the toolbar:

Server detail — Connection + Configuration

Where the throttle lives

Same sending-server detail → Configuration section. The Sending limit dropdown caps how many emails AcelleMail will hand to this server per unit of time (per minute / hour / day):

Sending limit dropdown — 5,000 emails per 1 hour

AcelleMail enforces the limit globally — when the rolling-window counter hits the cap, the queue holds back until the window slides. No throttling code in your campaigns; configure once per server.

Adjust the sending-limit-per-hour per-day per the curves above. As each ISP's reputation grows (verify via Postmaster Tools / SNDS / AcelleMail's per-domain bounce mining), step up that ISP's volume independently.

Use a warmup strategy preset

AcelleMail's admin Warmup Strategies screen ships with 4 preset curves you can attach per-server — Cautious, Balanced (default), Aggressive, Long-Haul:

Warmup strategies presets

For per-ISP warmup, the safest pattern: attach Long-Haul to servers targeting Microsoft/Yahoo/iCloud (conservative ISPs), Balanced to gmail-targeted servers. Mix by which ISP-tagged segment the server is reserved for.

Per-ISP signal sources

ISP Reputation source Daily-check frequency
Gmail Google Postmaster Tools Daily during warmup; weekly after
Outlook (Microsoft) SNDS (Smart Network Data Services) Daily during warmup; weekly after
Yahoo No native postmaster — use AcelleMail bounce log per-recipient Daily during warmup
iCloud (Apple) No native postmaster — use bounce log per-recipient Daily during warmup
B2B (Proofpoint / Mimecast / Cisco) Direct relationships, OR your bounce log patterns Investigate per-domain on bounce

For per-ISP AcelleMail-side mining, query your bounce_logs table:

SELECT
  SUBSTRING_INDEX(SUBSTRING_INDEX(email, '@', -1), '.', -2) AS domain,
  COUNT(*) AS bounces,
  SUM(CASE WHEN bounce_type = 'hard' THEN 1 ELSE 0 END) AS hard
FROM bounce_logs
WHERE created_at >= NOW() - INTERVAL 7 DAY
GROUP BY domain
ORDER BY bounces DESC
LIMIT 25

(Remember: prefix your table name with DB_TABLES_PREFIX if you have one — bounce_logsacelle_bounce_logs in some installs.)

If yahoo.com bounces are 40% of all bounces but only 15% of your list, Yahoo-specific block. Pause yahoo segment; investigate at AcelleMail's Yahoo-postmaster-program contact.

Common UI signals + fixes

Symptom Likely cause UI fix
Tag-based segment shows fewer subscribers than expected Tag not applied at import — back-fill via SQL or re-import Re-tag via the SQL pattern above, or Audience → list → Import → Update mode
Gmail volume at Day 7 — many soft bounces Quota too aggressive Hold gmail segment at current day; don't ramp tomorrow
Outlook segment fully delivered, Yahoo segment 50% bounce Yahoo-specific reputation hit Pause yahoo segment for 5 days; resume at lower volume
Per-ISP campaign report missing breakdown AcelleMail's per-domain stats need a custom report Use campaigns/{uid}/tracking-log/listing filtered by domain
Setting up 4 separate campaigns each day feels manual Automate via API + cron Schedule campaigns via API; pull tag-based segments dynamically
Advanced: automated per-ISP volume orchestration via API

For high-volume installs, manual per-ISP scheduling is tedious. Automate via API + cron.

Daily orchestration script:

#!/bin/bash
# Run at 03:00 daily. Auto-launches 4 per-ISP warmup campaigns based on
# current warmup day + per-ISP signal health.

DAY_OF_WARMUP=$1  # Pass current day as arg
ACELLE_TOKEN="..."
LIST_UID="..."
TEMPLATE_UID="..."

# Per-ISP daily volumes (from the curve table above)
declare -A GMAIL_VOL=([1]=5000 [3]=15000 [7]=40000 [14]=75000)
declare -A OUTLOOK_VOL=([1]=1000 [3]=3000 [7]=10000 [14]=30000)
declare -A YAHOO_VOL=([1]=1000 [3]=2000 [7]=5000 [14]=15000)
declare -A ICLOUD_VOL=([1]=500 [3]=1000 [7]=3000 [14]=8000)

for isp in gmail outlook yahoo icloud; do
  case $isp in
    gmail)   vol=${GMAIL_VOL[$DAY_OF_WARMUP]} ;;
    outlook) vol=${OUTLOOK_VOL[$DAY_OF_WARMUP]} ;;
    yahoo)   vol=${YAHOO_VOL[$DAY_OF_WARMUP]} ;;
    icloud)  vol=${ICLOUD_VOL[$DAY_OF_WARMUP]} ;;
  esac

  # Check yesterday's per-ISP signal — if bounce rate creeping up, skip today
  yesterday_bounce=$(curl -sH "Authorization: Bearer $ACELLE_TOKEN" \
    "https://acellemail.com/api/v1/campaigns/recent?tag=isp:$isp&days=1" \
    | jq '.aggregate.bounce_rate')

  if (( $(echo "$yesterday_bounce > 0.04" | bc -l) )); then
    echo "Skip $isp today — yesterday bounce $yesterday_bounce"
    continue
  fi

  # Launch today's per-ISP warmup campaign
  curl -X POST "https://acellemail.com/api/v1/campaigns" \
    -H "Authorization: Bearer $ACELLE_TOKEN" \
    -d "{
      \"name\": \"Warmup Day $DAY_OF_WARMUP — $isp\",
      \"list_uid\": \"$LIST_UID\",
      \"template_uid\": \"$TEMPLATE_UID\",
      \"segment_tags\": [\"isp:$isp\", \"engaged-last-7d\"],
      \"sending_limit\": $vol,
      \"schedule\": \"now\"
    }"
done

Signal-gated step-up:

Replace the manual day-counter with a signal-driven gate:

GATE: bounce <2% AND complaint <0.1% AND open >25% in last 24h for THIS isp
  YES → step up volume 20%
  NO  → hold today's volume; if 3 consecutive hold-days, cut volume 25%

Self-tuning warmup. Run as a daily cron. Reduces manual intervention; surfaces problems via alerts rather than silent under-volume.

Multi-tenant warmup orchestration:

For SaaS operators, each tenant gets their own warmup. The orchestrator loops over active tenants:

for each tenant:
  for each (tenant, ISP) pair:
    fetch current warmup day
    fetch per-ISP signals
    launch / skip / hold today's campaign
    increment tenant.isp.warmup_day on success

Tooling note — for very large warmups (>10M emails/day) consider the dedicated tools like Mailosaur or Litmus's deliverability monitoring as additional signals. Per-ISP reputation tracking at scale is a discipline of its own.

Related articles

13 bình luận

8 bình luận

  1. nadia.r.cl
    For very low-volume senders (< 5k/month), oes warmup even matter? Or just send and let the provider's shared pool absorb the trickle?
  2. m.schmidt78
    For very low-volume senders (< 5k/month), does warmup even matter? Or just send and let the provider's shared pool absorb the trickle?
    1. admin
      there's no built-in way today. Two workarounds: (1) cron + custom script polling the API every N minutes, (2) webhook-driven if your event source supports it. Most operators go with #2. :)
    2. admin (đã chỉnh sửa)
      Short answer: yes — set the MySQL session variable from your worker's .env on boot and you'll get the longer timeout per connection. We'll add an explicit recipe in the next refresh.
  3. emma.whitaker
    We hit a Spamhaus listing once. Self-service delisting was actually fast (< 24h) but the reputation recovery took weeks. Not the listing itself that hurt — the user complaints that caused it...
    1. admin (đã chỉnh sửa)
      Useful field report. The 'kill -9 was the only fix' edge case is rare but real — well note it as a fallback. tbh
  4. ahmed.hassan.c…
    Bookmarked. Going to share with the team — we've been winging warmup and it shows in the numbers...
    1. admin
      glad it landed. drop suggestions in the comments and we'll incorporate them on the next refresh.
  5. danrey.dev
    we warmed up a dedicated ip last fall. the 2-week ramp this article describes is on the aggressive side — gmail in particular punishes anything faster than ~3-4 weeks. we did 4 weeks and had a clean ramp.
  6. jmorrison.itop…
    if you're warming a new IP after a known issue, consider seeding with transactional mail first (password resets, order confirmations). Higher engagement rate per send than marketing — helps the reputation ramp.
  7. hung.nguyen.it
    This is the clearest IP warmup schedule I've found. The volume table at the top is what I'm referencing daily.
  8. lucas.bernard.…
    Confirming the Postmaster Tools data lag — sometimes 48 hours, sometimes longer. Don't make decisions on a single day's data
    1. admin
      Thanks for the numbers. Worth pulling into a follow-up post on volume-tier sizing.

More in Sending & Deliverability