Summary
htmx-ext-sse@2.2.4 (and src/sse/sse.js on main) still reconnects forever with no jitter after EventSource.CLOSED. The old XOR backoff (2 ^ retryCount) was fixed in 2.2.1; these two problems replaced it.
Happy to open a PR if you want one. CONTRIBUTING prefers an issue first for discussion, so this stops here until you say otherwise.
Current code
ensureEventSource's source.onerror in src/sse/sse.js (same in the 2.2.4 npm file):
if (source.readyState === EventSource.CLOSED) {
retryCount = retryCount || 0
retryCount = Math.max(Math.min(retryCount * 2, 128), 1)
var timeout = retryCount * 500
window.setTimeout(function() {
ensureEventSourceOnElement(elt, retryCount)
}, timeout)
}
1. No give-up
Math.min(retryCount * 2, 128) caps the delay at 64 seconds (128 * 500). There is no maximum-attempts check. A permanently unreachable endpoint is retried forever at 64s intervals for as long as the element stays in the DOM.
onopen resets retryCount to 0 after a successful reconnect, which is good for a transient outage. It does not bound a never-recovering endpoint.
2. No jitter
Math.random() went away with the XOR expression in 2.2.1. Every client that lost the connection at the same moment now retries in lockstep: 0.5s, 1s, 2s, 4s, … A server that just came back gets a thundering herd.
Not this issue
2.0.0–2.2.0 used Math.random() * (2 ^ retryCount) * 500 plus Math.min(7, retryCount + 1). That XOR / capped-counter bug is already gone. Please do not treat this as a request to restore that expression.
Suggested shape (not a patch)
- Stop after a finite number of failed attempts (or expose a max-attempts option;
Infinity can stay the default if you want today's behavior).
- Add jitter around the exponential delay so clients desynchronize.
- Keep the existing successful-open reset so a recovered stream does not stay at the 64s cap.
Verified against npm htmx-ext-sse@2.2.4 (2025-10-18) and bigskysoftware/htmx-extensions main src/sse/sse.js.
Summary
htmx-ext-sse@2.2.4(andsrc/sse/sse.jsonmain) still reconnects forever with no jitter afterEventSource.CLOSED. The old XOR backoff (2 ^ retryCount) was fixed in 2.2.1; these two problems replaced it.Happy to open a PR if you want one. CONTRIBUTING prefers an issue first for discussion, so this stops here until you say otherwise.
Current code
ensureEventSource'ssource.onerrorinsrc/sse/sse.js(same in the 2.2.4 npm file):1. No give-up
Math.min(retryCount * 2, 128)caps the delay at 64 seconds (128 * 500). There is no maximum-attempts check. A permanently unreachable endpoint is retried forever at 64s intervals for as long as the element stays in the DOM.onopenresetsretryCountto0after a successful reconnect, which is good for a transient outage. It does not bound a never-recovering endpoint.2. No jitter
Math.random()went away with the XOR expression in 2.2.1. Every client that lost the connection at the same moment now retries in lockstep: 0.5s, 1s, 2s, 4s, … A server that just came back gets a thundering herd.Not this issue
2.0.0–2.2.0 used
Math.random() * (2 ^ retryCount) * 500plusMath.min(7, retryCount + 1). That XOR / capped-counter bug is already gone. Please do not treat this as a request to restore that expression.Suggested shape (not a patch)
Infinitycan stay the default if you want today's behavior).Verified against npm
htmx-ext-sse@2.2.4(2025-10-18) andbigskysoftware/htmx-extensionsmainsrc/sse/sse.js.