80

I'm using a Node/express server. The default timeout of express is 120,000 ms, but it is not enough for me. When my response reaches 120,000 ms, the console will log POST /additem 200 120006ms and the page shows an error, so I want to set the timeout to a larger value. How would I do that?

SomeKittens
  • 38,868
  • 19
  • 114
  • 143
MarsOnly
  • 945
  • 1
  • 8
  • 9

6 Answers6

111

I'm assuming you're using express, given the logs you have in your question. The key is to set the timeout property on server (the following sets the timeout to one second, use whatever value you want):

var server = app.listen(app.get('port'), function() {
  debug('Express server listening on port ' + server.address().port);
});
server.timeout = 1000;

If you're not using express and are only working with vanilla node, the principle is the same. The following will not return data:

var http = require('http');
var server = http.createServer(function (req, res) {
  setTimeout(function() {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World\n');
  }, 200);
}).listen(1337, '127.0.0.1');

server.timeout = 20;
console.log('Server running at http://127.0.0.1:1337/');
SomeKittens
  • 38,868
  • 19
  • 114
  • 143
43

Try this:

var options = {
    url:  'http://url',
    timeout: 120000
}

request(options, function(err, resp, body) {});

Refer to request's documentation for other options.

Chin
  • 19,717
  • 37
  • 107
  • 164
Lee
  • 2,874
  • 3
  • 27
  • 51
  • 2
    I have tried this,but it doesn't work.when the response reaches 120000 ms, the console still display `POST /additem 200 120006ms` and the page shows error. – MarsOnly May 29 '14 at 05:18
  • Could it be server side time-out setting? – Lee May 29 '14 at 06:17
  • 11
    We should really differentiate between _incoming_ http request and _outgoing_ http request. – CMCDragonkai May 18 '15 at 07:20
  • 1
    If you are using your node app as a proxy, you may want to use both `require('request')` and `require('express')`. In such a case, when you make a data via the `request` module, it will only execute your callback once the request is complete. By specifying the `timeout` as @Lee is suggesting, you are 'failing' the request and calling the callback before data is returned. For me, this is often better than failing via express, as @SomeKittens suggests, because I often require cleanup from my request before exiting the process. I would suggest using 2000 (2 sec) rather than 120000 (2 mins) – JJ Stiff Apr 22 '16 at 00:03
  • timeout it's a valid param https://github.com/request/request#user-content-requestoptions-callback – ilan weissberg Sep 19 '17 at 13:46
  • 1
    Note that if the underlying TCP connection cannot be established, the OS-wide TCP connection timeout will overrule the timeout option (the default in Linux can be anywhere from 20-120 seconds). https://www.npmjs.com/package/request#requestoptions-callback – Dee Mar 14 '19 at 07:57
24

Linking to express issue #3330

You may set the timeout either globally for entire server:

var server = app.listen();
server.setTimeout(500000);

or just for specific route:

app.post('/xxx', function (req, res) {
   req.setTimeout(500000);
});
Ivan_ug
  • 2,467
  • 2
  • 17
  • 18
  • 1
    was just going to add this answer myself. was looking for this specifically but didn't see your answer. – LizardKing Jul 29 '21 at 19:26
  • 1
    Also note that the *response* has another timeout which you might want to set, too. Consider slowaris attack before blindly setting it to very high number, though. – Mikko Rantalainen Feb 07 '22 at 13:37
  • Node.js official documentation link for second approach [here](https://nodejs.org/dist/latest-v6.x/docs/api/all.html#http_request_settimeout_timeout_callback) – Naveen Kumar Mar 13 '22 at 23:21
  • 1
    @MikkoRantalainen thanks for pointing that out. I initially set a higher number to emphasize visibility. – Ivan_ug Mar 23 '23 at 10:58
16

For specific request one can set timeOut to 0 which is no timeout till we get reply from DB or other server

request.setTimeout(0)
Bhavik
  • 177
  • 1
  • 5
5

For those having configuration in bin/www, just add the timeout parameter after http server creation.

var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces
*/
server.listen(port);
server.timeout=yourValueInMillisecond
Rohith K D
  • 275
  • 7
  • 14
  • Hi Rohith. This works perfectly fine in local machine but doesn't work when deployed. Any idea why? – Prajwal Jun 25 '18 at 06:55
  • 1
    How are you running it in deployment? Is it using PM2, forever?. Is bin/www used for HTTP server configuration when deployed or from any other source?. – Rohith K D Jun 25 '18 at 11:11
  • If behavior changes when running on actual server, you may be having flakey connection (TCP/IP connection drops randomly) or you have some kind of (more or less transparent) reverse proxy in between causing the timeout. – Mikko Rantalainen Feb 07 '22 at 13:39
0

With the latest NodeJS you can experiment with this monkey patch:

const http = require("http");
const originalOnSocket = http.ClientRequest.prototype.onSocket;
require("http").ClientRequest.prototype.onSocket = function(socket) {
    const that = this;
    socket.setTimeout(this.timeout ? this.timeout : 3000);
    socket.on('timeout', function() {
        that.abort();
    });
    originalOnSocket.call(this, socket);
};
Bela Vizy
  • 1,133
  • 8
  • 19