Skip to content

feat: enable TCP keepalive and nodelay on all connections (DRIVERS-383)#276

Merged
comtihon merged 1 commit into
comtihon:masterfrom
raxdcx:feat/tcp-keepalive
Apr 13, 2026
Merged

feat: enable TCP keepalive and nodelay on all connections (DRIVERS-383)#276
comtihon merged 1 commit into
comtihon:masterfrom
raxdcx:feat/tcp-keepalive

Conversation

@samwar

@samwar samwar commented Apr 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds {keepalive, true} and {nodelay, true} socket options to both gen_tcp:connect and ssl:connect calls in mc_worker_logic:do_connect/5.

This brings the Erlang driver into compliance with MongoDB specification DRIVERS-383, which requires all drivers to enable TCP keepalive by default. All other official MongoDB drivers (Node.js, Python, Java, Go, C) already comply.

Problem

Without TCP keepalive, idle connections are silently closed by firewalls and load balancers, causing high connection churn in production environments.

Changes

  • src/connection/mc_worker_logic.erl: Added {keepalive, true}, {nodelay, true} to both the plain TCP and SSL clauses of do_connect/5
  • test/tcp_keepalive_SUITE.erl: New test suite with property-based tests (PropEr, 100 iterations each) and unit tests

Socket option precedence (SSL)

For SSL connections, user-provided ssl_opts are appended after the defaults (++ Opts), so users can override keepalive/nodelay if needed (last occurrence wins).

Tests

Test Type Result
prop_keepalive_nodelay_enabled Property (100 iter)
prop_existing_options_preserved Property (100 iter)
prop_ssl_user_option_override Property (100 iter) ⏭️ Skips without SSL MongoDB
unit_keepalive_concrete Unit
unit_keepalive_ping Unit

Scope

  • Two lines changed in production code
  • No new modules, records, or supervision tree changes
  • SRV-based connections covered automatically (delegates to do_connect/5)
  • Fully backward compatible — no configuration changes required

Add {keepalive, true} and {nodelay, true} socket options to both
gen_tcp:connect and ssl:connect calls in mc_worker_logic:do_connect/5.

This brings the Erlang driver into compliance with MongoDB specification
DRIVERS-383, which requires all drivers to enable TCP keepalive by
default. Keepalive prevents firewalls and load balancers from silently
closing idle connections, reducing connection churn in production.

For SSL connections, user-provided ssl_opts are appended after the
defaults so they can override keepalive/nodelay if needed.

Includes property-based tests (PropEr) and unit tests verifying:
- keepalive and nodelay enabled on all plain TCP connections
- existing socket options (binary, active, packet) preserved
- SSL user option override precedence
- ping command works on keepalive-enabled connections
@samwar

samwar commented Apr 6, 2026

Copy link
Copy Markdown
Contributor Author

I've been noticing a lot of silently closed connections on long-running operations after upgrading my production nodes from MongoDB 5 to MongoDB 6. My hope is that by making the driver compliant with TCP keep alive and Mongo's own specifications that this will resolve those errors.

@samwar

samwar commented Apr 7, 2026

Copy link
Copy Markdown
Contributor Author

@comtihon Let me know if you see any issues with this PR.

@samwar

samwar commented Apr 13, 2026

Copy link
Copy Markdown
Contributor Author

@comtihon pinging you again to hopefully have this reviewed and merged.

@comtihon comtihon merged commit 24681a3 into comtihon:master Apr 13, 2026
14 checks passed
@comtihon

Copy link
Copy Markdown
Owner

Somehow missed this. Thank you!

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