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

77,576

Solution 1

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

Solution 2

To set keepAliveTimeout on the express server do:

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

server.keepAliveTimeout = 30000;


Solution 3

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
Share:
77,576

Related videos on Youtube

Miguel L.
Author by

Miguel L.

Updated on July 09, 2022

Comments

  • Miguel L.
    Miguel L. almost 2 years

    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.

    • Clocher Zhong
      Clocher Zhong about 3 years
      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 nodejs.org/dist/latest-v14.x/docs/api/….
  • gtato
    gtato about 5 years
    Why are you listening twice there?
  • Yogu
    Yogu about 5 years
    Does not work for me, the timeout got overridden after I set it. Setting keepAliveTimeout on the Server object did work though.
  • Pasupathi Rajamanickam
    Pasupathi Rajamanickam about 5 years
    @Yogu where do you set keepAliveTimeout? Can you provide as another answer?
  • Mike 'Pomax' Kamermans
    Mike 'Pomax' Kamermans almost 5 years
    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)
  • RedBullet
    RedBullet over 3 years
    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.
  • bvdb
    bvdb over 3 years
    is this different from app.request.setTimeout(30*1000); ?
  • Clocher Zhong
    Clocher Zhong about 3 years
    Timeout is distinct from keepAliveTimeout, socket.setTimeout cannot set the HTTP Keep-Alive timeout in a nodejs server. you should use server.keepAliveTimeout nodejs.org/dist/latest-v14.x/docs/api/…