Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions content/momentum/4/config-options-summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ The `Version` column indicated the version(s) of Momentum that support the optio
| [dns_failures_to_purge](/momentum/4/config/ref-dns-failures-to-purge) – Configure the maximum number of DNS lookups | sending | 10 | 4.0 and later | domain, global |
| [dns_fallback_to_tcp](/momentum/4/config/ref-dns-fallback-to-tcp) – Whether or not to fail over to TCP in place of UDP | both | false | 4.0 and later | global |
| [dns_max_udp_queries_per_port](/momentum/4/config/ref-dns-max-udp-queries-per-port) - Limit the number of DNS queries sent using the same UDP source port | sending | 0 | 5.2 and later | global |
| [dns_rate_limit_enabled](/momentum/4/config/ref-dns-rate-limit) - Enable or disable the DNS rate limiter | sending | false | 5.3 and later | global |
| [dns_rate_limit_max_queue](/momentum/4/config/ref-dns-rate-limit) - Maximum number of domains the rate limiter will hold while waiting for a token | sending | 100000 | 5.3 and later | global |
| [dns_rate_limit_mx_queries](/momentum/4/config/ref-dns-rate-limit) - Maximum number of MX DNS queries dispatched per period | sending | 100 | 5.3 and later | global |
| [dns_rate_limit_period](/momentum/4/config/ref-dns-rate-limit) - The period, in seconds, used by the DNS rate limiter | sending | 1 | 5.3 and later | global |
| [dns_udp_rcvbuf_size](/momentum/4/config/ref-dns-udp-buffer-size) - Set the size of the UDP socket receiving buffer used by DNS lookups | both | 0 | 5.2 and later | global |
| [dns_udp_sndbuf_size](/momentum/4/config/ref-dns-udp-buffer-size) - Set the size of the UDP socket sending buffer used by DNS lookups | both | 0 | 5.2 and later | global |
| [domain](/momentum/4/config/ref-domain) *(scope)* – Configure domain-specific options | sending |   | 4.0 and later | binding, binding_group, global |
Expand Down
4 changes: 4 additions & 0 deletions content/momentum/4/config/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ description: "This chapter provides the definitions of the configuration options
| [dns_failures_to_purge](/momentum/4/config/ref-dns-failures-to-purge) | configure the maximum number of DNS lookups |
| [dns_fallback_to_tcp](/momentum/4/config/ref-dns-fallback-to-tcp) | whether or not to fail over to TCP in place of UDP |
| [dns_max_udp_queries_per_port](/momentum/4/config/ref-dns-max-udp-queries-per-port) | limit the number of DNS queries sent using the same UDP source port |
| [dns_rate_limit_enabled](/momentum/4/config/ref-dns-rate-limit) | enable or disable the DNS rate limiter |
| [dns_rate_limit_max_queue](/momentum/4/config/ref-dns-rate-limit) | maximum number of domains the rate limiter will hold while waiting for a token |
| [dns_rate_limit_mx_queries](/momentum/4/config/ref-dns-rate-limit) | maximum number of MX DNS queries dispatched per period |
| [dns_rate_limit_period](/momentum/4/config/ref-dns-rate-limit) | the period, in seconds, used by the DNS rate limiter |
| [dns_udp_rcvbuf_size](/momentum/4/config/ref-dns-udp-buffer-size) | set the size of the UDP socket receiving buffer used by DNS lookups |
| [dns_udp_sndbuf_size](/momentum/4/config/ref-dns-udp-buffer-size) | set the size of the UDP socket sending buffer used by DNS lookups |
| [domain_for_unqualified_recipient_addresses](/momentum/4/config/ref-domain-for-unqualified-recipient-addresses) | configure a domain which will be used to resolve delivery for unqualified addresses |
Expand Down
71 changes: 71 additions & 0 deletions content/momentum/4/config/ref-dns-rate-limit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
---
lastUpdated: "07/01/2026"
title: "dns_rate_limit_enabled, dns_rate_limit_mx_queries, dns_rate_limit_period, dns_rate_limit_max_queue"
description: "dns_rate_limit_* configuration options that limit the rate at which Momentum dispatches DNS queries, to prevent bursts that may overwhelm the DNS infrastructure"
---

<a name="conf.ref.dns_rate_limit"></a>
## Name

dns_rate_limit_enabled — enable or disable the DNS rate limiter

dns_rate_limit_mx_queries — maximum number of MX DNS lookups dispatched per period

dns_rate_limit_period — length of the rate limit window, in seconds

dns_rate_limit_max_queue — maximum number of domains the rate limiter will hold while waiting for a token
Comment thread
deepakpn marked this conversation as resolved.

## Synopsis

`dns_rate_limit_enabled = true`

`dns_rate_limit_mx_queries = 500`

`dns_rate_limit_period = 1`

`dns_rate_limit_max_queue = 50000`

<a name="idp69437300"></a>
## Description

Momentum initiates an MX lookup each time a new destination domain enters the internal lookup table and each time a cached domain record expires and must be refreshed. Under normal traffic the resulting query rate is manageable, but several conditions can produce sudden, large bursts:

- Traffic spikes that bring in messages for thousands of distinct domains within a few seconds.
- TTL expiry storms where many cached records expire at the same instant.
- Restart recovery, where the lookup table is repopulated from the spool and can fire tens of thousands of lookups in rapid succession.

These bursts can overwhelm the recursive resolver configured in `resolv.conf` — some resolvers enforce their own incoming query-rate caps, others simply drop packets under load — causing DNS timeouts, stalled deliveries, and degraded throughput - even though the MTA itself is healthy.

### How It Works

The DNS rate limiter caps the number of outgoing MX lookups Momentum issues per unit of time. When the cap is reached, new lookups are placed in a bounded in-memory queue and dispatched at the configured rate. If the queue itself fills up, the lookup is sent immediately as a safety-valve fallback rather than being dropped.

### Configuration Options

`dns_rate_limit_enabled` turns the rate limiter on or off. The default value is `false` (disabled), in which case MX lookups go out as before and no queue is maintained. **Changing this option requires Momentum to be restarted.**

`dns_rate_limit_mx_queries` sets the maximum number of MX domain lookups that may be dispatched within each `dns_rate_limit_period`-second window. The budget is counted per domain lookup, not per UDP packet (see *Caveats* below). The default value is `100`. The value must be positive and can be changed with a configuration reload; the new limit becomes effective on the next drain cycle.

`dns_rate_limit_period` sets the length of the rate limit window, in seconds. `dns_rate_limit_mx_queries` lookups are permitted within each window. A period of `1` gives the smoothest rate, closest to a true per-second limit; larger values allow more burstiness within the window. Note that `dns_rate_limit_mx_queries = 200` with `dns_rate_limit_period = 2` is **not** equivalent to 100 lookups per second — it permits a total of 200 lookups across the 2-second window, so for example 180 lookups in the first second leave only 20 lookups of budget for the second second. The default value is `1`. The value must be positive and can be changed with a configuration reload.

`dns_rate_limit_max_queue` sets the maximum number of domains that may be held in the rate limiter queue waiting for a token. A domain that is already queued is not enqueued a second time. Size the queue large enough to absorb the burst expected between drain cycles (roughly 100 ms); raising it uses more memory, and lowering it below the expected burst size increases the likelihood of overflow events. When the queue is full, new domains bypass the rate limiter and are resolved immediately, which can temporarily exceed the configured query budget. The default value is `100000` and the minimum accepted value is `1000`. **Changing this option requires Momentum to be restarted.**

### Statistics

Counters reported by the `summary` [console command](/momentum/4/console-commands/summary) and the [HTTP API endpoint](/momentum/4/http-api-stats/summary) — `Immediate`, `Queued`, `Drained` and `Overflow` — can be used to evaluate whether the configured rate and queue size are appropriate for the workload. A healthy system under light-to-moderate load shows mostly `Immediate` increments. A system hitting its limit intentionally shows `Queued` and `Drained` growing in tandem. Persistent growth of `Overflow` means the queue or the configured rate is too small for the traffic volume — increase `dns_rate_limit_max_queue`, increase `dns_rate_limit_mx_queries`, or reduce the inbound message acceptance rate.

<a name="idp69437302"></a>
## Caveats

When the rate limiter is enabled, the internal DNS resolver library (c-ares) is forced to `attempts=1`. This reduces resilience to transient failures; ensure that the configured nameservers are reliable before enabling this feature.

The `rotate` option in `resolv.conf` cycles the starting nameserver round-robin across successive lookups, but combined with the forced `attempts=1` each nameserver is still attempted at most once per lookup, and only sequentially on timeout. When using `rotate` with multiple nameservers, take the nameserver count into account when sizing `dns_rate_limit_mx_queries`.

_Overflow is a safety valve, not a guarantee of delivery._ When the queue is full and a lookup bypasses the rate limiter, the configured rate is exceeded; if the resolver itself starts dropping or rate-limiting packets at that point, the resulting DNS timeouts may cause delivery delays.

TTL-expiry refreshes count against the same budget as lookups triggered by new messages. In environments with very high domain-cache churn, refreshes can consume a meaningful fraction of the configured limit.

<a name="idp69437301"></a>
## Scope

`dns_rate_limit_enabled`, `dns_rate_limit_mx_queries`, `dns_rate_limit_period` and `dns_rate_limit_max_queue` are valid in the global scope.
22 changes: 22 additions & 0 deletions content/momentum/4/console-commands/summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Summary Statistics
Query Rate: 9.08 queries/second
DNS Response Time Peak: 469 ms
DNS Response Time Average: 0.302 ms
DNS Rate Limiter: disabled
Successfully Delivered Messages: 2102439
Failed Messages: 2508439
Rejected Messages: 1
Expand Down Expand Up @@ -220,6 +221,27 @@ The average of all answers response times since startup or last summary reset, i

</dd>

<dt>DNS Rate Limiter</dt>

<dd>

_Introduced in Momentum 5.3._

Whether the [DNS rate limiter](/momentum/4/config/ref-dns-rate-limit) is `enabled` or `disabled`. When the console session is in debug mode and the rate limiter is enabled, additional fields are reported:

```
DNS Rate Limit: 500 MX queries per 1 seconds
DNS Rate Limiter Queue: 42 / 50000
DNS Rate Limiter Immediate: 18340
DNS Rate Limiter Queued: 4120
DNS Rate Limiter Drained: 4078
DNS Rate Limiter Overflow: 0
```

`Immediate` counts MX lookups dispatched without queueing (within the per-period budget); `Queued` counts lookups that had to wait in the queue; `Drained` counts lookups dispatched from the queue; `Overflow` counts lookups that bypassed the rate limiter because the queue was full.

</dd>

<dt>Successfully Delivered Messages</dt>

<dd>
Expand Down
79 changes: 79 additions & 0 deletions content/momentum/4/http-api-stats/summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ Sample output is shown below:
"DNSQueryRate": 2.25,
"DNSResponseTimePeak": 291,
"DNSResponseTimeAverage": 1.04,
"DNSRateLimiterEnabled": false,
"ResidentMessages": 120,
"DiskQueueProgress": " 29/ 29",
"DeliveredMessages": 516030153,
Expand Down Expand Up @@ -222,6 +223,84 @@ The average of all answers response times since startup or last summary reset, i

</dd>

<dt>DNSRateLimiterEnabled</dt>

<dd>

_Introduced in Momentum 5.3._

Whether the [DNS rate limiter](/momentum/4/config/ref-dns-rate-limit) is enabled (`true`) or disabled (`false`). When the rate limiter is enabled, the following additional fields are also reported:

<dl class="variablelist">

<dt>DNSRateLimitMXQueries</dt>

<dd>

The current value of [`dns_rate_limit_mx_queries`](/momentum/4/config/ref-dns-rate-limit) — the maximum number of MX DNS queries dispatched per `DNSRateLimitPeriod`.

</dd>

<dt>DNSRateLimitPeriod</dt>

<dd>

The current value of [`dns_rate_limit_period`](/momentum/4/config/ref-dns-rate-limit) — the period, in seconds, over which the MX query budget is enforced.

</dd>

<dt>DNSRateLimiterQueueSize</dt>

<dd>

The current number of domains waiting in the rate limiter queue for a token.

</dd>

<dt>DNSRateLimiterQueueMax</dt>

<dd>

The maximum number of domains that may be held in the rate limiter queue, as configured by [`dns_rate_limit_max_queue`](/momentum/4/config/ref-dns-rate-limit).

</dd>

<dt>DNSRateLimiterImmediate</dt>

<dd>

The total number of MX lookups dispatched without queueing — i.e. lookups that fit within the per-period budget — since startup or last summary reset.

</dd>

<dt>DNSRateLimiterQueued</dt>

<dd>

The total number of MX lookups that had to be queued to wait for a token since startup or last summary reset.

</dd>

<dt>DNSRateLimiterDrained</dt>

<dd>

The total number of MX lookups dispatched from the queue since startup or last summary reset.

</dd>

<dt>DNSRateLimiterOverflow</dt>

<dd>

The total number of MX lookups that bypassed the rate limiter because the queue was full since startup or last summary reset. A non-zero value indicates that [`dns_rate_limit_max_queue`](/momentum/4/config/ref-dns-rate-limit) may be too small for the workload.

</dd>

</dl>

</dd>

<dt>ResidentMessages</dt>

<dd>
Expand Down
1 change: 1 addition & 0 deletions content/momentum/changelog/5/5-3-0.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ This section will list all of the major changes that happened with the release o
| Feature | I-1064 | Added support for [license](/momentum/4/before-you-begin#momentum-license) signatures using ECDSA P-256 with SHA-256. |
| Feature | I-1214 | Removed `msys-nodejs` RPM from the Momentum bundle, to be replaced with the 3rd-party `nodejs` package. Node.js LTS 24+ must be installed separately from the system or a vendor repository. |
| Feature | I-1216 | Added the [log_hires_timestamp](/momentum/4/config/ref-log-hires-timestamp) option to emit microsecond-resolution timestamps in the `mainlog`, `bouncelog`, `rejectlog`, `paniclog`, custom logs, chunk logs, and message generation logs, preserving event ordering when reading multiple log files together. |
| Feature | TASK-198522 | New DNS configuration options to [rate-limit MX lookups](/momentum/4/config/ref-dns-rate-limit), preventing query bursts from overwhelming the DNS infrastructure. |
| Fix | TASK-227757 | [`ha_proxy_client`](/momentum/4/modules/ha-proxy-client) now re-resolves a hostname-based `ha_proxy_server` during each health check, so backend IP changes are picked up automatically without restart. |
Loading