Add ELECTRIC_TCP_READ_TIMEOUT for the HTTP keep-alive idle timeout#4716
Add ELECTRIC_TCP_READ_TIMEOUT for the HTTP keep-alive idle timeout#4716alco wants to merge 3 commits into
Conversation
Expose ThousandIsland read_timeout (default 60s), which doubles as the keep-alive idle timeout: Bandit reaps connections idle longer than this without announcing the close via connection: close. Behind a pooling proxy (e.g. AWS ALB) the value must exceed the proxy idle timeout, or the proxy races the unannounced close when reusing a pooled connection and clients see intermittent 502s. Cloud diagnosis: daily-recurring storms of ALB-minted 502s (~709k on Jul 9) from mass idle reaping of cold connection pools. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AEErBr3SXEa5VprZu26ZkP
✅ Deploy Preview for electric-next ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Claude Code ReviewSummaryAdds What's Working Well
Issues FoundCritical (Must Fix)None. Important (Should Fix)None. Suggestions (Nice to Have)
Issue ConformanceNo linked issue. Per project conventions PRs should reference the issue/incident they address, but the PR description is unusually thorough — it documents the production incident (ALB 502 storm), the root cause (keep-alive idle timeout inverted relative to the proxy idle timeout), and the remediation. The changeset is present and correctly targets Previous Review StatusBoth iteration-1 suggestions were addressed in iteration 2 (
No functional regression. Nothing from prior reviews has regressed. Review iteration: 3 | 2026-07-16 |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4716 +/- ##
=======================================
Coverage 60.04% 60.05%
=======================================
Files 397 397
Lines 43766 43766
Branches 12586 12589 +3
=======================================
+ Hits 26281 26284 +3
+ Misses 17403 17401 -2
+ Partials 82 81 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Test asserts tcp_read_timeout maps to a top-level ThousandIsland option (nesting it in transport_options would silently no-op), and that nil omits it. Docs now attribute the 60s default to ThousandIsland rather than presenting it as our own. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AEErBr3SXEa5VprZu26ZkP
What
Adds
ELECTRIC_TCP_READ_TIMEOUTto configure ThousandIsland'sread_timeout(default 60s), which doubles as Bandit's HTTP keep-alive idle timeout: connections that have waited this long for their next request are closed. The option mirrorsELECTRIC_TCP_SEND_TIMEOUT(human-readable duration) and threads throughtcp_read_timeout→thousand_island_options/1. Default is unchanged (nil→ ThousandIsland's 60s).Includes a docs entry in
website/docs/sync/api/config.mdand a changeset.Why
When Electric runs behind a connection-pooling proxy, the target's keep-alive timeout must exceed the proxy's idle timeout. If it doesn't, the proxy can reuse a pooled connection at the same moment Bandit's idle timer closes it (the close is a bare FIN — nothing announces it in-band), and the resulting TCP reset surfaces to clients as an intermittent
502 Bad Gateway.