Skip to content

Docs / Configuration

PowerMTA throttling & back-off

Updated 2026-06-05· 7 min read· bring-your-own-license

Throttling sets how fast a virtual MTA may send to a destination — messages per hour and simultaneous connections — while back-off is how PowerMTA reacts when a receiver returns temporary 4xx failures: it slows and retries rather than pushing harder. Configure both per provider family (via virtual MTAs and pattern lists), start conservative and ramp during warm-up, and let the receiver's deferral responses tell you when you're sending too fast. The aim is to send as fast as each provider will cleanly accept, not as fast as your server can.

Throughput in email isn't decided by your hardware — it's decided by the receiver. Send faster than a provider tolerates and you don't get more delivered; you get deferred, and if you keep pushing, your reputation pays for it. Throttling and back-off are how you stay on the right side of that line — one sets the pace in advance, the other reacts when a receiver pushes back.

Settings live per recipient domain

The first thing to understand is the unit PowerMTA throttles on. Delivery settings are made in the context of a recipient domain, and PowerMTA keeps a separate queue for each unique combination of virtual MTA and destination domain. A limit you set in <domain gmail.com> governs the queue for Gmail on each vMTA independently — which is exactly what you want, since each IP’s standing with each provider is its own thing.

Many providers run several domains behind the same mail servers — Outlook, Hotmail, Live and MSN, for instance, share infrastructure — so PowerMTA offers domain-macro to apply one set of limits across a whole family while still keeping a separate queue per domain. You define the macro once and reference it as a <domain> group, so the family is throttled coherently rather than as unrelated destinations. This per-domain, per-family model is what lets you tune each provider without affecting the rest.

Throttling: the ceiling you set

Throttling caps how much a virtual MTA sends to a given destination. Two controls do most of the work:

ControlWhat it limits
max-msg-rateMessages per unit time to a destination (e.g. per hour)
max-smtp-outSimultaneous outbound SMTP connections
connection limitsHow aggressively new connections are opened

You apply these per provider rather than globally — Gmail, Microsoft and Yahoo each tolerate different rates — by grouping destinations with MX rollups and pattern lists and setting limits on each group.

The fuller set of per-domain controls, all set inside a <domain> block:

<domain gmail.com>
    max-smtp-out 5            # simultaneous connections
    max-msg-rate 500/h        # messages per hour
    max-msg-per-connection 20
    retry-after 30m
</domain>

A point that surprises people: connections matter more than message rate. Receivers throttle on the number of concurrent connections more aggressively than on raw message throughput, and exceeding a provider’s connection limit is the single fastest way to trigger a 421 deferral. For volumes in the 1,000–10,000-per-hour range, just 1–5 concurrent connections (max-smtp-out) per destination is usually the right ceiling — higher rarely sends more and often sends less. So treat max-smtp-out as your primary lever and max-msg-rate as the secondary one, and set both per provider, never globally.

Back-off: the reaction to deferrals

When a receiver is being pushed too hard it returns a temporary 4xx deferral rather than rejecting outright. Back-off is PowerMTA's correct response: hold the mail, slow the rate and retry after a delay instead of immediately re-attempting at full speed. Configured back-off turns a provider's "slow down" into exactly that, rather than a reputation problem.

Back-off is wired up with a <smtp-pattern-list>: a set of Perl-style regular expressions matched against the receiver’s SMTP reply text. When a reply matches a reputation- or rate-related pattern, the matching rule puts that queue into back-off mode, where it sends more slowly until it recovers:

<smtp-pattern-list isp-backoff>
    reply /unusual (amount|rate) of unsolicited mail/ mode=backoff   # Google
    reply /temporarily rate limited due to IP reputation/ mode=backoff # Outlook
    reply /temporarily deferred/ mode=backoff                        # Yahoo
</smtp-pattern-list>

<domain gmail.com>
    smtp-pattern-list isp-backoff
    backoff-to-normal-after 2h
    backoff-max-msg-rate 100/h        # slow pace while backed off
    backoff-retry-after 30m
</domain>

The directives shape how back-off behaves: backoff-max-msg-rate sets the reduced pace, backoff-retry-after the wait between attempts, backoff-to-normal-after how long before the queue tries normal speed again, and backoff-to-normal-after-delivery true returns to normal once a delivery succeeds. backoff-notify can alert you when a queue backs off. Together they turn a provider’s “slow down” into a measured retreat rather than a reputation-burning retry storm.

During warm-up, everything is lower

A new IP earns its rate. Start with conservative limits and raise them over days as engagement proves your sending is wanted — the discipline covered in IP warm-up and dedicated vs shared IP. Throttling is the lever that enforces a warm-up curve.

Per-ISP examples

Because each provider tolerates different rates, you tune per family. Gmail rewards conservative connection counts; the Outlook family shares mail servers and benefits from a macro plus 421-means-mx-unavailable; Yahoo has its own deferral language. A representative shape:

<domain gmail.com>
    max-smtp-out 5
    max-msg-rate 500/h
    retry-after 30m
</domain>

domain-macro outlook hotmail.com, outlook.com, live.com, msn.com
<domain $outlook>
    max-smtp-out 10
    max-msg-rate 1000/h
    421-means-mx-unavailable yes
</domain>

<domain yahoo.com>
    max-smtp-out 5
    max-msg-per-connection 20
</domain>

These numbers are starting points, not gospel — your reputation and IP age move them. The structure is the durable part: one block per provider family, connections kept low, message rate as a secondary cap, and a macro folding related domains into a single coherent policy. Tune the values from the deferral responses each provider actually returns, which is the subject of the 421 throttling fix.

Bouncing on quota errors

Not every 4xx deserves endless retries. A mailbox that returns “over quota” or “mailbox full” on every attempt is effectively dead, and retrying it for days wastes connections you could spend on deliverable mail. A pattern list can convert those specific temporary responses into an immediate bounce instead:

<smtp-pattern-list quota>
    reply /(over quota|mailbox full|mailbox quota)/ bounce-rcpt
</smtp-pattern-list>

With bounce-rcpt, the recipient is bounced (and so flows into your suppression handling) rather than retried to no purpose. Use it surgically — only for responses that genuinely mean the address won’t accept mail — since a too-broad pattern would bounce recipients who are merely temporarily deferred. The distinction is the same one throttling rests on: transient provider rate-limiting deserves back-off, a persistently unreachable mailbox deserves a bounce.

Manual queue control

Sometimes you need to act on a queue by hand — a provider that backed you off recovers, or you want to release a queue you slowed manually. PowerMTA exposes queue state through its command line:

pmta show queues                       # inspect queue state and modes
pmta set queue mode=normal yahoo.com   # return a domain queue to normal
pmta set queue mode=normal yahoo.com/vmta1  # a specific vMTA+domain queue

Targeting domain/vmta reaches the exact queue, since a backed-off Yahoo queue on one vMTA is separate from Yahoo on another. Manual control is the exception, not the routine — well-configured pattern lists and back-off directives should handle the day-to-day automatically — but knowing how to inspect and reset a queue is essential when you’re diagnosing why mail to one provider is moving slowly.

When back-off goes wrong

Back-off is powerful enough to hurt you if misconfigured, and it’s a common source of “PowerMTA is slow” complaints. Patterns that are too broad catch ordinary responses and put healthy queues into back-off unnecessarily; a backoff-to-normal-after set too long keeps a queue crawling well after the provider has relaxed; and back-off rates set too low can leave mail trickling out far below what the receiver would now accept. The result looks like a throughput problem but is really a tuning one.

The fix is precision: match only the specific reputation- and rate-related replies, set recovery windows that let a queue test normal speed reasonably soon, and confirm with pmta show queues that queues aren’t stuck in back-off when they shouldn’t be. A pattern list is a scalpel, not a blanket — the goal is to slow down exactly when a provider asks and return to full speed the moment it stops asking, nothing more.

Why connections matter more than rate

It’s worth dwelling on the connection-versus-rate point, because getting it backwards is a frequent cause of self-inflicted deferrals. When operators analyse “exceeded the connection limit” errors, the correlation isn’t with how fast connections are opened (the connect rate) but with how many are open at once (the concurrency). That’s why max-smtp-out, which caps simultaneous connections, is the lever that prevents these errors — not max-connect-rate.

The practical guidance follows directly: for most senders, a low concurrency ceiling of a handful of connections per destination carries surprising volume, and pushing concurrency higher tends to trip provider limits faster than it gains throughput. Resist the instinct that more connections means more mail — beyond a modest point it means more deferrals. And at genuinely high volume the bottleneck is usually disk speed on your own server rather than CPU or connection count, so if a queue is slow the answer is rarely “open more connections.” Keep concurrency conservative and let consistency, not aggression, do the work.

Throttling and reputation reinforce each other

Throttling isn’t a fixed tax you pay forever — it interacts with reputation in a loop. Sending at a rate a provider accepts cleanly, without tripping deferrals, builds the reputation that lets you send more over time. Push too hard, collect deferrals, and you damage the reputation that would have raised your ceiling, so you end up able to send less. The conservative path is also the faster one in the long run.

This is why warm-up and throttling are the same discipline viewed over different timescales: warm-up is the deliberate ramp of limits as a new IP earns trust, and steady-state throttling is holding each provider’s rate at the level your current standing supports. Authentication feeds into it too — a domain failing alignment or signing inconsistently amplifies throttling, because receivers trust an unauthenticated stream less and defer it sooner. Get authentication solid first, then let measured throttling build the standing that earns higher rates.

KumoMTA traffic shaping

KumoMTA expresses throttling and back-off as traffic shaping in Lua. Per-domain shaping rules set the equivalents of PowerMTA’s limits — a maximum connection rate, a maximum message rate, concurrency caps — and KumoMTA can adjust them dynamically in response to the provider’s replies, the same role PowerMTA’s pattern lists and back-off directives play. The shaping config is often kept in a data file keyed by destination, which makes per-ISP policy easy to maintain.

The principles are identical regardless of engine: throttle per provider not globally, keep concurrency low, react to deferrals by slowing rather than retrying harder, and ramp during warm-up. Only the expression differs — declarative <domain> directives and pattern lists in PowerMTA, Lua shaping rules in KumoMTA — and the Auto PMTA Configurator ships sensible per-ISP throttling for either, then adapts from the responses each provider returns.

Tuning from the queues

Throttling values aren’t guesses you set once — they’re hypotheses you confirm against data. PowerMTA’s queue and status views show, per destination, how many messages are queued, how many connections are open, and whether a queue is in back-off, while the accounting logs record the deferral and bounce categories behind those numbers. A provider whose queue is growing and showing rising 4xx deferrals is telling you its current limit is too high for your standing; one delivering cleanly with a small steady queue has headroom you can carefully use.

So the loop is: set conservative limits, watch each provider’s queue and deferral rate, and adjust the specific family that’s struggling — lower its max-smtp-out or max-msg-rate, or tighten its pattern list — rather than touching a global setting. Because settings are per domain and per vMTA, you can isolate the exact queue that needs attention and leave the healthy ones alone. This is the same per-IP, per-provider visibility that pools and vMTAs give you, applied to the question of rate.

Start conservative, then iterate

If there’s a single rule for throttling, it’s to begin below where you think you need to be and ramp upward on evidence, rather than starting high and backing down after the damage. Deferrals from over-sending don’t just delay the current batch — sustained, they erode the reputation that sets your ceiling, so an aggressive start can leave you permanently able to send less than a patient one would have. The conservative opening is not timidity; it’s the faster route to a high sustained rate.

From there, change one thing at a time and observe before changing the next. Raise a provider’s rate, watch a few days of deferral data, and only then raise it again; if deferrals climb, step back. This measured iteration is exactly what warm-up formalises for new IPs, and it never really stops — providers adjust their own thresholds, your reputation shifts, and the right rate drifts with them. Throttling well is an ongoing conversation with each receiver, conducted through the rates you set and the deferrals they return.

The long tail of small domains

The big providers get named blocks, but most lists also contain a long tail of small and corporate domains, and they need a different default. A small or self-hosted mail server is easily overwhelmed by the concurrency a large provider shrugs off, so the catch-all <domain *> policy should be conservative — a low max-smtp-out of one to a few connections — while the named families get higher ceilings:

<domain *>                  # the long tail: be gentle
    max-smtp-out 2
    max-msg-per-connection 100
</domain>

This protects the many small receivers from a level of concurrency they can’t handle, while your named provider blocks let the big mailbox families run faster where they can. It’s the scope cascade doing useful work: one careful default for everything, specific overrides for the destinations that warrant them. Forgetting the catch-all is a common omission — without it, the long tail inherits whatever global behaviour exists and small servers start deferring or blocking you for hammering them with more parallel connections than their hardware was ever built to accept, which is an easy way to collect blocklist entries from the very domains least likely to ever notice, document, or remove you from one.

The bottom line

Throughput is set by the receiver, not your hardware. Throttling is the ceiling you set in advance — per recipient domain, via <domain> blocks and domain-macro families — with max-smtp-out (concurrent connections) as the primary lever and max-msg-rate secondary, tuned per provider and never globally. Back-off is the reaction: a <smtp-pattern-list> matches a provider’s rate or reputation replies and slows the queue through backoff-max-msg-rate, backoff-retry-after and backoff-to-normal-after.

Keep concurrency low (connections trip limits before rate does), bounce persistently unreachable mailboxes rather than retrying forever, start conservative and ramp during warm-up, and tune back-off precisely so queues recover promptly. Treat deferrals as feedback, not noise. KumoMTA does the same with Lua shaping. If you’d rather not hand- tune directives per ISP, the Auto PMTA Configurator ships adaptive per-provider throttling, deferral back-off and warm-up curves out of the box, and our managed deliverability service tunes them against real responses — for legitimate, opt-in sending.

Frequently asked questions

What's the difference between throttling and back-off in PowerMTA? +

Throttling is the ceiling you set in advance — how many messages per hour and how many simultaneous connections a virtual MTA may use for a destination. Back-off is the reaction: when a receiver returns temporary failures (4xx), PowerMTA slows down and retries later instead of hammering the door. You configure both; they work together to keep you inside each provider's tolerance.

What rate should I start at? +

Lower than you think, then ramp. There's no universal number — it depends on your reputation, the receiver and your IP's age. A new IP sends a small, conservative volume that grows over days; an established IP to a tolerant provider can sustain far more. The signal to listen to is the receiver's own responses: rising deferrals mean you're pushing too hard. This is the heart of IP warm-up.

Should I throttle per IP, per domain, or per provider? +

Per provider, expressed through your virtual MTAs and pattern lists. Gmail, Microsoft and Yahoo each have different tolerances, so you group destinations and apply limits per group rather than one global cap. Pattern lists and MX rollups are how you bucket those destinations so a single set of limits covers each provider family.

Does aggressive throttling hurt deliverability? +

Throttling that's too loose hurts it — exceeding a receiver's rate triggers deferrals and, sustained, reputation damage. Throttling that's appropriately conservative protects it. The goal isn't to send as fast as possible; it's to send as fast as the receiver will cleanly accept, which is almost always slower than your hardware could manage.

How does the Auto PMTA Configurator handle this? +

It applies adaptive per-ISP throttling out of the box — sensible starting limits per provider family, back-off on deferrals, and warm-up curves that ramp new IPs gradually — then adjusts based on the responses each provider returns. You get a tuned baseline instead of guessing at directives on day one.

Related