IP pool management for high-volume sending
Why it matters
At volumes above 100,000 emails per day, a single sending IP becomes both a performance bottleneck and a single point of reputation failure. A block on one IP stops all sending until it is manually removed and replaced — a process that can take hours. IP pool management distributes sending load across multiple IPs and allows the system to automatically exclude a blocked or high-bounce IP and continue sending through healthy ones, without downtime or engineering intervention. Reputation-weighted or least-used selection also prevents one IP from absorbing a disproportionate share of sends while warm-up periods complete on others.
Severity rationale
Low because single-IP architectures are acceptable at lower volumes, but above 50,000 emails per day a single IP block creates a total sending outage that requires manual intervention to resolve.
Remediation
Store sending IPs in the database with per-IP health and warm-up metadata, then select from the pool based on health and current load:
export async function selectSendingIp(): Promise<string> {
const candidates = await db.sendingIp.findMany({
where: { active: true },
orderBy: { sentToday: 'asc' } // Prefer least-used
})
if (candidates.length === 0) {
throw new Error('No available sending IPs')
}
// Exclude IPs with bounce rates above 5% — they are reputation-damaged
const healthy = candidates.filter(ip => ip.hourlyBounceRate < 0.05)
// Fall back to any active IP if all are bouncing above threshold
return (healthy[0] ?? candidates[0]).ipAddress
}
Add an active boolean column to the SendingIp table so a damaged IP can be removed from rotation by setting active = false — no code deployment required. Pair with the warmup schedule check from deliverability-engineering.warmup-reputation.automated-warmup-schedule so IPs in early warm-up are not selected for full-volume sends.
Detection
-
ID:
ip-pool-management -
Severity:
low -
What to look for: Count all sending IPs configured and enumerate the selection logic. For high-volume senders (>100k/day), check whether the codebase manages multiple sending IPs in a pool. Look for IP rotation logic, IP health tracking (per-IP bounce rate, per-IP reputation), and the ability to remove a damaged IP from the pool without downtime. Also check whether the code balances load across IPs in the pool using round-robin, least-used, or reputation-weighted selection.
-
Pass criteria: At least 2 sending IPs are configured and managed. The system selects IPs from the pool with awareness of each IP's health and warm-up status. An IP can be removed from rotation without code changes.
-
Fail criteria: A single sending IP is used with no pool management, or multiple IPs are used but selected randomly without regard to health or warm-up status.
-
Skip (N/A) when: Sending volume is below 50,000 emails/day where a single dedicated IP is sufficient, or the ESP manages IP pool selection transparently.
-
Detail on fail:
"Single IP used for all sending — no IP pool management or rotation logic found"or"Multiple IPs configured but selected randomly without health checks — a damaged IP remains in rotation" -
Remediation: Implement IP pool selection with health awareness:
export async function selectSendingIp(): Promise<string> { const availableIps = await db.sendingIp.findMany({ where: { active: true, // Exclude IPs in warm-up phase that would exceed daily limit // (Use the canSendMore function from warmup logic) }, orderBy: { sentToday: 'asc' } // Round-robin: prefer least-used }) if (availableIps.length === 0) { throw new Error('No available sending IPs — all pools at capacity or in cool-down') } // Prefer IPs with lowest current bounce rate const ranked = availableIps .filter(ip => ip.hourlyBounceRate < 0.05) // Exclude high-bounce IPs .sort((a, b) => a.sentToday - b.sentToday) return ranked[0]?.ipAddress ?? availableIps[0].ipAddress }
External references
- iso-25010:2011 · reliability.availability — ISO 25010 Availability sub-characteristic
Taxons
History
- 2026-04-18·v1.0.0·Initial import from deliverability-engineering·automated