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


11 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"