FastLinkIt

Deliverability: throttling and warmup

Contacts & Mailingmailing4 min read

Applies automatically to every mailing — no setup required, but tunable

Two layered safeguards that protect your sender reputation when you ship at volume:

  1. Per-recipient-domain throttling — pace inbound traffic to each receiver (Gmail, Outlook, Yahoo, …) at the rate that provider tolerates from an unauthenticated sender.
  2. Sender-domain warmup — new verified sender domains start at a low daily send cap and ramp linearly to full speed over the first 30 days.

Both run inside MailingSenderService. Both are advisory bounds — recipients blocked by either gate are deferred to the next sweep / next UTC day, not lost.

Per-recipient-domain throttling

Token-bucket per destination domain. Each bucket starts full at the configured capacity and refills continuously at capacity / 60 tokens per second. When the bucket is empty, that recipient defers and the mailing flips back to Status = queued so the next 10s sweep picks it up.

Defaults

Receiver domain Per-minute cap
gmail.com / googlemail.com 100
outlook.com / hotmail.com / live.com / msn.com 60
icloud.com / me.com / mac.com 60
yahoo.com / yahoo.co.uk / ymail.com 30
aol.com / proton.me / protonmail.com 30
(everything else) 60

Override

In appsettings.json:

{
  "Mailing": {
    "Throttle": {
      "DefaultPerMinute": 60,
      "PerDomain": {
        "gmail.com": 150,
        "yourcompany.com": 0
      }
    }
  }
}
  • DefaultPerMinute = 0 — disable throttling globally
  • PerDomain.<host> = 0 — skip throttling for that one domain (useful for self-hosted internal MTAs where you control the inbound side)

Sender-domain warmup

When you verify a new sender domain, receivers have no history of you. A 5,000-recipient blast on day 1 looks identical to a spam-bot spinning up a fresh domain. Warmup ramps you up gradually so your reputation builds.

How the ramp works

Day-N daily cap = DailyCapDay1 * N, where N is the number of full days since your domain's DkimVerifiedAt timestamp.

With the defaults (DailyCapDay1 = 50, RampDays = 30):

Days since verification Daily cap
Day 1 50
Day 2 100
Day 3 150
Day 7 350
Day 14 700
Day 30 1,500
Day 31+ unlimited

Counter resets at UTC midnight per sender domain. Recipients beyond today's cap defer to tomorrow — the mailing's Status flips back to queued so the regular sender loop ships them then.

Override

{
  "Mailing": {
    "Warmup": {
      "Enabled": true,
      "DailyCapDay1": 50,
      "RampDays": 30
    }
  }
}

Set Enabled = false to disable warmup entirely (sends rely on throttling alone). Smaller DailyCapDay1 for more conservative ramps; larger if you have evidence your sender reputation is already healthy.

When warmup applies

Skipped when:

  • The mailing has no verified sender domain (platform default sender already has reputation — warmup would punish legitimate sends).
  • The sender domain's DkimVerifiedAt is null (DKIM not actually signing yet).
  • More than RampDays days have passed since DkimVerifiedAt.

Applies when sending from a verified SenderDomain row whose DKIM was verified within the last RampDays days.

How they layer

Both gates check on every recipient. The lower of the two wins:

  • New sender on day 1 — warmup caps you at 50/day total. Even Gmail's 100/min throttle won't let you ship more, because warmup runs first.
  • Established sender shipping to Gmail in a 5,000-recipient blast — warmup doesn't apply (day 30+), so Gmail's 100/min throttle paces you to roughly 6,000 sends/hour to gmail.com specifically.
  • Mixed receiver mailing in the middle of a warmup — both apply, you ship the warmup-bound count split across receiver buckets each minute.

Worked example — new newsletter sender

Mira just verified news.miracultureletter.com with DKIM 5 minutes ago. Her list is 8,400 contacts.

  1. Day 1: she queues the first issue. Warmup cap = 50. The first 50 recipients ship across the next ~1 minute (per-receiver throttle paces inside that minute). Remaining 8,350 defer to day 2.
  2. Day 2: cap = 100. 100 ship today. 8,250 defer.
  3. Day 30: cap = 1,500. By now Gmail and Outlook have seen Mira's signature ~30 days in a row at modest volumes — sender reputation is healthy.
  4. Day 31+: warmup off, only the per-receiver throttle paces sends.

Mira didn't have to think about any of this — both gates run automatically the moment a verified sender domain is in scope.

Rejoining the server...

Rejoin failed... trying again in seconds.

Failed to rejoin.
Please retry or reload the page.

The session has been paused by the server.

Failed to resume the session.
Please retry or reload the page.