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.

@ronag
ronag requested a review from mcollina September 12, 2026 18:29
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