Multi-Server Rotation in AcelleMail — How the Dispatcher Picks

Once you have 2+ sending servers, the AcelleMail dispatcher distributes per-message across them. This guide explains the rotation logic, how to verify it in the admin pool, and how to override for deterministic routing.

How the dispatcher picks a server per message

When you launch a campaign with multiple servers in your plan's pool, AcelleMail's send-pipeline picks one server per message. The pick order:

  1. Filter by plan — only servers attached to the campaign owner's plan are candidates
  2. Filter by quota — servers that hit their daily/hourly cap drop out for this window
  3. Filter by warmup state — servers in active warmup get priority for low-volume sends and are skipped for high-volume burst sends
  4. Round-robin within remaining candidates — even distribution; no stickiness per recipient or per campaign

The pick happens at job-handler time (not at campaign-launch time). Mid-send, if one server hits quota or fails its health check, subsequent messages skip it automatically — no manual failover.

Verify the rotation in the admin pool

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

For pool-wide visibility, open the admin view:

Admin pool — total / active / inactive + per-type breakdown

The "Server types" bar shows the composition of your pool. The per-server row shows daily / hourly usage. After launching a campaign, refresh every few seconds — usage counters increment across multiple servers, confirming rotation is active.

Deterministic routing — when you need it

Round-robin is the right default. Some scenarios want deterministic routing:

Scenario Solution
Marketing on IP A, transactional on IP B Two Plans: "Marketing" attaches Server A only; "Transactional" attaches Server B only. Assign customers/campaigns to the right plan.
EU customers sent from EU server (GDPR data residency) Per-customer Plan assignment based on region tag
New IP being warmed — start at 10% traffic Per-server warmup config sets daily cap that grows automatically
Campaign with extra-strict deliverability requirements Attach to a Plan whose pool is a single high-reputation server

Setting it up via Sending Plans

In the admin sidebar Plans → [plan] → Sending Servers, attach the specific servers you want this plan's customers to use. Customers on this plan only see those servers; the dispatcher picks among them.

The admin server detail shows which plans each server is attached to:

Admin server detail — plan attachments visible

Common UI signals + fixes

Symptom Likely cause UI fix
All campaigns hit Server A, B sits idle Server B not attached to the plan, OR Server B's daily quota set to 0 Admin → Plan → Sending Servers (attach); OR Server B → Sending limit (raise from 0)
Server A usage hits 100% daily quota at noon Pool too small for daily volume Raise per-server quotas OR add a third server
Rotation seems uneven (60/40 split) One server is warming (lower quota) Expected — the dispatcher avoids overloading the warming server
Mid-campaign one server flatlines Health check failing — connection refused or auth error Open that server's detail → Test connection → fix the credentials/network
Campaign log shows "Used Server X" for ALL messages Single-server plan attached, OR all-but-one server disabled Confirm via Admin → Plan; enable additional servers in plan attachment

Distribution patterns over time

Healthy multi-server distribution over a 30-day window should look like:

Pattern What it means
33/33/34 across 3 servers Healthy round-robin, all servers similar quota + warmup state
80/15/5 across 3 servers One large + two warming. Expected during ramp-up.
60/40 across 2 servers Server B has a lower daily cap or recently warmed up. Adjust caps to align.
100/0 across 2 servers Server B disabled or out of the plan. Bug — fix.
Advanced: weighted rotation, sticky routing, and quota-orchestration patterns

AcelleMail's default round-robin is uniform. For non-uniform distribution patterns, the lever is per-server sending limit + how plans attach:

Weighted rotation via quota — to send 70% on Server A and 30% on Server B, set:

Server A sending_limit: 70,000/day
Server B sending_limit: 30,000/day

Pool dispatcher continues round-robin but Server B caps at 30k, after which only A receives more. Approximates a 70/30 weight at high volumes; can drift at low volumes due to round-robin.

Sticky routing per recipient — out of the box AcelleMail does NOT stick a recipient to a specific server. For sender-domain consistency (some receivers warm to a specific IP), the workaround is one-IP-per-tenant: create a separate Plan per tenant, each with a dedicated server. Operationally heavy; only worth it for high-stakes tenants.

Quota orchestration across vendors — for very high volume, the typical pattern is:

Tier 1 (highest reputation, lowest cost):  Amazon SES — 60% of volume
Tier 2 (mid reputation, growing):          Mailgun  — 25%
Tier 3 (newest IP, in warmup):             Postmark — 15%

Adjust quotas weekly as warmup-tier servers earn reputation. Auto-grow Postmark from 15% → 25% as bounce rate stays clean.

Automated rebalancing via API:

# Daily script: read per-server bounce rate, raise quota on clean + lower on dirty
for server_uid in $SERVER_UIDS; do
  br=$(curl -sH "Authorization: Bearer $ADMIN_TOKEN" \
    "https://acellemail.com/api/v1/admin/sending-servers/${server_uid}/stats" \
    | jq '.bounce_rate_last_24h')

  current=$(curl -sH "Authorization: Bearer $ADMIN_TOKEN" \
    "https://acellemail.com/api/v1/admin/sending-servers/${server_uid}" \
    | jq '.sending_limit')

  # If bounce rate < 1%, raise quota 10%; if > 3%, cut quota 25%
  new=$(python -c "
  br=$br; c=$current
  print(int(c*1.1) if br<0.01 else int(c*0.75) if br>0.03 else c)
  ")

  curl -X PATCH -H "Authorization: Bearer $ADMIN_TOKEN" \
    -d "{\"sending_limit\": $new}" \
    "https://acellemail.com/api/v1/admin/sending-servers/${server_uid}"
done

Run as a daily cron. Self-tuning pool that prefers clean servers, throttles dirty ones automatically.

Failure-mode rotation — when a server fails mid-send, AcelleMail's dispatcher marks it degraded and skips it for retries within the same campaign run. Re-evaluates per-server every 5 minutes via health-check ping. Tune the health-check interval in config/sending-server.php if you need faster failover (cost: more probe traffic).

Related articles

18 条评论

10 条评论

  1. v.petrova.ru
    Confirming the Postmaster Tools data lag — sometimes 48 hours, sometimes longer. Dont make decisions on a single day's data.
  2. lucas.bernard.…
    Does engagement-based segmentation help during warmup? E.g. only sending to the most-engaged 20% during week 1?
    1. admin
      that config is exposed in 5.2+. for older versions you'll need to edit the config file directly. we'll add a version-matrix in the article...
  3. d.cohen.tlv
    Bookmarked. Going to share with the team — we've been winging warmup and it shows in the numbers.
  4. phuong.mai.hn
    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
      Great real-world detail. Your point about stale running_pid > 30 min as an alert is something we should add to the diagnostic flow.
  5. 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
    1. admin (已编辑)
      Good tip. The Cloudflare-outbound-rate-limit case is something we hadn't documented.
    2. admin (已编辑)
      Solid addition — adding to the article on the next refresh.
  6. bos.devops
    This is the clearest IP warmup schedule I've fond. The volume table at the top is what I'm referencing daily.
  7. nadia.r.cl
    The Postmaster Tools section is gold. Most senders don't even know it exists.
  8. anna.k.pm
    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
    1. admin
      Thanks for the detail — adding the kernel-reboot edge case to the article on the next update. :)
    2. admin (已编辑)
      worth noting — your config diverges from the recommended one in one place that often bites people. we'll send a separate note with the suggested change
  9. rafa.silva.br
    This is the clearest IP warmup schedule Ive found. The volume table at the top is what I'm referencing daily
  10. cw.dev.sh
    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
      Depends on your version. 5.x supports it natively; 4.x needs a config flag set in `.env`. We'll note this caveat in the article on the next pass.
    2. admin (已编辑)
      suppression list import via csv captures all opt-outs including preference-center ones if you exported with the right field set. the export filter defaults exclude some — check the 'include unsubscribed' checkbox on mailchimp's export wizard...

More in Sending & Deliverability