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
6 changes: 3 additions & 3 deletions content/momentum/4/config-options-summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ The `Version` column indicated the version(s) of Momentum that support the optio
| [http_method](/momentum/4/config/ref-http-method) – Define the HTTP method to use | sending | POST | 4.0 and later | binding, binding_group, domain, global |
| [http_uri](/momentum/4/config/ref-http-uri) – Define the HTTP URI that you wish to connect to | sending |   | 4.0 and later | binding, binding_group, domain, global |
| [http_version](/momentum/4/config/ref-http-version) – Define the HTTP version to use | sending | 1.1 | 4.0 and later | binding, binding_group, domain, global |
| **idle_time** – Number of seconds of inactivity before a client is disconnected | receiving | 300 | 4.0 and later | esmtp_listener, http_listener, listen, pathway, pathway_group, peer, xmpp_listener |
| [idle_time](/momentum/4/config/ref-idle-time) – Number of seconds of inactivity before a client is disconnected | receiving | 300 | 4.0 and later | esmtp_listener, http_listener, listen, pathway, pathway_group, peer, xmpp_listener |
| [idle_timeout](/momentum/4/config/ref-idle-timeout) – Time to maintain idle outbound connections | sending | 5 | 4.0 and later | binding, binding_group, domain, global |
| [if_check_interval](/momentum/4/modules/4-modules-cluster#option.if_check_interval) – How often to run through a maintenance cycle (cluster-specific) | na | 30 | 4.0 and later | cluster |
| [if_down_limit](/momentum/4/modules/4-modules-cluster#option.if_down_limit) – How long to wait before deciding to bring an IP online (cluster-specific) | na | 4 | 4.0 and later | cluster |
Expand All @@ -211,7 +211,7 @@ The `Version` column indicated the version(s) of Momentum that support the optio
| [license](/momentum/4/config/ref-license) – Specify an alternate license location | na | /opt/msys/ecelerity/etc (*non-dynamic*) | 4.0 and later | global |
| [listen](/momentum/4/listeners#listeners.enable.option) *(scope)* – Specify the socket that a listener listens on | receiving |   | 4.0 and later | control_listener, ecstream_listener, esmtp_listener, http_listener, msgcserver_listener, xmpp_listener |
| **listen_backlog** – Listen backlog | receiving | 500 (*3.0*) | 4.0 and later | control_listener, eccluster_listener, ecstream_listener, esmtp_listener, http_listener, listen, xmpp_listener |
| **listener_sessions** – Specifies the maximum number of concurrent sessions that can be established to this listener | receiving | 0 | 4.0 and later | esmtp_listener, listen, pathway, pathway_group, peer |
| [listener_sessions](/momentum/4/config/ref-listener-sessions) – Specifies the maximum number of concurrent sessions that can be established to this listener | receiving | 0 | 4.0 and later | esmtp_listener, listen, pathway, pathway_group, peer |
| [lmtp_port](/momentum/4/config/ref-lmtp-port) – Configure the port for LMTP deliveries | sending | 2003 | 4.0 and later | binding, binding_group, domain, global |
| [local_changes_file](/momentum/4/config/ref-local-changes-file) – File for writing local configuration changes | na | /opt/msys/ecelerity/etc/local_changes.conf | 4.0 and later | global |
| [local_changes_only](/momentum/4/config/ref-local-changes-only) – Whether there is a file for writing local configuration change | na | false | 4.0 and later | global |
Expand Down Expand Up @@ -321,7 +321,7 @@ The `Version` column indicated the version(s) of Momentum that support the optio
| [server_max_file_descriptors](/momentum/4/config/ref-server-max-file-descriptors) – Sets the maximum number of file descriptors usable by the system | na | 3000000 | 4.0 and later | global |
| [server_max_outbound_connections](/momentum/4/config/ref-server-max-outbound-connections) – Sets the maximum number of outbound connections | sending | 20000 | 4.0 and later | binding, binding_group, global |
| [server_reserve_outbound_connections](/momentum/4/config/ref-server-reserve-outbound-connections) – Sets the server-wide connection limit reserve | sending | 200 | 4.0 and later | global |
| **service_sessions** – Specifies the maximum number of concurrent sessions that can be established to all listeners for this service (e.g., ESMTP, ECStream) | receiving | 0 | 4.0 and later | esmtp_listener, listen, pathway, pathway_group, peer |
| [service_sessions](/momentum/4/config/ref-service-sessions) – Specifies the maximum number of concurrent sessions that can be established to all listeners for this service (e.g., ESMTP, ECStream) | receiving | 0 | 4.0 and later | esmtp_listener, listen, pathway, pathway_group, peer |
| [signing_stats](/momentum/4/config/ref-signing-stats) – Control how signing statistics are recorded | sending | all | 4.0 and later | global |
| [siv_throttle_cache_size](/momentum/4/config/ref-siv-throttle-cache-size) – Set the maximum number of named throttles | both | 100, 1000 (*3.0.24*) | 4.0 and later | global |
| [skip_hosts](/momentum/4/config/ref-skip-hosts) – Skip the specified host, but consider other hosts in the domain | sending |   | 4.2.1.6 and later | global |
Expand Down
50 changes: 50 additions & 0 deletions content/momentum/4/config/ref-idle-time.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
lastUpdated: "06/24/2026"
title: "Idle_Time"
description: "idle time specifies the number of seconds of inactivity before an inbound client connection is disconnected It recycles idle session slots so that concurrency caps such as listener sessions and service sessions are not held by idle connections."
---

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

Idle_Time — number of seconds of inactivity before an inbound client is disconnected.

## Synopsis

`Idle_Time = 300`

<a name="idp.idle_time"></a>
## Description

`Idle_Time` sets the number of seconds an inbound client connection may remain idle before Momentum disconnects it. It is the primary mechanism for reclaiming session slots held by connections that are no longer doing useful work, and it works hand-in-hand with the inbound concurrency caps [Listener_Sessions](/momentum/4/config/ref-listener-sessions) and [Service_Sessions](/momentum/4/config/ref-service-sessions): because a session slot is held for the entire life of a connection, reaping idle connections frees slots that would otherwise count against those caps.

The default for this option is `0`, which means connections are never reaped for inactivity. The `ecelerity.conf` file shipped with Momentum sets `Idle_Time` to `300`, which is the recommended value.

Like the session caps, `Idle_Time` can be set per source block by placing it inside a `Peer` (CIDR) scope — for example, a longer idle window for trusted senders and a shorter one for everyone else:

```
ESMTP_Listener {
Idle_Time = 60

Peer "10.0.0.0/8" { # trusted senders: longer idle window
Idle_Time = 300
}
Peer "0.0.0.0/0" { # everyone else: faster reaping
Idle_Time = 30
}
}
```

### Caveats

`Idle_Time` only reaps connections that the event loop is actively watching, and only when the loop is free. Under saturation it fires late, and it will not reap connections parked for asynchronous work. It recycles idle session slots, but it will not clear every lingering connection — it is not a substitute for addressing connections that fail to close.

<a name="idp.idle_time.scope"></a>
## Scope

`Idle_Time` is valid in the esmtp_listener, http_listener, listen, pathway, pathway_group, peer, and xmpp_listener scopes.

<a name="idp.idle_time.seealso"></a>
## See Also

[Listener_Sessions](/momentum/4/config/ref-listener-sessions), [Service_Sessions](/momentum/4/config/ref-service-sessions), [Listeners](/momentum/4/listeners), [Configuring Inbound Mail Service Using SMTP](/momentum/4/esmtp-listener)
80 changes: 80 additions & 0 deletions content/momentum/4/config/ref-listener-sessions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
lastUpdated: "06/24/2026"
title: "Listener_Sessions"
description: "listener sessions specifies the maximum number of concurrent inbound sessions that can be established to this listener When the cap is reached new connections receive a retryable 421 4 4 5 response and are closed Use Peer CIDR scopes to partition the cap per source block."
---

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

Listener_Sessions — maximum number of concurrent inbound sessions for a single listener.

## Synopsis

`Listener_Sessions = 0`

<a name="idp.listener_sessions"></a>
## Description

`Listener_Sessions` caps the number of concurrent inbound sessions that may be established to *this* listener (for example, the `ESMTP_Listener`). It is a circuit-breaker that protects a node from being overwhelmed by inbound concurrency.

A session slot is held for the entire life of a connection — including time spent idle or otherwise lingering — and is only released when the connection is fully closed. While the cap is reached, every new connection in the same scope is rejected, including legitimate mail, until a slot is freed.

When the cap is reached, the connection is given a clean, retryable response and is closed:

```
421 4.4.5 Service unavailable, concurrency limit reached.
```

The default value is `0`, which means *no limit*.

### Scope, fallback, and per-source caps

`Listener_Sessions` is a *per-scope aggregate*, not a per-IP limit. How the active sessions are counted depends on the scope in which the option is set:

* When set **outside** a `Peer` scope (directly in the `ESMTP_Listener` or a `Listen` scope), the cap is a single shared budget summed across **all** connecting sources. A few noisy sources can consume the entire budget.

* When set **inside** a `Peer` (CIDR) scope, sessions are counted **per matching CIDR block**, so each source block gets its own independent budget.

Because `Peer` scopes use most-specific-match fallback, you can partition a broad cap into narrower per-source budgets, and apply tighter caps to known offenders. For more information about fallback, see [“Configuration Scopes and Fallback”](/momentum/4/4-ecelerity-conf-fallback).

The following example sets an absolute ceiling on the listener, a larger budget for a trusted subnet, and a tighter budget for everyone else:

```
ESMTP_Listener {
Listener_Sessions = 1800 # ceiling for this listener
Idle_Time = 60

Peer "10.0.0.0/8" { # trusted senders: larger budget
Listener_Sessions = 1500
Idle_Time = 300
}
Peer "0.0.0.0/0" { # everyone else: tighter cap, faster reaping
Listener_Sessions = 600
Idle_Time = 30
}

Listen ":25" {
Listener_Sessions = 1800
Idle_Time = 60
}
}
```

### Caveats

* **The cap counts lingering connections too.** A slot is held for the connection's whole life, including while it is stuck. If connections keep lingering, the cap fills with them and then rejects all new connections in that scope. It is a circuit-breaker, not a cure for connections that fail to close.

* **It is a per-scope aggregate, not per-IP.** A broad cap is one shared budget that a few noisy sources can consume. Partition it with narrower `Peer` scopes, and use specific tight scopes (or upstream firewalling) for known offenders.

To cap concurrency across *all* listeners for a service rather than a single listener, see [Service_Sessions](/momentum/4/config/ref-service-sessions).

<a name="idp.listener_sessions.scope"></a>
## Scope

`Listener_Sessions` is valid in the esmtp_listener, listen, pathway, pathway_group, and peer scopes.

<a name="idp.listener_sessions.seealso"></a>
## See Also

[Service_Sessions](/momentum/4/config/ref-service-sessions), [Idle_Time](/momentum/4/config/ref-idle-time), [Listeners](/momentum/4/listeners), [Configuring Inbound Mail Service Using SMTP](/momentum/4/esmtp-listener)
75 changes: 75 additions & 0 deletions content/momentum/4/config/ref-service-sessions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
---
lastUpdated: "06/24/2026"
title: "Service_Sessions"
description: "service sessions specifies the maximum number of concurrent inbound sessions that can be established to all listeners for a service such as ESMTP or ECStream When the cap is reached new connections receive a retryable 421 4 4 5 response and are closed Use Peer CIDR scopes to partition the cap per source block."
---

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

Service_Sessions — maximum number of concurrent inbound sessions across all listeners for a service.

## Synopsis

`Service_Sessions = 0`

<a name="idp.service_sessions"></a>
## Description

`Service_Sessions` caps the number of concurrent inbound sessions that may be established across **all** listeners for a given service (for example, ESMTP or ECStream). This differs from [Listener_Sessions](/momentum/4/config/ref-listener-sessions), which limits a single listener: where several listeners serve the same service (for example, an `ESMTP_Listener` bound to ports 25, 587, and a Unix socket), `Service_Sessions` is the shared ceiling across all of them.

A session slot is held for the entire life of a connection — including time spent idle or otherwise lingering — and is only released when the connection is fully closed. While the cap is reached, every new connection in the same scope is rejected, including legitimate mail, until a slot is freed.

When the cap is reached, the connection is given a clean, retryable response and is closed:

```
421 4.4.5 Service unavailable, concurrency limit reached.
```

The default value is `0`, which means *no limit*.

### Scope, fallback, and per-source caps

`Service_Sessions` is a *per-scope aggregate*, not a per-IP limit. How the active sessions are counted depends on the scope in which the option is set:

* When set **outside** a `Peer` scope, the cap is a single shared budget summed across **all** connecting sources for the service. A few noisy sources can consume the entire budget.

* When set **inside** a `Peer` (CIDR) scope, sessions are counted **per matching CIDR block**, so each source block gets its own independent budget.

Because `Peer` scopes use most-specific-match fallback, you can partition a broad cap into narrower per-source budgets, and apply tighter caps to known offenders. For more information about fallback, see [“Configuration Scopes and Fallback”](/momentum/4/4-ecelerity-conf-fallback).

The following example sets a service-wide ceiling, a larger budget for a trusted subnet, and a tighter budget for everyone else:

```
ESMTP_Listener {
Service_Sessions = 2000 # absolute ceiling across all ESMTP sockets
Idle_Time = 60

Peer "10.0.0.0/8" { # trusted senders: larger budget
Service_Sessions = 1500
Idle_Time = 300
}
Peer "0.0.0.0/0" { # everyone else: tighter cap, faster reaping
Service_Sessions = 600
Idle_Time = 30
}
}
```

### Caveats

* **The cap counts lingering connections too.** A slot is held for the connection's whole life, including while it is stuck. If connections keep lingering, the cap fills with them and then rejects all new connections in that scope. It is a circuit-breaker, not a cure for connections that fail to close.

* **It is a per-scope aggregate, not per-IP.** A broad cap is one shared budget that a few noisy sources can consume. Partition it with narrower `Peer` scopes, and use specific tight scopes (or upstream firewalling) for known offenders.

To cap concurrency for a single listener rather than the whole service, see [Listener_Sessions](/momentum/4/config/ref-listener-sessions).

<a name="idp.service_sessions.scope"></a>
## Scope

`Service_Sessions` is valid in the esmtp_listener, listen, pathway, pathway_group, and peer scopes.

<a name="idp.service_sessions.seealso"></a>
## See Also

[Listener_Sessions](/momentum/4/config/ref-listener-sessions), [Idle_Time](/momentum/4/config/ref-idle-time), [Listeners](/momentum/4/listeners), [Configuring Inbound Mail Service Using SMTP](/momentum/4/esmtp-listener)
12 changes: 11 additions & 1 deletion content/momentum/4/esmtp-listener.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,18 @@ The `Pool_Name` option associates the `accept-pool` ThreadPool with the listener

When using threaded accepts for listeners, you must provision the thread pool you intend to use via the ThreadPool directive. If the thread pool you name is not found or is unspecified, the IO pool will be used and a critical message will appear in your log.

### <a name="esmtp_listener.concurrency"></a> Limiting Inbound Concurrency

You can cap the number of concurrent inbound sessions with two options:

* [Listener_Sessions](/momentum/4/config/ref-listener-sessions) – the maximum concurrent sessions for *this* listener.

* [Service_Sessions](/momentum/4/config/ref-service-sessions) – the maximum concurrent sessions across *all* listeners for the service (for example, all ESMTP sockets).

Both default to `0` (no limit). When a cap is reached, new connections receive a clean, retryable `421 4.4.5 Service unavailable, concurrency limit reached.` and are closed. The caps are a *per-scope aggregate*, not a per-IP limit: set them outside a `Peer` scope for a single shared budget, or inside `Peer` (CIDR) scopes to give each source block its own budget. Use [Idle_Time](/momentum/4/config/ref-idle-time) to reap idle session slots. See the linked reference pages for the full behavior and caveats.

For details about the non-module specific configuration options that are valid in the ESMTP_Listener and its nested scopes, refer to [*Configuration Options Summary*](/momentum/4/config-options-summary) .

Modules and their configuration options are discussed in the [*Modules Reference*](/momentum/4/modules/) .

For general information regarding listeners, see [“Listeners”](/momentum/4/listeners).
For general information regarding listeners, see [“Listeners”](/momentum/4/listeners).
Loading