PPoossttffiixx CCoonnnneeccttiioonn CCaacchhee
-------------------------------------------------------------------------------
IInnttrroodduuccttiioonn
This document describes the Postfix connection cache implementation, which is
available with Postfix version 2.2 and later.
Topics covered in this document:
* What SMTP connection caching can do for you
* Connection cache implementation
* Connection cache configuration
* Connection cache safety mechanisms
* Connection cache limitations
* Connection cache statistics
WWhhaatt SSMMTTPP ccoonnnneeccttiioonn ccaacchhiinngg ccaann ddoo ffoorr yyoouu
With SMTP connection caching, Postfix can deliver multiple messages over the
same SMTP connection. By default, Postfix 2.2 reuses a plaintext SMTP
connection automatically when a destination has high volume of mail in the
active queue.
SMTP Connection caching is a performance feature. Whether or not it actually
improves performance depends on the conditions:
* SMTP Connection caching can greatly improve performance when delivering
mail to a destination with multiple mail servers, because it can help
Postfix to skip over a non-responding server.
* SMTP Connection caching can also help with receivers that impose rate
limits on new connections.
* Otherwise, the benefits of SMTP connection caching are minor: it eliminates
the latency of the TCP handshake (SYN, SYN+ACK, ACK), plus the latency of
the SMTP initial handshake (220 greeting, EHLO command, EHLO response).
With TLS-encrypted connections, this can save an additional two roundtrips
that would otherwise be needed to send STARTTLS and to resume a TLS
session.
* SMTP Connection caching gives no gains with respect to SMTP session tear-
down. The Postfix smtp(8) client normally does not wait for the server's
reply to the QUIT command, and it never waits for the TCP final handshake
to complete.
* SMTP Connection caching introduces some overhead: the client needs to send
an RSET command to find out if a connection is still usable, before it can
send the next MAIL FROM command. This introduces one additional round-trip
delay.
For other potential issues with SMTP connection caching, see the discussion of
limitations at the end of this document.
CCoonnnneeccttiioonn ccaacchhee iimmpplleemmeennttaattiioonn
For an overview of how Postfix delivers mail, see the Postfix architecture
OVERVIEW document.
The Postfix connection cache is shared among Postfix mail delivering processes.
This maximizes the opportunity to reuse an open connection. Some MTAs such as
Sendmail have a non-shared connection cache. Here, a connection can be reused
only by the mail delivering process that creates the connection. To get the
same performance improvement as with a shared connection cache, non-shared
connections need to be kept open for a longer time.
The scache(8) server, introduced with Postfix version 2.2, maintains the shared
connection cache. With Postfix version 2.2, only the smtp(8) client has support
to access this cache.
When SMTP connection caching is enabled (see next section), the smtp(8) client
does not disconnect after a mail transaction, but gives the connection to the
scache(8) server which keeps the connection open for a limited amount of time.
After handing over the open connection to the scache(8) server, the smtp(8)
client continues with some other mail delivery request. Meanwhile, any smtp(8)
client process can ask the scache(8) server for that cached connection and
reuse it for mail delivery.
/-- smtp(8) --> Internet
qmgr(8)
|
\-- | smtp(8)
|
| ^
v |
scache(8)
With TLS connection reuse (Postfix 3.4 and later), the Postfix smtp(8) client
connects to a remote SMTP server and sends plaintext EHLO and STARTTLS
commands, then inserts a tlsproxy(8) process into the connection as shown
below.
After delivering mail, the smtp(8) client hands over the open smtp(8)-to-
tlsproxy(8) connection to the scache(8) server, and continues with some other
mail delivery request. Meanwhile, any smtp(8) client process can ask the scache
(8) server for that cached connection and reuse it for mail delivery.
/-- smtp(8) --> tlsproxy(8) --> Internet
qmgr(8)
|
\-- | smtp(8)
|
| ^
v |
scache(8)
The connection cache can be searched by destination domain name (the right-hand
side of the recipient address) and by the IP address of the host at the other
end of the connection. This allows Postfix to reuse a connection even when the
remote host is a mail server for domains with different names.
CCoonnnneeccttiioonn ccaacchhee ccoonnffiigguurraattiioonn
The Postfix smtp(8) client supports two connection caching strategies:
* On-demand connection caching. This is enabled by default, and is controlled
with the smtp_connection_cache_on_demand configuration parameter. When this
feature is enabled, the Postfix smtp(8) client automatically saves a
connection to the connection cache when a destination has a high volume of
mail in the active queue.
Example:
/etc/postfix/main.cf:
smtp_connection_cache_on_demand = yes
* Per-destination connection caching. This is enabled by explicitly listing
specific destinations with the smtp_connection_cache_destinations
configuration parameter. After completing delivery to a selected
destination, the Postfix smtp(8) client always saves the connection to the
connection cache.
Specify a comma or white space separated list of destinations or pseudo-
destinations:
o if mail is sent without a relay host: a domain name (the right-hand
side of an email address, without the [] around a numeric IP address),
o if mail is sent via a relay host: a relay host name (without the [] or
non-default TCP port), as specified in main.cf or in the transport map,
o a /file/name with domain names and/or relay host names as defined
above,
o a "type:table" with domain names and/or relay host names on the left-
hand side. The right-hand side result from "type:table" lookups is
ignored.
Examples:
/etc/postfix/main.cf:
smtp_connection_cache_destinations = $relayhost
smtp_connection_cache_destinations = hotmail.com, ...
smtp_connection_cache_destinations = static:all (not recommended)
See Client-side TLS connection reuse to enable multiple deliveries over a
TLS-encrypted connection (Postfix version 3.4 and later).
CCoonnnneeccttiioonn ccaacchhee ssaaffeettyy mmeecchhaanniissmmss
Connection caching must be used wisely. It is anti-social to keep an unused
SMTP connection open for a significant amount of time, and it is unwise to send
huge numbers of messages through the same connection. In order to avoid
problems with SMTP connection caching, Postfix implements the following safety
mechanisms:
* The Postfix scache(8) server keeps a connection open for only a limited
time. The time limit is specified with the smtp_connection_cache_time_limit
and with the connection_cache_ttl_limit configuration parameters. This
prevents anti-social behavior.
* The Postfix smtp(8) client reuses a session for only a limited number of
times. This avoids triggering bugs in implementations that do not correctly
handle multiple deliveries per session.
As of Postfix 2.3 connection reuse is preferably limited with the
smtp_connection_reuse_time_limit parameter. In addition, Postfix 2.11
provides smtp_connection_reuse_count_limit to limit how many times a
connection may be reused, but this feature is unsafe as it introduces a
"fatal attractor" failure mode (when a destination has multiple inbound
MTAs, the slowest inbound MTA will attract most connections from Postfix to
that destination).
Postfix 2.3 logs the use count of multiply-used connections, as shown in
the following example:
Nov 3 16:04:31 myname postfix/smtp[30840]: 19B6B2900FE:
to=<wietse@test.example.com>, orig_to=<wietse@test>,
relay=mail.example.com[1.2.3.4], ccoonnnn__uussee==22, delay=0.22,
delays=0.04/0.01/0.05/0.1, dsn=2.0.0, status=sent (250 2.0.0 Ok)
* The connection cache explicitly labels each cached connection with
destination domain and IP address information. A connection cache lookup
succeeds only when the correct information is specified. This prevents mis-
delivery of mail.
CCoonnnneeccttiioonn ccaacchhee lliimmiittaattiioonnss
Postfix SMTP connection caching conflicts with certain applications:
* With Postfix versions < 3.4, the Postfix shared connection cache cannot be
used with TLS, because an open TLS connection can be reused only in the
process that creates it. For this reason, the Postfix smtp(8) client
historically always closed the connection after completing an attempt to
deliver mail over TLS.
* Postfix connection caching currently does not support multiple SASL
accounts per mail server. Specifically, Postfix connection caching assumes
that a SASL credential is valid for all hostnames or domain names that
deliver via the same mail server IP address and TCP port, and assumes that
the SASL credential does not depend on the message originator.
CCoonnnneeccttiioonn ccaacchhee ssttaattiissttiiccss
The scache(8) connection cache server logs statistics about the peak cache size
and the cache hit rates. This information is logged every
connection_cache_status_update_time seconds, when the process terminates after
the maximal idle time is exceeded, or when Postfix is reloaded.
* Hit rates for connection cache lookups by domain will tell you how useful
connection caching is.
* Connection cache lookups by network address will always fail, unless you're
sending mail to different domains that share the same MX hosts.
* No statistics are logged when no attempts are made to access the connection
cache.