43

I'm actually doing some load testing against an ExpressJS server, and I noticed that the response send by the server includes a "Connection: Keep-Alive" header. As far as I understand it, the connection will remain opened until the server or the client sends a "Connection: Close" header.

In some implementations, the "Connection: Keep-Alive" header comes up with a "Keep-Alive" header setting the connection timeout and the maximum number of consecutive requests send via this connection.

For example : "Keep-Alive: timeout=15, max=100"

Is there a way (and is it relevant) to set these parameters on an Express server ?

If not, do you know how ExpressJS handles this ?

Edit: After some investigations, I found out that the default timeout is set in the node standard http library:

socket.setTimeout(2 * 60 * 1000); // 2 minute timeout

In order to change this:

var http = require('http');

http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end("Hello World");
}).on('connection', function(socket) {
  socket.setTimeout(10000);
}).listen(3000);

Anyway it still looks a little bit weird to me that the server doesn't send any hint to the client concerning its timeout.

Edit2: Thanks to josh3736 for his comment.

setSocketKeepAlive is not related to HTTP keep-alive. It is a TCP-level option that allows you to detect that the other end of the connection has disappeared.

Miguel L.
  • 648
  • 2
  • 7
  • 11
  • Timeout is distinct from keepAliveTimeout, socket.setTimeout cannot set the HTTP Keep-Alive timeout in a nodejs server. You should use server.keepAliveTimeout and turn TCP keepalive on at same time with using socket.setKeepAlive https://nodejs.org/dist/latest-v14.x/docs/api/http.html#http_server_keepalivetimeout. – Clocher Zhong Mar 15 '21 at 03:25

3 Answers3

37

For Express 3:

var express = require('express');
var app = express();
var server = app.listen(5001);

server.on('connection', function(socket) {
  console.log("A new connection was made by a client.");
  socket.setTimeout(30 * 1000); 
  // 30 second timeout. Change this as you see fit.
});
Community
  • 1
  • 1
dgo.a
  • 2,424
  • 21
  • 30
  • Why are you listening twice there? – gtato Jan 23 '19 at 15:06
  • Does not work for me, the timeout got overridden after I set it. Setting `keepAliveTimeout` on the Server object did work though. – Yogu Feb 05 '19 at 13:39
  • @Yogu where do you set `keepAliveTimeout`? Can you provide as another answer? – Pasupathi Rajamanickam Feb 26 '19 at 17:36
  • 4
    Why does this answer show how to do this for `express` when the question was for the base node.js `http` library? At the very least also show this for the base `http` module, even if you then go on to say "but you probably want to use express" (which some folks really don't because they need a base HTTP server purely for a protocol upgrade) – Mike 'Pomax' Kamermans Jun 08 '19 at 16:13
  • I'd love to understand what is actually going on here. What I am experiencing is when I take a really long time to process a request, eventually it looks like the request gets retried before I am finished processing the original request. – RedBullet Sep 04 '20 at 14:38
  • is this different from `app.request.setTimeout(30*1000);` ? – bvdb Sep 25 '20 at 21:42
  • Timeout is distinct from keepAliveTimeout, socket.setTimeout cannot set the HTTP Keep-Alive timeout in a nodejs server. you should use server.keepAliveTimeout https://nodejs.org/dist/latest-v14.x/docs/api/http.html#http_server_keepalivetimeout – Clocher Zhong Mar 15 '21 at 03:23
10

To set keepAliveTimeout on the express server do:

var express = require('express');
var app = express();
var server = app.listen(5001);

server.keepAliveTimeout = 30000;


Ninn
  • 101
  • 1
  • 3
4

For Node.js 10.15.2 and newer with express, only server.keepAliveTimeout was not enough. We also need to configure server.headersTimeout longer than server.keepAliveTimeout.

server.keepAliveTimeout = 30000; 
// Ensure all inactive connections are terminated by the ALB, by setting this a few seconds higher than the ALB idle timeout
server.headersTimeout = 31000; 
// Ensure the headersTimeout is set higher than the keepAliveTimeout due to this nodejs regression bug: https://github.com/nodejs/node/issues/27363
zangw
  • 37,361
  • 17
  • 142
  • 172