Client reconnect jitter limits during NATS server drain
0 reputation · 26 Jan 2023, 03:43 UTC
0 reputation · 26 Jan 2023, 03:43 UTC
When preparing a zero‑downtime rolling upgrade of a small application that relies on NATS, the precise moment at which client libraries attempt to reconnect after a server drain determines whether transient message buffering spikes occur. Understanding this timing helps size buffers and choose safe drain intervals.
The NATS client libraries implement a reconnect back‑off strategy that is not guaranteed to be deterministic; the exact delay can vary between runs and across SDK versions, which makes it difficult to predict the window during which messages may accumulate in JetStream durable consumers. Knowing the default back‑off parameters, whether they can be tuned to cap jitter, and how durable consumer acknowledgments behave during this window is essential for planning the upgrade.
What is the default reconnect back‑off interval and jitter range used by the official NATS Go client after a drain event? Can the client be configured to limit the maximum reconnect delay or to use a fixed back‑off? How does enabling JetStream durable consumers affect observable message buffering during the reconnect window?
33275 reputation · 26 Jan 2023, 12:02 UTC
When a NATS server enters drain mode, it stops accepting new connections and keeps existing ones open until the configured drain_timeout expires. The Go client does not try to reconnect during that period; it simply waits for the server to close the connection. Once the server closes the socket, the client starts the normal reconnection loop.
ReconnectWait – the initial delay before the first retry (default 2 s).ReconnectWaitMax – the maximum delay after exponential back‑off (default 5 s).ReconnectJitterLimit – the random offset added to each retry (default 1 s).ReconnectJitterLimit and is applied on top of the exponential back‑off value.So the first retry will occur after roughly 2 s + [0‑1 s], the second after roughly 4 s + [0‑1 s], and so on, capped at 5 s + jitter.
ReconnectJitterLimit option can be set to any time.Duration you choose, e.g. nats.ReconnectJitterLimit(2 * time.Second).
0 or provide a custom ReconnectJitter function that returns 0.
max_consumers or max_wait_time limits are hit, the server may start dropping or pausing new messages.
max_wait_time, enable ack_wait tuning, or ensure your application can handle a burst of messages on reconnect.
fmt.Printf("Jitter limit: %v\n", conn.Opts.ReconnectJitterLimit)
nats-server -DV --drain_timeout 5s
-js and -DV) to watch backlog growth during the disconnect.
Could you share the NATS Go client version you are using and the drain timeout configured on the server? These details will confirm whether the defaults match the numbers above or if a newer release has adjusted them.
Use comments to ask for clarification. Post a solution as an answer.
33,275 reputation · 26 Jan 2023, 11:36 UTC
In the NATS Go client (v1.12.0 and later) the reconnect algorithm uses an exponential back‑off that starts at ReconnectWait (default 1 s) and doubles each attempt up to MaxReconnects or the built‑in cap (≈30 s). On each attempt a jitter value is added that is a random fraction of the current back‑off interval; by default the fraction is ±50 % (i.e., jitter ∈ [‑0.5·interval, +0.5·interval]). This means the jitter scales with the back‑off rather than being a fixed offset.
ReconnectJitter option to a time.Duration that represents the absolute bound, or provide a ReconnectJitterFunc that returns a value capped at your chosen limit.ReconnectWait to a fixed duration and ReconnectJitter to 0 yields a deterministic fixed‑interval reconnect loop.AckWait, messages may accumulate beyond the MaxPending limit, causing the server to block or drop new publishes.