Running high-volume sends from a single Postfix server with a single sending IP creates two problems: a throughput ceiling (typically 200K–500K messages per day), and reputation concentration — all your complaints, bounces, and spam trap hits affect one IP. Adding multiple IPs to Postfix allows you to distribute sending volume, isolate different traffic types (transactional vs marketing), and warm up new IPs while keeping existing ones clean. This guide covers the three main Postfix multi-IP configurations: source address rotation, per-destination IP assignment, and traffic-type separation.
Step 1 — Add IPs to the Server
Before configuring Postfix, the additional IPs must be assigned to your server's network interface. On Linux, additional IPs are added as virtual interfaces or IP aliases. The exact method depends on your cloud provider and Linux distribution.
# /etc/netplan/01-netcfg.yaml
network:
version: 2
ethernets:
eth0:
dhcp4: false
addresses:
- 203.0.113.10/24 # primary IP
- 203.0.113.11/24 # second IP
- 203.0.113.12/24 # third IP
gateway4: 203.0.113.1
nameservers:
addresses: [8.8.8.8, 8.8.4.4]
# Apply: sudo netplan apply
# Verify all IPs are bound:
# ip addr show eth0
# For AWS EC2: assign Elastic IPs to the instance in console,
# then use EC2 network interface settings to assign secondary IPs.
# AWS requires you to request elastic IP addresses via the console
# before they can be assigned.
Method 1 — Per-Destination IP Routing via Transport Maps
Transport maps let you route mail to specific ISPs through specific sending IPs. This is useful when one IP has a stronger reputation with Gmail and another with Yahoo — you can route Gmail recipients through the better-performing Gmail IP and Yahoo recipients through the Yahoo-optimised IP.
# /etc/postfix/main.cf — point to transport maps transport_maps = hash:/etc/postfix/transport # /etc/postfix/transport — route domains to named transports gmail.com gmail-transport googlemail.com gmail-transport yahoo.com yahoo-transport ymail.com yahoo-transport outlook.com ms-transport hotmail.com ms-transport live.com ms-transport # /etc/postfix/master.cf — define the custom transports # Each transport uses a different smtp_bind_address gmail-transport unix - - n - - smtp -o smtp_bind_address=203.0.113.10 -o smtp_destination_concurrency_limit=10 -o smtp_destination_rate_delay=0s yahoo-transport unix - - n - - smtp -o smtp_bind_address=203.0.113.11 -o smtp_destination_concurrency_limit=5 -o smtp_destination_rate_delay=0.4s ms-transport unix - - n - - smtp -o smtp_bind_address=203.0.113.12 -o smtp_destination_concurrency_limit=5 -o smtp_destination_rate_delay=0.2s # Rebuild transport database after editing: # sudo postmap /etc/postfix/transport # sudo postfix reload
Method 2 — Traffic Type Separation (Transactional vs Marketing)
The most important IP separation for most senders is between transactional email (receipts, 2FA, password resets) and marketing email (newsletters, campaigns). Transactional email has inherently high engagement — users expect it and open it. Mixing it with marketing email on the same IP means a bad marketing campaign can damage the IP that delivers your 2FA codes.
# /etc/postfix/main.cf sender_dependent_default_transport_maps = hash:/etc/postfix/sender_transport # /etc/postfix/sender_transport # Route by sending identity noreply@yourapp.com transactional-smtp alerts@yourapp.com transactional-smtp security@yourapp.com transactional-smtp newsletter@yourapp.com marketing-smtp campaigns@yourapp.com marketing-smtp # /etc/postfix/master.cf transactional-smtp unix - - n - - smtp -o smtp_bind_address=203.0.113.10 -o smtp_destination_concurrency_limit=15 -o maximal_queue_lifetime=1d marketing-smtp unix - - n - - smtp -o smtp_bind_address=203.0.113.11 -o smtp_destination_concurrency_limit=8 -o smtp_destination_rate_delay=0.1s -o maximal_queue_lifetime=6h # Apply: # sudo postmap /etc/postfix/sender_transport # sudo postfix reload
Method 3 — Multiple Postfix Instances (postmulti)
For the cleanest isolation, Postfix supports running multiple completely independent instances on the same server via postmulti. Each instance has its own queue directory, configuration files, and PID. This is the architecture used by large ESPs where different clients need fully isolated sending pipelines with separate DKIM keys, bounce handling, and queue management.
# Enable multi-instance support (one-time): sudo postmulti -e init # Create a new instance named "marketing": sudo postmulti -I postfix-marketing -G mta -e create # The new instance has its own config directory: # /etc/postfix-marketing/ # Configure the second instance: sudo postmulti -i postfix-marketing -x postconf -e "inet_interfaces = 203.0.113.11" "smtp_bind_address = 203.0.113.11" "queue_directory = /var/spool/postfix-marketing" "data_directory = /var/lib/postfix-marketing" # Enable and start the second instance: sudo postmulti -i postfix-marketing -e enable sudo postmulti -i postfix-marketing -p start # List all running instances: sudo postmulti -l # Check queue for specific instance: sudo postmulti -i postfix-marketing -x mailq
▶ Multi-IP Postfix deployment checklist
ip addr show before configuring Postfix. Postfix will fail silently if it tries to bind to an IP that is not assigned.Situation: All three clients sharing a single Postfix instance and single IP. One client had a poor list with 3.2% complaint rate. This contaminated the shared IP, causing Gmail to deliver the other two clients' transactional emails to spam.
Solution: Deployed postmulti — three separate Postfix instances on the same server, each with its own dedicated IP. The high-complaint client was isolated completely. The other two clients retained their clean IP reputation.
Outcome: Transactional delivery restored within 48 hours for clean clients. The high-complaint client required a full list audit and 6-week warm-up on its new IP. Infrastructure cost: $0 additional (same server, additional IPs only).

