Docs / Config
PowerMTA MX rollup & pattern lists — per-provider throttling
MX rollup tells PowerMTA to group recipient domains by their mail exchanger, so the thousands of domains hosted behind one provider (Google, Microsoft) share a single queue, connection limit and reputation view — matching how the receiver actually sees you. You set defaults in <domain *>, tune <mx-pattern> blocks per provider, group receivers with <pattern-list>, and honor backoff on 4xx deferrals. It's throttling to respect a provider's limits, not to evade them.
The biggest mistake in PowerMTA throttling is configuring it per recipient domain. Recipients don't run their own mail servers — they're hosted behind a few large providers, and those providers rate-limit you as a single sender. MX rollup and pattern lists are how you align your throttling with that reality — grouping the destinations a single provider handles so you throttle the provider, not each domain.
Start with the catch-all
The <domain *> block sets the baseline for every receiver you don't name. Keep it conservative and turn on rollup:
<domain *>
max-msg-rate 100/min
max-smtp-out 20
mx-rollup true
</domain>
With mx-rollup on, PowerMTA queues by the recipient's MX host, so all domains behind the same provider are managed as one — the foundation everything else builds on.
Tune per provider with MX patterns
Override the catch-all for the big receivers using <mx-pattern> blocks keyed on their mail-exchanger suffix:
<mx-pattern *.mail.protection.outlook.com> # Microsoft 365
max-msg-rate 60/min
max-smtp-out 10
</mx-pattern>
<mx-pattern *.google.com> # Google Workspace / Gmail
max-msg-rate 120/min
max-smtp-out 20
</mx-pattern> Use the MX checker to confirm a recipient domain's mail exchangers before you commit to a pattern. Start conservative and raise rates only as a provider proves it'll accept more from your reputation.
The MX rollup list
Under the conceptual mx-rollup framing, PowerMTA’s explicit mechanism is the
<mx-rollup-list>, which maps mail-exchanger hosts to a named rollup queue. The
queue name must end in .rollup, and more than one MX can map to the same queue — so the family of
domains a provider hosts collapses into one queue based on the MX they actually resolve to:
<mx-rollup-list>
mx *.mail.protection.outlook.com outlook.rollup
mx *.google.com google.rollup
</mx-rollup-list>
<domain outlook.rollup> # one policy for the whole family
max-smtp-out 10
max-msg-rate 1000/h
</domain>
The rollup is evaluated at submission from the recipient domain’s real MX records, which makes it resilient: a domain
moving providers follows its new MX automatically. The one caveat is wildcards — for a rollup queue defined with a
wildcard MX you must give the queue an explicit smtp-hosts or route, since PowerMTA can’t
infer the right servers for every domain that might match. This is the feature built for large mailbox providers,
filtering and antispam clouds, and hosts running corporate mail for tens of thousands of domains.
domain-macro: the family approach
The older, simpler tool is domain-macro: a named list of domains you reference as a
<domain> group, applying one set of settings to the whole family.
domain-macro outlook hotmail.com, outlook.com, live.com, msn.com
<domain $outlook>
max-smtp-out 10
max-msg-rate 1000/h
</domain>
It’s easy to read, but it has a catch worth knowing: a macro still creates a separate queue per domain,
so the connection and rate limits apply per queue and your real concurrency to the shared MX multiplies with each
domain in the list. The queue-to parameter consolidates a macro into a single rollup queue to fix
that. A macro also hard-codes which domains belong to the family, so a domain that moves to different MXs, or an
unlisted domain on the same servers, slips through. MX rollup avoids both problems by keying on the live MX —
which is why it’s the sturdier choice for the big providers.
Big providers split their MX
A complication the large receivers add: many split their mail across multiple MX groups. Yahoo, for example, has historically grouped its MX servers by continent, and the Outlook family routes different domains through related but distinct gateways. That means “one provider” sometimes needs more than one rollup or macro — a Yahoo Americas group and a Yahoo Asia group, say — each throttled to the tolerance of that specific infrastructure.
The practical method is to look up the actual MX records for the domains you send to and group by the suffix they
share, rather than assuming one pattern covers a whole brand. Google-hosted domains resolve to
*.google.com, Microsoft 365 to *.mail.protection.outlook.com, but a brand’s consumer
and corporate mail can land on different gateways. Confirm with the MX checker
before writing a rollup, so each queue maps to a real, coherent set of servers rather than an assumption about
who owns the domain.
Group receivers with a pattern list
When several receivers should share rules, define them once as a <pattern-list> and reference it instead of repeating <domain> blocks — it keeps a large config readable and consistent.
There’s a second, related kind of pattern list aimed at the receiver’s responses rather than its domains:
the <smtp-pattern-list>. It holds Perl-style regular expressions matched against the SMTP reply
text a provider returns, and each rule decides what to do when a reply matches — most often putting the queue into
back-off, or bouncing a recipient outright:
<smtp-pattern-list provider-signals>
reply /unusual (amount|rate) of unsolicited mail/ mode=backoff
reply /temporarily deferred/ mode=backoff
reply /(over quota|mailbox full)/ bounce-rcpt
</smtp-pattern-list>
You attach the list to a domain or rollup queue with smtp-pattern-list provider-signals, and now the
same per-provider bucket that throttles by rate also reacts intelligently to that provider’s specific deferral
language. This is where MX rollup and pattern lists meet: rollup decides which queue a destination lands
in, and the SMTP pattern list decides how that queue reacts to what the provider says back. The deeper
treatment of the back-off directives themselves lives in throttling
and back-off.
Connection limits at the destination IP
Some providers defeat domain- and MX-level limits in a different way: they host many domains, each with its own unique MX hostname, but all of those MX hosts resolve to the same small set of IP addresses. Throttling per domain or per MX then still opens too many simultaneous connections to those shared IPs, and you collect “exceeded the connection limit” errors anyway.
PowerMTA addresses this with a connection limit applied at the destination IP level, which caps concurrent connections to a given IP or range no matter how many distinct MX hosts or domains point at it. For a provider whose many domains share a handful of IPs, this is the control that actually prevents the errors — the limit follows the real bottleneck (the IPs) rather than the apparent one (the domain names). It’s a useful tool to reach for when per-domain throttling looks correct but a provider keeps refusing connections.
Why provider-level is the right unit
Stepping back, the reason all of this matters is that reputation and rate limits are enforced where the mail is received, not where it’s addressed. PowerMTA keeps a separate queue per recipient domain by default, which is great for isolation — a problem on one domain doesn’t stall another — but delivery problems are usually at the provider level and affect every domain that provider hosts. The receiver sees one stream of connections arriving at their MX from your IP, regardless of how many different recipient domains those messages name.
If you throttle per domain, five thousand domains behind one provider can each sit under its individual limit while the combined rate hitting that provider’s MX runs far past anything they’ll tolerate — and they defer or block you for it. Rolling those domains up to one queue with one rate makes your sending match what the receiver actually measures. That alignment between your throttling unit and the provider’s enforcement unit is the whole point of MX rollup; everything else is detail.
Honor backoff
The whole point is to respect limits. When a provider returns a 4xx deferral, PowerMTA should slow down, not retry aggressively. Configure backoff so a throttle response reduces your rate temporarily and recovers gradually:
<domain *>
backoff-to-normal-after 30m
backoff-max-msg-rate 10/min
</domain> KumoMTA does rollup automatically
One of the clearest differences between the engines is here. In KumoMTA, MX rollup isn’t something you configure —
it’s built in. KumoMTA automatically rolls up every destination domain by its MX fingerprint and queues and
throttles all mail bound for the same MX group together, with no <mx-rollup-list> to write and
keep current. The incomplete or outdated macro list that bites PowerMTA setups simply can’t happen, because the
grouping is derived live from the MX rather than hard-coded.
Pattern lists carry over too, as Lua automation rules: a regex matched against the SMTP reply, an action such as
reducing the message rate, and a duration for how long the adjustment holds — the same idea as PowerMTA’s
mode=backoff, expressed in code and shared across a cluster. So the concepts of this page are universal
— throttle by provider, react to deferral language — while KumoMTA removes the manual rollup bookkeeping. The Auto
PMTA Configurator sets up per-provider grouping for either engine, so you get correct rollup whichever you run.
Common rollup mistakes
The errors cluster predictably. Throttling per domain instead of per provider is the root one — it lets your combined rate to a provider’s MX blow past their tolerance while each domain looks compliant. Incomplete macro lists miss domains that share the same servers, so part of your traffic to a provider escapes the intended limit. Hard-coded routing in a macro bounces mail when a listed domain changes MX.
The rest are easy to overlook: forgetting the <domain *> catch-all, so the long
tail of small receivers inherits no sensible default; assuming one pattern covers a whole brand
when a provider splits its MX by region; and treating rollup as an evasion tool, raising rates to
force volume through. Each has a clean counter — group by live MX, keep a conservative catch-all, verify patterns
with a real MX lookup, and set rates to the provider’s tolerance rather than your ambition.
A complete per-provider setup
Putting rollup, per-provider rates, response patterns and a catch-all together:
<mx-rollup-list>
mx *.mail.protection.outlook.com outlook.rollup
mx *.google.com google.rollup
</mx-rollup-list>
<smtp-pattern-list signals>
reply /temporarily deferred/ mode=backoff
reply /(over quota|mailbox full)/ bounce-rcpt
</smtp-pattern-list>
<domain outlook.rollup>
max-smtp-out 10
max-msg-rate 1000/h
smtp-pattern-list signals
</domain>
<domain google.rollup>
max-smtp-out 5
max-msg-rate 500/h
smtp-pattern-list signals
</domain>
<domain *> # the long tail: gentle default
max-smtp-out 2
smtp-pattern-list signals
</domain> Each big provider gets one queue at a rate suited to it, both share the same response patterns, and everything else falls to a conservative catch-all — a structure that scales from a handful of domains to thousands without rewriting per-domain blocks.
Rollup and the sending side
MX rollup organises the destination side of delivery; virtual MTAs and pools organise the source side. The two compose cleanly because PowerMTA queues per combination of vMTA and destination — so each sending IP gets its own rollup queue per provider. Your Gmail rollup on one vMTA throttles independently of the same Gmail rollup on another, which is exactly right, since each IP’s standing with Gmail is its own.
Seen together, the picture is a grid: source identities (vMTAs, grouped into pools) on one axis, destination providers (rollup queues) on the other, and a throttling policy at each intersection. That’s how a serious setup reasons about rate — not “how fast can I send,” but “how fast can this IP send to this provider right now.” Rollup gives you the destination axis; pools and vMTAs give you the source axis; the per-provider rates and pattern lists fill in the cells.
Maintaining rollup over time
Provider infrastructure isn’t static. Mailbox providers change their MX hostnames, acquire or retire brands, and shift which gateways handle which domains, so a grouping that was correct a year ago can quietly drift. This is the deciding advantage of MX rollup over hard-coded macros: because rollup keys on the live MX at submission, it tracks those changes on its own, while a macro’s fixed domain list silently goes stale.
Where you do rely on macros or explicit patterns, build in a periodic review — re-check the MX records of your highest-volume destinations, confirm the suffixes you grouped on still hold, and look for new domains arriving on servers you already throttle. The cost of a stale grouping is invisible until a chunk of your traffic to a provider quietly escapes the limit and starts collecting deferrals. A short, scheduled MX audit of your top destinations is cheap insurance against that, and it pairs naturally with the rate review that throttling already asks for.
Rollup for filtering clouds
The case for rollup is strongest with the security and filtering clouds that sit in front of corporate mail — Proofpoint, Mimecast, Barracuda and the like. A single such provider can front the inbound mail for tens of thousands of unrelated business domains, every one of them resolving to the same gateway infrastructure. Throttle those per domain and you’d set thousands of tiny limits while the filtering cloud, which measures you as one sender hitting its gateways, watches your aggregate rate climb to a level that trips its defences.
Rolling all the domains behind such a provider into one queue is the only way to throttle to the unit it enforces on. These gateways are also the most sensitive to reputation and rate, since their entire job is filtering, so a conservative per-cloud rate plus a pattern list tuned to their deferral language pays off directly in placement. Identify them the same way as any provider — look up the MX for your business-domain recipients and group by the shared gateway suffix — and give each filtering cloud its own rollup queue with rates set to its tolerance, not your throughput target.
The bottom line
Receivers rate-limit you per provider, so throttle per provider. MX rollup — PowerMTA’s
<mx-rollup-list> mapping mail-exchanger hosts to a .rollup queue — consolidates the
many domains a provider hosts into one queue with one rate, connection limit and reputation view, matching how the
receiver actually sees you. domain-macro is the simpler family approach but creates per-domain queues
unless you queue-to a rollup, and it hard-codes membership. An <smtp-pattern-list>
then reacts to each provider’s deferral language with back-off or a bounce.
Keep a conservative <domain *> catch-all, remember big providers split their MX by region, reach
for a destination-IP connection limit when many domains share IPs, and verify every pattern against a real MX
lookup. KumoMTA performs rollup automatically by MX fingerprint, removing the bookkeeping entirely. If you’d rather
not hand-build per-provider grouping, our managed deliverability service
sets rollup and rates from your real accounting data, and the Auto PMTA Configurator
configures it for either engine, grouping your destinations by their real mail exchangers and setting rates that match each provider’s tolerance from the first send. Align your throttling unit with the receiver’s enforcement unit, and the deferrals that come from accidentally over-sending a provider — the most common self-inflicted throttling problem there is — simply stop, because you are finally measuring your own sending the same way the receiver does — for legitimate, opt-in sending.
Frequently asked questions
What is MX rollup in PowerMTA? +
MX rollup groups recipient domains by their mail-exchanger host rather than by domain name. Because thousands of different domains are hosted behind a handful of providers (Google Workspace, Microsoft 365, and so on), rolling them up means PowerMTA maintains one queue, one connection limit and one reputation view per provider — which is how the receiver actually sees you — instead of treating every customer domain separately.
Why throttle per provider instead of per domain? +
Because the limit is enforced per provider infrastructure, not per domain. If you send to 5,000 different domains that all sit behind Microsoft 365, Microsoft throttles you as one sender hitting their MX. Rolling those domains up lets you set a single rate that respects Microsoft's tolerance; per-domain throttling would let the combined rate run far past it.
What is a pattern list? +
A
Is throttling a way to bypass a provider's rate limits? +
No — it's the opposite. Throttling exists to stay within what a receiver will accept so you avoid deferrals and blocks. Honoring a 4xx 'slow down' with proper backoff is what protects your reputation; trying to push past the limit gets you temp-failed or blocked, which is far worse than sending a little slower.
How do I find a provider's MX pattern? +
Look up the recipient domain's MX records and use the common suffix. Google-hosted domains use MX like aspmx.l.google.com (pattern *.google.com); Microsoft 365 uses *.mail.protection.outlook.com. The MX checker tool shows a domain's mail exchangers so you can confirm the pattern before you write the block.
Related