How to Configure Postfix with Multiple Relay Hosts for Failover Email Delivery


3 views

When configuring Postfix for email delivery, the relayhost parameter in main.cf is critical for specifying intermediate mail servers. However, a single relayhost entry creates a single point of failure.

Postfix naturally supports multiple MX records resolution. If your relayhost points to a domain with multiple MX records:

relayhost = example.com

Postfix will:

  • Query DNS for MX records of example.com
  • Attempt delivery to hosts in order of priority
  • Fall through to lower priority hosts if higher ones fail

For more control, use the relay_domains and transport_maps approach:

# main.cf
relay_domains = $mydestination, example.com
transport_maps = hash:/etc/postfix/transport

Then in /etc/postfix/transport:

example.com  smtp:[host1.example.com]:587
example.com  smtp:[host2.example.com]:587
example.com  smtp:[host3.example.com]:587

Modern Postfix versions support SRV record lookups:

smtp_srv_lookup = yes
relayhost = example.com

This will query _submission._tcp.example.com SRV records for hosts and ports.

For sophisticated load balancing:

# /etc/postfix/transport
example.com  smtp:[host1.example.com]:587, smtp:[host2.example.com]:587

Then run:

postmap /etc/postfix/transport
postfix reload

Always verify with:

postconf -n
postmap -q example.com hash:/etc/postfix/transport

And test delivery with:

sendmail user@external.com < /dev/null
tail -f /var/log/maillog

When configuring Postfix mail servers, the relayhost parameter typically accepts only a single destination. However, there are several ways to implement failover functionality:


# Basic relayhost configuration (single host)
relayhost = [mail.example.com]:587

Postfix automatically follows MX records when given a domain name without square brackets:


# This will use MX records for failover
relayhost = example.com

The behavior depends on your DNS setup:

  • Postfix will try MX records in order of priority
  • Multiple A records for the same MX host will be tried in random order
  • Timeout and retry logic follows smtp_mx_address_limit and smtp_mx_session_limit settings

For more control, configure a transport map with multiple destinations:


# main.cf:
relayhost = 
transport_maps = hash:/etc/postfix/transport

# /etc/postfix/transport:
example.com    smtp:[mail1.example.com]:587, smtp:[mail2.example.com]:587

When different sender domains need different relay hosts:


# main.cf:
sender_dependent_relayhost_maps = hash:/etc/postfix/sender_relay

# /etc/postfix/sender_relay:
@domain1.com    [mail1.example.com]:587
@domain2.com    [mail2.example.com]:587

Verify your configuration with these commands:


postconf -n | grep relayhost
postmap -q example.com transport
postfix reload

Key parameters to adjust for failover behavior:

  • smtp_connect_timeout (default: 30s)
  • smtp_helo_timeout (default: 300s)
  • maximal_queue_lifetime (default: 5d)

For dynamic relay host selection based on custom logic:


# main.cf:
smtpd_recipient_restrictions = 
    check_policy_service unix:private/policy

# policy service script example
def decide_relayhost():
    # Your custom logic here
    return "[backup-relay.example.com]:587"