Prerequisites
Issue
There's already an issue here fastify/fastify-cli#168 never solved (afaik).
But I decided to put it here because maybe it's something that fastify (not cli) should manage or be aware of it, because it regards additional hidden connections by chrome.
I reproduced the bug of not graceful restart on watch.
- new project
- install fastify and fastify-cli
package.json (dependencies only)
"scripts": {
"start": "fastify start --ignore-watch='node_modules' -w -V -l error --options -P fastify.js"
},
"dependencies": {
"fastify": "^5.0.0",
"fastify-cli": "^7.0.1"
}
fastify.js
module.exports = async function (fastify, options) {
fastify.get('/', async function () {
return { hello: 'world' }
})
}
- run
npm start
- server is running
- open chrome (this is the issue :)) at http://localhost:3000. it should output the hello world json
- modify the source
The server doesn't graceful restart and it will forced to close after 5 seconds

Now I made a lot of experiments.
In the end it seems that chrome opens 2 connections and 1 of them is not in idle status.
So this line
|
instance.server.closeIdleConnections() |
will close only one of them and the second one is a connection in waiting. In fact if you change instance.server.closeIdleConnections() in instance.server.closeAllConnections() the server restart without timeout, but of course we lose the graceful shutdown.
Where I found 2 connections? I tried to put in fastify source file after other listeners:
server.on('connection', function(socket) {
console.log(socket)
})
and I opened the debugger. For one page call in chrome there are 2 sockets. If I do the same with Firefox, the connection logged is only one and the bug does not happen at all.
Even upgrading node to 22 and using before the close here
|
instance.server.close(function (err) { |
this code:
// only for node 22
instance.server.getConnections((err, count)=> {
console.log({err, count})
})
the count is 1 (it should be 0 because there are no active connections and the closeIdleConnections is already called)
Deleting all my debug code (rm node_modules and reinstall everything again):
I tried chrome without the debug window opened: process forced end.
I tried in inkognito mode: it works! graceful restart
I tried with a guest profile: it works! graceful restart
So I thought about some extensions or plugin. I've deactivate everything but there are still 2 connections and the bug happens.
I tried with another clean and new chrome profile (without any extension or whatever): process forced end.
So, in the end if chrome opens some hidden connections and put them in waiting, there is no much more to do fastify side.
The only thing maybe could be defining a flag to close all connections without graceful in case of watching mode.
But also knowing what chrome does, should be useful. Maybe it's something linked on how it manages its profiles or something that fastify could recognize and force the closing of these "dummy" connection. Maybe somebody knows better.
Prerequisites
Issue
There's already an issue here fastify/fastify-cli#168 never solved (afaik).
But I decided to put it here because maybe it's something that fastify (not cli) should manage or be aware of it, because it regards additional hidden connections by chrome.
I reproduced the bug of not graceful restart on watch.
package.json (dependencies only)
fastify.js
npm startThe server doesn't graceful restart and it will forced to close after 5 seconds

Now I made a lot of experiments.
In the end it seems that chrome opens 2 connections and 1 of them is not in idle status.
So this line
fastify/fastify.js
Line 463 in b1b9a75
will close only one of them and the second one is a connection in waiting. In fact if you change
instance.server.closeIdleConnections()ininstance.server.closeAllConnections()the server restart without timeout, but of course we lose the graceful shutdown.Where I found 2 connections? I tried to put in fastify source file after other listeners:
and I opened the debugger. For one page call in chrome there are 2 sockets. If I do the same with Firefox, the connection logged is only one and the bug does not happen at all.
Even upgrading node to 22 and using before the close here
fastify/fastify.js
Line 484 in b1b9a75
this code:
the count is 1 (it should be 0 because there are no active connections and the closeIdleConnections is already called)
Deleting all my debug code (rm node_modules and reinstall everything again):
I tried chrome without the debug window opened: process forced end.
I tried in inkognito mode: it works! graceful restart
I tried with a guest profile: it works! graceful restart
So I thought about some extensions or plugin. I've deactivate everything but there are still 2 connections and the bug happens.
I tried with another clean and new chrome profile (without any extension or whatever): process forced end.
So, in the end if chrome opens some hidden connections and put them in waiting, there is no much more to do fastify side.
The only thing maybe could be defining a flag to close all connections without graceful in case of watching mode.
But also knowing what chrome does, should be useful. Maybe it's something linked on how it manages its profiles or something that fastify could recognize and force the closing of these "dummy" connection. Maybe somebody knows better.