Andrew Mercer
on this page

Once a message reaches the MTA that's authoritative for its destination domain, something has to actually put it somewhere a user (or their IMAP/POP3 client) can read it. This last step is delivery, and it's conceptually separate from everything SMTP-related.

mbox vs. Maildir

Two competing on-disk formats for storing mail, both predating any of the notes in this guide but still exactly what's chosen (often implicitly) any time a "local delivery" or "virtual mailbox" path is configured:

  • mbox — a single flat file per mailbox; all messages concatenated together, separated by a From line. Simple, but a classic source of corruption if two processes write to it concurrently without proper locking, and it doesn't scale well to large mailboxes since any access can mean rewriting the whole file.
  • Maildir — one file per message, split across new/, cur/, and tmp/ subdirectories. Designed specifically to be safe for concurrent access without locking (delivery writes to tmp/ then atomically renames into new/), and scales far better. This is the de facto standard for any modern setup, and what Dovecot uses by default.

Local delivery vs. virtual mailboxes

Postfix distinguishes between two very different delivery models, and a lot of the confusion in older/mixed configuration examples (including some of the ones distilled into this guide) comes from mixing them up:

  • System/local accounts — the recipient corresponds to an actual Unix user account on the box (mydestination domains, delivered via the local(8) delivery agent, typically into /var/mail/<user> or similar, using the system's own /etc/passwd).
  • Virtual mailboxes — the recipient does not need to be a Unix account at all. Domains are listed in virtual_mailbox_domains, and a lookup table (flat file, MySQL, LDAP, etc.) maps addresses to storage locations, UIDs/GIDs, and quotas independently of the system's user database. This is what lets one server host mailboxes for many unrelated domains and users without creating a Unix account per mailbox — the pattern behind PostfixAdmin and the MySQL-backed virtual mailbox setup in this guide.

Getting this distinction right matters immediately when you're debugging: mydestination and virtual_mailbox_domains are mutually exclusive for the same domain — a domain listed in one should not also be listed in the other, or delivery behavior becomes unpredictable.

Aliasing vs. mailboxes

A third, lighter-weight mechanism that's easy to conflate with "real" mailboxes: aliases just redirect one address to one or more other addresses — no storage of their own. Postfix has two alias mechanisms that look similar but serve different scopes:

  • /etc/aliases (processed by postalias, referenced via alias_maps) — for local/system recipients. Classic uses: routing root's mail to a real inbox, or building a simple mailing list by aliasing one local address to several external addresses.
  • virtual_alias_maps (processed by postmap) — for addresses in domains that aren't necessarily local system domains at all; this is how "receive mail for a whole extra domain and forward it elsewhere" (a "virtual alias domain") works without any real mailboxes existing for that domain.

MDA: where delivery is actually handed off

The Mail Delivery Agent is the piece of software that takes a message Postfix has decided to deliver locally and actually writes it to a mailbox in one of the formats above. Historically this was procmail; in any current setup it's normally Dovecot's LMTP/deliver, invoked by Postfix via its virtual_transport/mailbox_command settings. Dovecot then does double duty as both the MDA (writing mail in) and the IMAP/POP3 server (serving mail back out to MUAs) — which is why "Postfix + Dovecot + MySQL" is such a common combination in self-hosted mail: Postfix handles SMTP in and out, Dovecot handles everything about actually storing and serving the mailboxes.