Choose the right email protocol
LMTP and Sieve
Place local delivery and server-side filtering after SMTP transport without confusing them with mailbox access.
Two protocols work in the last few centimeters of the path, between the receiving MTA and the mailbox. You rarely see them from a client, but they explain a lot about how a mail server behaves.
LMTP moves the message from the MTA into the mailbox system. Sieve decides what happens to it once it’s there: which folder, whether to reject it, whether to forward it. Neither one is for reading mail.
LMTP: SMTP with one reply per recipient
LMTP looks almost exactly like SMTP. It even uses the same commands, except the greeting is LHLO instead of EHLO. The difference is at the end.
In SMTP, after the message data, the server sends one reply for the whole transaction. In LMTP, it sends one reply per accepted recipient:
C: LHLO mx.studiorossi.it
C: MAIL FROM:<[email protected]>
C: RCPT TO:<[email protected]>
C: RCPT TO:<[email protected]>
C: DATA
S: 354 Send message
C: ...message...
C: .
S: 250 2.1.5 sara delivered
S: 452 4.2.2 marco mailbox temporarily over quota
Sara’s copy is in her mailbox. Marco’s is over quota, and the MTA in front now knows to queue it and retry just his copy. With plain SMTP the server would have had to accept both and generate a bounce later, or reject both.
That’s why LMTP exists. At the final hop the mailbox system already knows the outcome for each person, so it can say so right away. You’ll see it between Postfix and Dovecot, typically over a Unix socket or a trusted internal connection. It is not used across the public Internet.
Sieve: filters that run on the server
Sieve is a tiny language for filtering rules. Here is one that files invoices into a Finance folder:
require ["fileinto"];
if header :contains "subject" "Invoice" {
fileinto "Finance";
}
require declares the extensions the script uses. The if tests a header. fileinto moves the message. That’s most of the language.
The big advantage over a filter in your mail app is where it runs. The server evaluates the script at delivery time, so the message lands in Finance before any client sees it. Your phone, your laptop, and webmail all agree, and it works while your laptop is closed.
Two rules for Sieve scripts
Keep a safe default. A message that matches no rule should stay in the inbox. Never end a script with an implicit discard.
Be careful with redirect. If the destination forwards back to you, or two accounts redirect to each other, you’ve built a mail loop. Servers have loop detection, but don’t rely on it.
Try changing the LMTP transcript so one recipient fails permanently, with the right reply code. Then write a Sieve rule that files messages with “ALERT” in the subject into a folder, while everything else stays in the inbox.
Lesson completed