Repository navigation
HTTP Server close is taking up to 5 seconds in node 18 #50188
Description
Activity
Started on 18.18.1, the 18.18.0 does not have this weird delay.EDIT: it has the delay also on 18.18.0
Reacted by Alex YangRelated PR: #48383
The hot fix:
import * as http from "node:http"; import { promisify } from "node:util"; const server = http.createServer(async (req, res) => { res.writeHead(200, { "Content-Type": "text/plain" }); res.write("Hello world"); res.end(); }); const listenPromisied = promisify(server.listen.bind(server)); const closePromisied = promisify(server.close.bind(server)); await listenPromisied(0, "127.0.0.1"); const address = server.address(); await fetch(`http://${address.address}:${address.port}`); console.time("server close"); + server.closeAllConnections(); await closePromisied(); console.timeEnd("server close");Reacted by Jacques-Yves Bleau- addedhttpIssues and PRs related to the http subsystem.Issues and PRs related to the http subsystem.
on Oct 15, 2023 Should we bisect or
closeAllConnectionsis expected to be called?The latest behavior is to close all sockets, I think there are some backport issues on 18. Let me see if I can do the backport
The 19.0.0 looks like the first release without this delay.
I will try bisect to see if I can find the commit that fixes the delay and then we can backport.
The #48383 was released on 20.4.0, and this issue started on 18.0.0 (or even earlier, I didn't try rewrite the fetch call)
Reacted by Alex Yang@himself65 bisect will not help in this case:
The merge base 19064bec341185a8c15fc438cfcf0df8633a179e is bad. This means the bug has been fixed between 19064bec341185a8c15fc438cfcf0df8633a179e and [cc993fb2760d01457955f5b9ff787d559ed1c34e].From what I understand, 18.x and 19.x have different git histories, so there's no way to find the bad commit using bisect.
At least, I don't know a way to do it, I'm open to suggestions.Reacted by Alex YangI tried nodejs 16.x. now I think there might have a regression on nodejs 16 -> 18
import * as http from "node:http"; import { promisify } from "node:util"; import fetch from 'node-fetch' const server = http.createServer(async (req, res) => { res.writeHead(200, { "Content-Type": "text/plain" }); res.write("Hello world"); res.end(); }); const listenPromisied = promisify(server.listen.bind(server)); const closePromisied = promisify(server.close.bind(server)); await listenPromisied(0, "127.0.0.1"); const address = server.address(); await fetch(`http://${address.address}:${address.port}`); console.time("server close"); await closePromisied(); console.timeEnd("server close");
➜ nodejs git:(main) ✗ node index.mjs server close: 0.158ms ➜ nodejs git:(main) ✗ node -v v16.20.2
- addedregressionIssues related to regressions.Issues related to regressions.
on Oct 15, 2023 It's a regression from 17.x -> 18.x
h4ad:node-copy-4/ (main✗) $ node test-close-2.mjs server close: 0.108ms h4ad:node-copy-4/ (main✗) $ node -v v17.9.1Based on https://github.com/nodejs/node/pull/49091/files#diff-d692ac4524379ec6a1201165e8ff8d3267c8130e07014e8221ebf7e6f80c6641R1560-R1567, and this little change:
const server = http.createServer({ keepAliveTimeout: 200 }, async (req, res) => {h4ad:node-copy-4/ (main✗) $ node test-close-2.mjs server close: 0.255ms h4ad:node-copy-4/ (main✗) $ node -v v18.18.1
@himself65 I think you are right, the #48383 should fix the issue, I thought it landed on 18.18.0 but it did not, sorry for the confusion.
Let me know if you will do the backport, if not, I can do that.
I built 18.18.0 with fix #48383, it solves the delay.
Based on https://github.com/nodejs/node/pull/49091/files#diff-d692ac4524379ec6a1201165e8ff8d3267c8130e07014e8221ebf7e6f80c6641R1560-R1567, and this little change:
const server = http.createServer({ keepAliveTimeout: 200 }, async (req, res) => {h4ad:node-copy-4/ (main✗) $ node test-close-2.mjs server close: 0.255ms h4ad:node-copy-4/ (main✗) $ node -v v18.18.1@himself65 I think you are right, the #48383 should fix the issue, I thought it landed on 18.18.0 but it did not, sorry for the confusion.
Let me know if you will do the backport, if not, I can do that.
I might don't have time on backport you can try that.
I read some CIGTM code, i have no idea on this #48383 (comment)
Reacted by Vinicius Lourenço2 remaining items
Now I believe this is a kind of bug in undici
Reacted by Daniel Ramos- addedfetchIssues and PRs related to the Fetch API.Issues and PRs related to the Fetch API.and removedhttpIssues and PRs related to the http subsystem.Issues and PRs related to the http subsystem.regressionIssues related to regressions.Issues related to regressions.
on Oct 15, 2023 I think this is not a regression. From undici 4.4.1 (first version that has
fetch), the delay is always thereHotfix
res.writeHead(200, { 'Content-Type': 'text/plain', 'Connection': 'close' })
Thanks to nodejs/undici#2348 (comment)
The real reason is keep-alive is by default in somewhere
Reacted by Benjamin Gruenbaum- addedhttpIssues and PRs related to the http subsystem.Issues and PRs related to the http subsystem.and removedfetchIssues and PRs related to the Fetch API.Issues and PRs related to the Fetch API.
on Oct 16, 2023 The code
fetches and then does not read or dispose of the response. This is expected behavior I think? You only waited for headers, you might still read the body of the response.Node 18 is already EOL, and it seems this doesn’t happen in higher major versions
Reacted by Daniel Ramos- added 2 commits that reference this issue
on Aug 10, 2026

Version
v18.18.2
Platform
Darwin MacBook-Pro-de-Daniel.local 23.0.0 Darwin Kernel Version 23.0.0: Fri Sep 15 14:43:05 PDT 2023; root:xnu-10002.1.13~1/RELEASE_ARM64_T6020 arm64
Subsystem
http
What steps will reproduce the bug?
How often does it reproduce? Is there a required condition?
I have only reproduced the bug in node 18, but is deterministic, it happens every time
What is the expected behavior? Why is that the expected behavior?
In node 19 and 20 it's only taking 0.5 seconds. Thats a normal time that I would expect.
What do you see instead?
I see 5 seconds of delay in order to close
Additional information
I've reproduced the error in this repository with a bare minimum with Github Actions: DanielRamosAcosta/nodejs-close-server-bug
Here is the CI report:
This is affecting to a library I'm maintaining similar to supertest. If you see the CI there, Node 18 tests are taking very long due to the servers being closed.