Miguel L.
Miguel L.

Reputation: 728

How to set the HTTP Keep-Alive timeout in a nodejs server

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.

Upvotes: 50

Views: 104438

Answers (3)

zangw
zangw

Reputation: 48366

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

Update

Since this issue Regression issue with keep alive connections has been closed. We could just set keepAliveTimeout on the latest node.js version.


One more thing, If your node.js server is deployed under AWS ELB and encounters 502 error code occasionally.

Clients -> AWS ELB -> Node Server

AWS ELB has 60 seconds of connection idle timeout by default, and per doc

We also recommend that you configure the idle timeout of your application to be larger than the idle timeout configured for the load balancer

Config the value of keepAliveTimeout to greater than 60 seconds could be one option to eliminate this issue.

Upvotes: 16

Ninn
Ninn

Reputation: 151

To set keepAliveTimeout on the express server do:

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

server.keepAliveTimeout = 30000;


Upvotes: 15

dgo.a
dgo.a

Reputation: 2764

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.
});

Upvotes: 38

Related Questions