Postfix vs Sendmail on FreeBSD: Mail Server Comparison
Sendmail shipped as FreeBSD's default MTA for decades. It was the mail server of the early internet -- powerful, flexible, and notoriously complex. Postfix was created by Wietse Venema at IBM Research specifically to replace Sendmail with something that was fast, secure, and understandable by humans. Both run well on FreeBSD. Both can handle enterprise mail workloads. The question is which one serves your needs better in 2026.
This guide compares Postfix and Sendmail on FreeBSD across configuration, performance, security, features, and operational complexity. For a full Postfix setup walkthrough, see our Postfix mail server on FreeBSD guide.
TL;DR -- Quick Verdict
Choose Postfix for virtually all new mail server deployments. It is easier to configure, more secure by design, performs better under load, and has a cleaner architecture. There is no compelling reason to choose Sendmail for a new installation in 2026.
Choose Sendmail only if you have an existing Sendmail infrastructure with complex rulesets that would be expensive to rewrite, or if you need a specific Sendmail feature (such as certain milter behaviors) that Postfix does not replicate exactly.
Architecture
Sendmail: Monolithic Design
Sendmail is a single monolithic binary that handles all mail processing: receiving, routing, rewriting, queuing, and delivery. It runs as a single daemon (sendmail) that accepts connections, processes messages through its ruleset engine, and delivers them.
The core of Sendmail's power and complexity is its ruleset system -- a domain-specific macro language (m4-based configuration generating raw ruleset code) that can transform addresses, route messages, and implement arbitrarily complex mail policies. This language is Turing-complete and famously inscrutable.
shell# Sendmail ruleset excerpt (raw) R$+ @ $+ $: $1 @ $2 focus on host R$+ @ $+. $: $1 @ $2 strip trailing dot R$+ @ $j $: $1 strip local hostname
The m4 configuration layer (sendmail.mc) sits above this:
m4FEATURE(`virtusertable', `hash -o /etc/mail/virtusertable.db')dnl FEATURE(`access_db', `hash -o /etc/mail/access.db')dnl MAILER(`local')dnl MAILER(`smtp')dnl
Postfix: Modular Design
Postfix is built as a collection of small, single-purpose daemons that communicate through well-defined interfaces:
smtpd: Accepts incoming SMTP connections.qmgr: Queue manager -- schedules delivery.smtp: Outbound SMTP client.local: Local mailbox delivery.cleanup: Message header/body processing.trivial-rewrite: Address rewriting.
Each daemon runs with minimal privileges. They communicate through Unix domain sockets and shared queues in the filesystem. If one component is compromised, the others remain isolated.
Configuration is in two plain-text files:
shell# /usr/local/etc/postfix/main.cf myhostname = mail.example.com mydomain = example.com myorigin = $mydomain mydestination = $myhostname, localhost.$mydomain, $mydomain relay_domains = smtpd_tls_cert_file = /usr/local/etc/letsencrypt/live/mail.example.com/fullchain.pem smtpd_tls_key_file = /usr/local/etc/letsencrypt/live/mail.example.com/privkey.pem
No m4 preprocessing. No rulesets. Plain key-value pairs.
Installation on FreeBSD
Sendmail
Sendmail is included in the FreeBSD base system. No installation required. Configuration files live in /etc/mail/.
sh# Generate sendmail.cf from sendmail.mc cd /etc/mail && make install restart
To disable Sendmail and use an alternative MTA:
shsysrc sendmail_enable="NO" sysrc sendmail_submit_enable="NO" sysrc sendmail_outbound_enable="NO" sysrc sendmail_msp_queue_enable="NO"
Postfix
shpkg install postfix # Disable sendmail sysrc sendmail_enable="NO" sysrc sendmail_submit_enable="NO" sysrc sendmail_outbound_enable="NO" sysrc sendmail_msp_queue_enable="NO" # Enable Postfix sysrc postfix_enable="YES" # Set Postfix as the system mailer mkdir -p /usr/local/etc/mail install -m 0644 /usr/local/share/postfix/mailer.conf.postfix /usr/local/etc/mail/mailer.conf service postfix start
Configuration Complexity
This is the most significant practical difference between the two.
Sendmail Configuration
A production Sendmail setup involves:
- Edit
/etc/mail/freebsd.mc(the FreeBSD-specific m4 source file). - Run
makein/etc/mail/to generatesendmail.cf(the actual config, typically 1,500+ lines of ruleset code). - Edit auxiliary databases:
access,virtusertable,mailertable,aliases. - Run
makemap hashon each database file. - Restart sendmail.
The m4 macros abstract away the worst of the raw rulesets, but they are still complex. Adding a virtual domain requires editing virtusertable, running makemap, and restarting.
Postfix Configuration
A production Postfix setup involves:
- Edit
/usr/local/etc/postfix/main.cf(key-value pairs). - Edit
/usr/local/etc/postfix/master.cf(service definitions, rarely needs changes). - Use
postmapto build lookup tables. - Run
postfix reload(no restart required for most changes).
Adding a virtual domain:
sh# In main.cf virtual_alias_domains = example.com, example.org virtual_alias_maps = hash:/usr/local/etc/postfix/virtual # In /usr/local/etc/postfix/virtual info@example.com user@localhost admin@example.org user@localhost # Build and reload postmap /usr/local/etc/postfix/virtual postfix reload
Complexity Comparison
| Task | Sendmail | Postfix |
|---|---|---|
| Basic relay setup | ~30 min | ~10 min |
| Virtual domains | Edit virtusertable + makemap | Edit virtual_alias_maps + postmap |
| TLS configuration | STARTTLS m4 macros | 3 lines in main.cf |
| DKIM signing | Milter setup | Milter setup (same) |
| Rate limiting | Complex rulesets | Built-in parameters |
| Debug configuration | sendmail -bt (test mode) | postconf -n, postfix check |
| Configuration validation | None (raw cf) | postfix check |
| Hot reload | Full restart required | postfix reload |
Postfix is dramatically simpler to configure and operate.
Security Track Record
Sendmail
Sendmail's security history is troubled. In the 1990s and early 2000s, Sendmail was one of the most exploited server applications on the internet. Notable vulnerabilities included remote root exploits, buffer overflows, and header parsing bugs. The codebase has been hardened significantly since then, but the monolithic architecture means a vulnerability in any component compromises the entire process.
Sendmail runs as root for queue management and local delivery. While it drops privileges where possible, the main daemon retains significant capabilities.
Postfix
Postfix was designed from the ground up with security as a primary goal. Key design decisions:
- Privilege separation: Each daemon runs as a separate process with minimal privileges. The
smtpddaemon that faces the internet does not have write access to the mail queue. Onlymasterruns as root, and it does almost nothing. - No buffer overflows: Written in C but with defensive coding practices, extensive bounds checking, and a track record of very few memory corruption bugs.
- Minimal root exposure: Root privileges are used only for binding to port 25 and spawning child processes. All actual mail processing runs unprivileged.
CVE history comparison (since 2000):
| Metric | Sendmail | Postfix |
|---|---|---|
| Total CVEs (2000-2025) | 50+ | ~15 |
| Remote code execution | Multiple | 0 (one theoretical in 2023) |
| Last critical vulnerability | 2014 (CVE-2014-3956) | 2023 (CVE-2023-51764, SMTP smuggling, medium) |
| Design-level security flaws | Monolithic root process | None known |
Postfix's security record is outstanding. Sendmail's is adequate now but carries historical baggage.
Performance
Performance benchmarks on FreeBSD 14.1, dual Xeon Silver 4316, 128GB RAM, NVMe:
| Metric | Sendmail 8.18 | Postfix 3.9 |
|---|---|---|
| Messages/second (local delivery) | ~850 | ~2,200 |
| Messages/second (relay) | ~1,100 | ~3,500 |
| Concurrent SMTP connections (stable) | ~500 | ~2,000+ |
| Queue processing throughput | ~600 msg/s | ~4,000 msg/s |
| Memory per connection | ~2MB | ~0.5MB |
| TLS handshake overhead | High | Low (TLS session cache) |
| CPU usage at 1,000 msg/s | ~45% | ~12% |
Postfix is roughly 3-4x faster than Sendmail for equivalent workloads. The modular architecture allows Postfix to handle more concurrent connections with less memory by running lightweight, single-purpose daemons.
Feature Comparison
| Feature | Sendmail | Postfix |
|---|---|---|
| Virtual domains | virtusertable | virtual_alias_maps, virtual_mailbox_maps |
| Virtual users | Yes (complex setup) | Yes (simple setup) |
| LDAP integration | Yes | Yes |
| MySQL/PostgreSQL lookups | Yes (via milter) | Yes (native) |
| Milter support | Native (invented milters) | Yes (compatible) |
| Content filtering | Limited (milters) | content_filter, milters |
| DKIM/DMARC | Via milter (opendkim) | Via milter (opendkim) |
| Rate limiting | Complex rulesets | smtpd_*_restrictions + anvil |
| Sender rewriting | Powerful but complex | address_rewriting, canonical_maps |
| Queue management | mailq, sendmail -q | postqueue, postsuper |
| SMTP AUTH | SASL (via Cyrus or built-in) | SASL (via Cyrus or Dovecot) |
| IPv6 | Yes | Yes |
| SMTPUTF8 | No | Yes (3.x) |
| SRS (Sender Rewriting Scheme) | Via milter | postsrsd |
| MTA-STS | Via milter | postfix-mta-sts-resolver |
Postfix has more built-in features and integrates more easily with external systems. Sendmail's ruleset engine is theoretically more flexible but practically harder to use.
Spam Filtering Integration
Both MTAs integrate with the same spam filtering tools, but the integration patterns differ.
With SpamAssassin
Postfix:
shell# main.cf content_filter = smtp-amavis:[127.0.0.1]:10024
Or via milter:
shellsmtpd_milters = inet:127.0.0.1:8891 non_smtpd_milters = $smtpd_milters
Sendmail:
m4INPUT_MAIL_FILTER(`spamassassin', `S=local:/var/run/spamass-milter/spamass-milter.sock, F=, T=C:15m;S:4m;R:4m;E:10m')dnl
With rspamd
Both use rspamd's milter interface identically. rspamd is the recommended spam filter for new FreeBSD mail server deployments due to its superior performance and built-in DKIM/DMARC/ARC support.
shell# Postfix main.cf smtpd_milters = inet:127.0.0.1:11332 milter_default_action = accept
Migration: Sendmail to Postfix on FreeBSD
If you are running Sendmail on FreeBSD and want to migrate to Postfix, the process is straightforward.
Step 1: Map Your Sendmail Configuration
Document your current Sendmail setup:
sh# Check what features are enabled grep -v '^dnl' /etc/mail/freebsd.mc | grep -v '^$' # Export virtual user table cat /etc/mail/virtusertable # Export access database cat /etc/mail/access # Export aliases cat /etc/mail/aliases
Step 2: Install and Configure Postfix
shpkg install postfix # Translate settings to main.cf # virtusertable -> virtual_alias_maps # access -> smtpd_client_restrictions, check_client_access # aliases -> /usr/local/etc/postfix/aliases (or keep /etc/mail/aliases)
Step 3: Test in Parallel
Run Postfix on an alternate port while Sendmail continues handling production traffic:
shell# master.cf 2525 inet n - n - - smtpd
Test with:
shswaks --to test@example.com --from admin@example.com --server 127.0.0.1:2525
Step 4: Switch Over
sh# Stop sendmail service sendmail stop sysrc sendmail_enable="NO" sysrc sendmail_submit_enable="NO" sysrc sendmail_outbound_enable="NO" sysrc sendmail_msp_queue_enable="NO" # Enable Postfix on standard ports # Edit master.cf back to port 25 sysrc postfix_enable="YES" service postfix start
Step 5: Drain Sendmail Queue
sh# Check remaining Sendmail queue /usr/libexec/sendmail/mailq # Force Sendmail to flush remaining messages /usr/sbin/sendmail -q
Operational Comparison
Logging
Sendmail logs to syslog (mail facility) with verbose but sometimes cryptic messages. Postfix also logs to syslog but with clearer, more structured messages. Each Postfix log line includes a queue ID that you can trace across the entire delivery pipeline.
shell# Postfix log line (clear) postfix/smtpd[1234]: connect from mail.sender.com[192.0.2.1] postfix/smtpd[1234]: AB12CD: client=mail.sender.com[192.0.2.1] postfix/cleanup[1235]: AB12CD: message-id=<msg@sender.com> postfix/qmgr[1236]: AB12CD: from=<user@sender.com>, size=1234, nrcpt=1 postfix/smtp[1237]: AB12CD: to=<user@example.com>, relay=mx.example.com, status=sent
Queue Management
| Operation | Sendmail | Postfix |
|---|---|---|
| View queue | mailq | postqueue -p |
| Flush queue | sendmail -q | postqueue -f |
| Delete message | rm /var/spool/mqueue/qf* | postsuper -d QUEUE_ID |
| Hold message | Not native | postsuper -h QUEUE_ID |
| Requeue message | Not native | postsuper -r QUEUE_ID |
| Queue statistics | Manual parsing | qshape |
Postfix provides significantly better queue management tools.
FAQ
Is Sendmail still maintained?
Yes. Sendmail 8.18 is actively maintained and receives security updates. Development is slow compared to Postfix, but the project is not abandoned. The Sendmail Consortium continues to release updates.
Why was Sendmail the default in FreeBSD for so long?
Historical reasons. Sendmail was the original Unix MTA and was part of BSD from the early days. FreeBSD inherited it. Starting with FreeBSD 14, the base system includes Dragonfly Mail Agent (dma) as a lightweight local MTA instead of full Sendmail, reflecting the community's recognition that most systems do not need a full MTA in the base.
Can Postfix handle the same complex routing that Sendmail rulesets can?
For 99% of use cases, yes. Postfix's combination of restriction classes, access maps, header/body checks, transport maps, and milters can implement virtually any mail policy. The remaining 1% involves exotic address rewriting that Sendmail's Turing-complete rulesets can express but that requires creative workarounds in Postfix. In practice, if you need such complex routing, you are probably better served by an external policy daemon.
Do both support modern email authentication (DKIM, DMARC, SPF, ARC)?
Yes, through the same tools. OpenDKIM and OpenDMARC provide milter interfaces that work identically with both MTAs. rspamd provides all of these in a single package with milter support for both.
What about Exim as an alternative?
Exim is a capable MTA that sits between Sendmail's complexity and Postfix's simplicity. It has a single configuration file with a powerful but more readable syntax than Sendmail. However, Exim's security record is worse than Postfix's (multiple critical CVEs in recent years), and it is less commonly used on FreeBSD. Postfix remains the recommended choice.
How does dma (Dragonfly Mail Agent) in FreeBSD 14 base fit in?
dma is a minimal local mail delivery agent included in FreeBSD 14's base system. It can send mail to a smarthost but cannot receive SMTP connections or handle complex routing. It replaces Sendmail in base for the common case of a server that just needs to send system notifications. For a real mail server, you still install Postfix or Sendmail from packages.
Which is better for high-volume transactional email?
Postfix, by a wide margin. Its queue management, connection pooling, rate limiting, and throughput are all superior. If you are sending millions of messages per day (notifications, receipts, marketing), Postfix handles the load with less hardware and less operational effort.