Your SMTP server configuration is the foundation of every email your organization sends. A misconfigured SMTP setup doesn’t just cause delivery failures — it damages sender reputation, triggers blocklist entries, and erodes trust with mailbox providers. For system administrators and DevOps engineers responsible for email infrastructure, getting the SMTP configuration right from the start prevents cascading problems that are far more expensive to fix later.
This guide covers the essential SMTP best practices for building a reliable, high-throughput mail delivery system — from port selection and encryption to connection management and operational monitoring.
Port selection is one of the first decisions in any SMTP setup, and choosing incorrectly causes immediate connectivity failures. Each port serves a different purpose in the SMTP ecosystem:
Port 25 is the original SMTP port defined in RFC 5321, used for MTA-to-MTA (server-to-server) relay. Most ISPs and cloud providers block outbound port 25 on customer networks to prevent spam. Use port 25 only for inbound mail acceptance on your MX servers or for relay between trusted internal MTAs.
# Postfix: Accept inbound mail on port 25
# /etc/postfix/master.cf
smtp inet n - y - - smtpd
-o smtpd_tls_security_level=may
-o smtpd_sasl_auth_enable=no
Port 587 is the IETF-standard message submission port (RFC 6409). This is the correct port for authenticated clients submitting outbound mail. It requires STARTTLS for encryption negotiation and mandates authentication before accepting messages. This is the port you should configure for all application-to-SMTP integrations.
# Postfix: Submission port with mandatory TLS and auth
# /etc/postfix/master.cf
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
-o smtpd_tls_mandatory_protocols=>=TLSv1.2
Port 465 uses implicit TLS — the connection is encrypted from the first byte without a STARTTLS negotiation step. Originally deprecated, it was re-assigned for submissions over TLS in RFC 8314. Use this port when your clients support direct TLS connections and you want to eliminate the plaintext negotiation phase entirely.
# Postfix: SMTPS (implicit TLS) on port 465
# /etc/postfix/master.cf
smtps inet n - y - - smtpd
-o syslog_name=postfix/smtps
-o smtpd_tls_wrappermode=yes
-o smtpd_sasl_auth_enable=yes
-o smtpd_tls_mandatory_protocols=>=TLSv1.2
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
| Port | Protocol | Encryption | Use Case |
|---|---|---|---|
| 25 | SMTP | Optional (STARTTLS) | Server-to-server relay, inbound MX |
| 587 | Submission | Required (STARTTLS) | Client submission (recommended) |
| 465 | SMTPS | Implicit TLS | Client submission (alternative) |
Transport Layer Security is non-negotiable for SMTP server configuration in 2026. Mailbox providers increasingly penalize or reject connections that lack encryption. Configure your server to enforce modern TLS standards:
# Postfix: TLS configuration in main.cf
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.example.com/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.example.com/privkey.pem
smtpd_tls_mandatory_protocols = >=TLSv1.2
smtpd_tls_mandatory_ciphers = high
smtpd_tls_exclude_ciphers = aNULL, MD5, RC4, DES, 3DES
smtp_tls_security_level = dane
smtp_dns_support_level = dnssec
Proper authentication prevents unauthorized relay and protects your server from being weaponized as an open relay. Configure these authentication mechanisms in your SMTP setup:
# Dovecot SASL configuration for Postfix
# /etc/dovecot/conf.d/10-auth.conf
auth_mechanisms = plain login
# Only allow auth over TLS
disable_plaintext_auth = yes
# Postfix integration
# /etc/postfix/main.cf
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
Opening a new TCP connection and TLS handshake for every message is wasteful and slow. Connection pooling reuses established SMTP sessions across multiple messages, dramatically improving throughput:
# Postfix: Connection and concurrency settings
# /etc/postfix/main.cf
smtp_destination_concurrency_limit = 20
smtp_destination_rate_delay = 1s
default_destination_concurrency_limit = 20
smtp_connection_cache_on_demand = yes
smtp_connection_cache_time_limit = 300s
smtp_connection_reuse_time_limit = 300s
Rate limiting protects your sender reputation and prevents your IP addresses from being throttled or blocked by receiving mail servers. Implement throttling at multiple layers:
# Postfix: Rate limiting with policy service
# /etc/postfix/main.cf
smtpd_client_message_rate_limit = 100
smtpd_client_connection_rate_limit = 30
anvil_rate_time_unit = 60s
# Per-destination transport throttling
transport_maps = hash:/etc/postfix/transport
# /etc/postfix/transport
gmail.com slow:
yahoo.com slow:
# /etc/postfix/master.cf
slow unix - - y - 2 smtp
-o smtp_destination_rate_delay=2s
-o smtp_destination_concurrency_limit=5
Proper bounce processing is a critical SMTP best practice that directly impacts deliverability. Failing to process bounces means you keep sending to invalid addresses — a behavior that mailbox providers interpret as spamming.
# Postfix: VERP configuration
# /etc/postfix/main.cf
smtpd_authorized_verp_clients = $mynetworks
# Application sends with: MAIL FROM:<[email protected]> XVERP
# Bounce classification
bounce_queue_lifetime = 1d
maximal_queue_lifetime = 3d
delay_warning_time = 4h
An SMTP server without monitoring is a delivery incident waiting to happen. Build observability into your configuration from day one:
# Prometheus metrics with postfix_exporter
# Monitor key delivery metrics:
# - postfix_queue_size{queue="deferred"}
# - postfix_smtp_delivery_duration_seconds
# - postfix_smtpd_connects_total
# - postfix_smtp_tls_connections_total
# Alert rule example (Prometheus)
- alert: DeferredQueueGrowing
expr: postfix_queue_size{queue="deferred"} > 1000
for: 15m
annotations:
summary: "Deferred queue exceeds 1000 messages"
Postfix is the most widely deployed MTA for production SMTP infrastructure. Key configuration lives in /etc/postfix/main.cf and /etc/postfix/master.cf. The examples throughout this guide use Postfix syntax. Run postfix check after any configuration change and postfix reload to apply without dropping active connections.
# /etc/exim4/exim4.conf.template
# TLS configuration
tls_advertise_hosts = *
tls_certificate = /etc/letsencrypt/live/mail.example.com/fullchain.pem
tls_privatekey = /etc/letsencrypt/live/mail.example.com/privkey.pem
tls_require_ciphers = ECDHE+AESGCM:DHE+AESGCM:ECDHE+CHACHA20
# Rate limiting
acl_check_connect:
ratelimit = 100 / 1h / per_conn / $sender_host_address
For Exchange environments, configure Send Connectors and Receive Connectors separately. Ensure the Receive Connector for client submissions requires TLS authentication (RequireTLS = $true) and uses port 587. Apply message rate limits via transport rules or Exchange throttling policies.
# Python: Proper SMTP client configuration
import smtplib
from email.message import EmailMessage
def send_email(msg: EmailMessage) -> None:
with smtplib.SMTP('smtp.example.com', 587) as server:
server.ehlo()
server.starttls(context=ssl.create_default_context())
server.ehlo()
server.login(SMTP_USER, SMTP_PASSWORD)
server.send_message(msg)
# Connection closes cleanly via context manager
Before deploying your SMTP server configuration to production, verify these items:
Every element of your SMTP server configuration contributes to delivery reliability. A well-configured server that follows these SMTP best practices maintains high inbox placement, avoids blocklists, and handles traffic surges gracefully. Invest the time in proper SMTP setup once, and your email infrastructure will reward you with consistent, reliable delivery for years.