How a Dutch B2B SaaS platform eliminated transactional email contention with marketing campaigns by replacing a shared Postfix queue with listener-port-separated PowerMTA infrastructure — sustaining 38-second median 2FA delivery during 600,000-message marketing bursts and recovering 9–14 percentage points of trial-conversion rate.
A Dutch B2B SaaS platform headquartered in Utrecht serves 400,000 users across Western Europe through a workflow-automation product used predominantly inside corporate IT environments. Email is operationally critical for the product's core functions: two-factor authentication codes that gate access to user accounts, password resets that recover credentials, billing alerts that notify account administrators of upcoming charge events, trial-expiration warnings that drive conversion at the most consequential moment in the user funnel, and webhook-failure notifications that surface integration problems to the customer's technical contacts. Each of these messages has a hard delivery requirement: a 2FA code that arrives 8 minutes after the user requested it is functionally useless because the user has already abandoned the login attempt or requested a second code, and a trial-expiration warning that arrives after the trial has expired produces a paying-customer-conversion event that the platform's economics depend on getting right.
By 2024, the platform was sending approximately 2 million transactional messages and 8 million marketing emails per month through a single Postfix-based SMTP relay configured without traffic separation. The deliverability metric that the marketing team tracked — aggregate inbox placement averaged across 30-day windows — looked acceptable. The problem manifested quarterly, predictably, when the marketing team executed a major product-announcement campaign or quarterly newsletter blast. During each campaign window, transactional delivery times spiked from a normal average of 45 seconds to 12–18 minutes, support tickets categorized as "didn't get my 2FA code" climbed by 340% within hours of the campaign send, and trial-conversion rate measured during the same windows dropped 9–14 percentage points below baseline. The marketing team and the product team had been treating these as separate problems for over a year.
Presenting Problems
- 2FA codes averaging 12–18 minutes delivery during marketing campaign windows; SLA target of under 2 minutes was being met during normal hours but not during the marketing-burst windows that mattered most for product reliability perception
- Password reset emails delayed by 6–11 minutes during campaign windows, with measurable downstream impact: support-ticket volume categorized as "password reset not received" spiked 340% within four hours of every marketing send
- Trial-conversion rate dropping 9–14 percentage points below baseline during campaign-week windows when trial-expiration warnings overlapped with marketing-burst delivery delays — the highest-stakes operational moment in the funnel was being affected by an infrastructure decision the product team had not been part of
- Transactional and marketing email sharing the same Postfix queue with no priority differentiation — FIFO processing meant that a 500,000-message campaign entering the queue simultaneously with a 2FA request placed the 2FA code behind 12,000–40,000 campaign messages
- No per-ISP throttling — Postfix attempted maximum connections simultaneously, triggering Gmail and Outlook rate-limiting that then throttled the entire IP for 3–5 hours and affected every transactional message during that window
- Marketing-campaign reputation events (occasional complaint-rate spikes from a particular campaign segment) producing IP-level reputation degradation that affected transactional delivery at recipients who would never have unsubscribed from operational mail — collateral damage from marketing behaviour
- No instrumentation for per-message latency at the queue level — the platform was unable to measure the problem precisely until custom logging was added during the engagement
We instrumented the existing Postfix queue with custom logging to measure per-message delivery latency during a live campaign send. The data showed the problem clearly: the Postfix queue was processing messages in FIFO order. When a 500,000-message campaign entered the queue simultaneously with 2FA requests, 2FA messages waited behind 12,000–40,000 campaign messages for queue processing. The latency was not random — it was structurally predictable from the queue ordering, and it was concentrated precisely in the windows where the platform's user experience was most sensitive to it.
The secondary problem was ISP throttling: sending 500,000 messages to Gmail in a burst caused Gmail to apply connection-rate limits that then throttled the entire IP for 3–5 hours. The throttling affected every subsequent message from that IP during the throttle window, including transactional messages that had nothing to do with the marketing campaign that triggered the rate limit. The Postfix configuration had no awareness of this — it continued attempting to deliver transactional messages on a throttled IP at the same rate it had been using before the throttle was applied, generating deferral retries that compounded the queue depth without resolving the underlying constraint.
Transactional Delivery Time — Campaign vs Non-Campaign Windows
The solution required complete traffic-class separation at the infrastructure level — not just priority queuing within a shared system. Priority queues within a shared MTA still produce contention because they share the underlying connection pool, the same per-IP throttle state, and the same reputation surface at the receiving ISP. Isolated infrastructure eliminates the contention rather than managing it. The PowerMTA architecture replacing the Postfix relay used listener-port-based routing to enforce the separation at the application boundary: the application's transactional sender connects to one listener and is routed to one IP pool, the marketing sender (MailWizz in this deployment) connects to a different listener and is routed to a different IP pool, and there is no path by which traffic from one listener can affect throughput on the other.
Transactional Delivery Time (seconds) — 12 Weeks
(from 780s during campaigns)
within 2-minute SLA
email delivery delays
transactional delivery
Technical Assessment: Infrastructure Layers Examined
The post-cutover assessment examined three operational layers that became visible only after the listener-port architecture was in place: the relationship between per-pool authentication and reputation isolation, the calibration of per-ISP throttles for the transactional pool's specific characteristics, and the operational practices that distinguish a transactional sending stream from a marketing one in ways that go beyond the queue-separation foundation.
Per-Pool Authentication for Reputation Isolation
The two pools sign messages with separate DKIM keys under separate selectors — the transactional pool uses trans2024._domainkey.platform.nl, the marketing pool uses mkt2024._domainkey.platform.nl. This separation matters operationally because some receiving ISPs aggregate reputation by DKIM signing identity in addition to (or sometimes instead of) sending-IP reputation. A complaint-rate event on the marketing pool affects only the marketing DKIM identity's reputation; transactional messages signed with a different identity are evaluated independently. The combination of dedicated IPs and dedicated DKIM keys produces reputation isolation at every layer that receiving infrastructure considers.
Per-Pool PowerMTA Domain Block Configuration
The transactional pool's per-domain configuration reflects its operational requirements: aggressive delivery with no msg-rate limits at Gmail or Outlook (the volumes are low enough that rate-limiting is unnecessary), short retry intervals on 421 deferrals (15 seconds rather than the marketing pool's 20 minutes — transactional messages cannot afford the long backoff that is appropriate for marketing), and a higher max-smtp-out per IP than the marketing pool because the transactional pool's traffic shape never produces sustained high throughput, only short bursts of individual messages. The marketing pool has the conservative configuration appropriate for high-volume sending: max-msg-rate 300/h at Gmail per IP, max-smtp-out 6, retry-after 20m on deferrals. The two configurations would be incompatible if applied to the same IPs; the architecture's value is that they don't have to be.
Authentication Upgrade Across Both Pools
DKIM keys on both pools were rotated to 2048-bit RSA. SPF was configured to include only the dedicated IPs from each pool — six IPs total in the SPF record, with no third-party includes for services that had been retired or were no longer relevant. DMARC progressed from p=none through p=quarantine to p=reject over the engagement period, with aggregate-report processing routed to a dedicated address that the operations team reviewed weekly. The DMARC aggregate reports surfaced two non-pool senders that the platform had not catalogued — both were remediated before DMARC reached p=reject.
Infrastructure Rebuild: Configuration Decisions
Listener-port routing as the architectural enforcement boundary. The application's transactional code commits an integration contract: it sends to port 2525, with credentials that authorize only the transactional pool. The marketing tooling commits a different contract: port 2526, credentials authorising only the marketing pool. Crossover is impossible at the network and authentication layer, not just at the queue layer. This matters because queue-based separation depends on the discipline of routing decisions made by the application; listener-port separation removes the possibility of routing errors entirely. A misconfigured transactional component cannot accidentally send marketing traffic through the transactional pool, because the credentials it has do not authorize that.
Independent accounting logs per pool for forensic clarity. Each pool produces independent accounting logs. When an issue surfaces — a deferral pattern, a complaint spike, an inbox-placement change — the logs are pre-segmented by pool, and the analysis does not require disambiguating which messages were transactional and which were marketing within an aggregated log. This dramatically reduces the time to root-cause for any operational incident; the operations team has reported a 70% reduction in time-to-diagnosis for delivery anomalies since the per-pool log architecture was introduced.
Pool-specific FBL processing pipelines. Complaint feedback loops are subscribed independently per pool at every ISP that supports them. A complaint on the marketing pool flows to a marketing-team queue and is processed against the marketing suppression registry. A complaint on the transactional pool — which is rare, because transactional content is rarely complained about — flows to an operations-team queue and triggers an investigation, because a transactional complaint usually indicates a product issue (a notification frequency the user did not consent to, a misdirected message) rather than a marketing-frequency complaint. Treating these as different operational signals, with different response paths, surfaces the two issue classes separately rather than averaging them in a unified complaint dashboard.
Operational Monitoring: What Changed Permanently
Per-pool latency SLAs as primary operational metrics. The transactional pool has a 2-minute median delivery SLA and a 5-minute 95th-percentile SLA. The marketing pool has no latency SLA — its operational metric is throughput per hour during campaign windows. Treating these as different metrics, monitored on different dashboards, surfaces drift in the metric that matters for each pool. The transactional pool's median delivery time is reviewed at 5-minute granularity during business hours; the marketing pool's throughput is reviewed campaign-by-campaign as part of post-campaign analysis. Aggregating these two streams' metrics on a single dashboard would obscure the leading indicators each stream actually requires.
Pre-campaign coordination protocol. Before any marketing campaign exceeding 100,000 messages is executed, the marketing operations team notifies the platform operations team through a Slack channel that surfaces the scheduled send time, expected volume, and target segment. The notification is not a permission request — the architecture means marketing campaigns no longer affect transactional delivery — but it gives the platform operations team awareness of expected volume on the marketing pool, allowing them to distinguish a planned campaign-induced reputation event from an unexpected one. Two campaigns in the post-migration year produced complaint-rate spikes that required investigation; both investigations completed within the campaign window because the operations team knew the campaigns were running.
Quarterly trial-conversion correlation review. The product team's trial-conversion metric is correlated quarterly against email delivery metrics for the trial-expiration warning sequence. The pre-migration correlation showed that trial-conversion rate during marketing-campaign weeks was 9–14 percentage points below baseline; the post-migration correlation shows no measurable difference between campaign weeks and non-campaign weeks. The metric that proved the architecture worked was not a deliverability metric — it was a product metric whose recovery was the engagement's actual business case.
"We had been treating delivery delay as a capacity problem — assumed we just needed a bigger server. The infrastructure team showed us it was an architecture problem: priority queuing within a shared MTA still produces contention because everything shares the same per-IP state at the receiving ISP. The fix was not more resources, it was separate lanes — separate listeners, separate IPs, separate DKIM keys. The support-ticket reduction paid for the infrastructure change in the first month. The trial-conversion recovery, which we did not initially attribute to the email infrastructure, was where the actual business case turned out to live."
— VP Engineering, Dutch SaaS PlatformThe technical changes in this engagement were straightforward. The more significant work was establishing the monitoring discipline that prevents the gradual drift that caused the original problems — an infrastructure that meets today's ISP requirements but has no ongoing review process will fall behind those requirements within 12-18 months.
— Cloud Server for Email Infrastructure TeamTransactional and marketing email are different operational categories, not different priority levels of the same category. Treating them as the same workload with priority differentiation — which is the architectural pattern most general-purpose MTAs default to — produces the queue-contention and reputation-coupling effects that this engagement resolved. The architectural pattern that works is not "transactional has higher priority"; it is "transactional and marketing run on infrastructure that does not share state". Listener-port separation enforces that distinction at the application boundary, which removes the possibility of routing errors and produces clean operational separation that scales without additional engineering effort.
The business case for transactional infrastructure separation is most often expressed in deliverability metrics (delivery time, SLA compliance, support-ticket reduction), but the deeper case is usually in product metrics that the deliverability team does not directly own. Trial-conversion rate, account-activation rate, password-recovery completion rate, 2FA success rate — all of these are influenced by transactional email reliability in ways that aggregate inbox-placement metrics do not surface. Engagements that frame the work in terms of product-funnel impact rather than purely email metrics produce business-case clarity that is harder to reach from the email-metrics view alone.