Skip to content

Add TCP keepalive options for database connections - #4748

Open
tsg wants to merge 2 commits into
electric-sql:mainfrom
tsg:tcp-keepalive
Open

Add TCP keepalive options for database connections#4748
tsg wants to merge 2 commits into
electric-sql:mainfrom
tsg:tcp-keepalive

Conversation

@tsg

@tsg tsg commented Jul 31, 2026

Copy link
Copy Markdown

This adds the following config options. These are set on the underlying TCP socket.

  • ELECTRIC_DATABASE_TCP_KEEPALIVE_IDLE - Idle time before probing. Enables SO_KEEPALIVE
  • ELECTRIC_DATABASE_TCP_KEEPALIVE_INTERVAL - Gap between probes.
  • ELECTRIC_DATABASE_TCP_KEEPALIVE_COUNT - Unanswered probes before drop.
  • ELECTRIC_DATABASE_TCP_USER_TIMEOUT - Max time data may stay unacknowledged.

All unset by default, so behaviour is unchanged unless configured. Durations accept the usual 30s / 500ms forms.

Sample config:

ELECTRIC_DATABASE_TCP_KEEPALIVE_IDLE=30s
ELECTRIC_DATABASE_TCP_KEEPALIVE_INTERVAL=10s
ELECTRIC_DATABASE_TCP_KEEPALIVE_COUNT=3
ELECTRIC_DATABASE_TCP_USER_TIMEOUT=60s

Implementation:

ConnectionResolver.populate_tcp_opts/1 now appends the options to :socket_options. SO_KEEPALIVE goes through :inet's portable {:keepalive, true}; the rest use :raw with the Linux IPPROTO_TCP option numbers, guarded on :os.type() so non-Linux developer machines skip them rather than failing with einval.

Note: I've generated the PR with AI, because I don't know Elixir, but the change looks fairly straightforward to me, so I'm hoping it's all correct. The one thing that feels a bit risky is what happens on non-Linux kernels. The code attempts to disable this automatically in that case.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

@tsg tsg changed the title Tcp keepalive Add TCP keepalive options for database connections Jul 31, 2026
@netlify

netlify Bot commented Jul 31, 2026

Copy link
Copy Markdown

Deploy Preview for electric-next ready!

Name Link
🔨 Latest commit 1580054
🔍 Latest deploy log https://app.netlify.com/projects/electric-next/deploys/6a6c9ede23358e0008f4c708
😎 Deploy Preview https://deploy-preview-4748--electric-next.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@alco

alco commented Aug 12, 2026

Copy link
Copy Markdown
Member

Thanks for the contribution, @tsg. Could you share the motivation and your use case that necessitates these options?

@tsg

tsg commented Aug 12, 2026

Copy link
Copy Markdown
Author

@alco we have a SQL gateway in between electric clients and Postgres, and we had reports about the electric client not being connected for a while after GW restarts. I could reproduce the situation where the client loses the connection and doesn't attempt to reconnect for ~15 minutes if I kill -9 the gateway. On a graceful restart (i.e. if the RST or FIN makes it to the client) it works as expected. But besides the gateway there could be other network elements on the path that could cause RST/FIN to be lost.

I think that by allowing tcp keepalive configuration one would have the knobs to ensure a quick reconnect regardless of what happens on the network layer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants