Skip to content

http: option to mark active connections to close when idle - #66000

Open
WhatCats wants to merge 1 commit into
nodejs:mainfrom
WhatCats:http-close-when-idle
Open

http: option to mark active connections to close when idle#66000
WhatCats wants to merge 1 commit into
nodejs:mainfrom
WhatCats:http-close-when-idle

Conversation

@WhatCats

Copy link
Copy Markdown

Summary

server.close() calls closeIdleConnections() internally (since bd7a808), which closes every connection that is idle at that exact moment. A connection that's actively sending a request or waiting for a response when close() runs is correctly left alone and once that response finishes, nothing ever rechecks it. It reverts to being a normal keep-alive connection and stays open until keepAliveTimeout reaps it (65s by default), rather than closing as part of the server.close() call.

Interestingly, when investigating, I noticed this exact gap is also independently documented in Bun's source: https://github.com/oven-sh/bun/blob/df573dace6178d4ff94a797313bc8b5fdcf515e4/src/runtime/server/mod.rs#L1747-L1751

// node:http servers are exempt: Node's `close()` sweeps idle
// connections exactly once (the JS layer already called
// `closeIdleConnections()`), and a connection whose response
// completes after `close()` stays keep-alive until its timeout
// reaps it — verified against Node v26.

Reproduce

Call server.close() while a request is in flight, using a client with an explicit keep-alive Agent (so the client doesn't voluntarily tear down its side). The 'close' event doesn't fire until keepAliveTimeout (+ keepAliveTimeoutBuffer) elapses, even though the response completed almost immediately. (see test/parallel/test-http-server-close-when-idle.js)

Fix

server.close() now calls closeIdleConnections(true), adding a closeWhenIdle parameter that marks a connection as due for closing once its current request/response finishes, even if it is active (not idle) at the moment close() is called. Previously such connections were left open for keep-alive reuse until keepAliveTimeout reaped them. A marked connection also stops advertising Connection: keep-alive on the response it is currently sending.

`server.close()` now calls `closeIdleConnections(true)`, adding a
`closeWhenIdle` parameter that marks a connection as due for closing
once its current request/response finishes, even if it is active
(not idle) at the moment `close()` is called.

Previously such connections were left open for keep-alive reuse
until `keepAliveTimeout` reaped them.

A marked connection also stops advertising `Connection: keep-alive`
on the response it is currently sending.

Signed-off-by: WhatCats <whatcater@gmail.com>
Assisted-by: Claude Code
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/http
  • @nodejs/net

@nodejs-github-bot nodejs-github-bot added http Issues and PRs related to the http subsystem. needs-ci PRs that need a full CI run. labels Sep 12, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Welcome to Node.js, and thank you for your first contribution!

Before review, please take a moment to read:

Please make sure every commit is signed off. For a first pull request, GitHub Actions require collaborator approval and Jenkins CI must be started by a collaborator or triager, so an initial wait is normal.

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

Labels

http Issues and PRs related to the http subsystem. needs-ci PRs that need a full CI run.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants