How to terminate a HTTP server in Node.js?
Tags: node
Published: 2020-01-20 03:35:58

---
title: How to terminate a HTTP server in Node.js?
published: true
description: Terminating a HTTP server when there are active connections.
tags: node.js
cover_image: https://thepracticaldev.s3.amazonaws.com/i/pt0lxt9bt7jiywzueb76.png
---

One of the most [popular](https://stackoverflow.com/questions/14626636/how-do-i-shutdown-a-node-js-https-server-immediately/59816397#59816397) support questions I answer is a variation of "how to terminate a HTTP server" or "why does HTTP server not stop after calling `server.close()`". The reason for that is described in the [documentation](https://nodejs.org/api/net.html#net_server_close_callback) of [`server.close()`](https://nodejs.org/api/http.html#http_server_close_callback):

> `server.stop()` stops the server from accepting new connections and keeps existing connections. This function is asynchronous, the server is finally closed when all connections are ended and the server emits a 'close' event.

i.e. when you call `server.close()`, server stops accepting new connections, but it keeps the existing connections open indefinitely. This can result in your server hanging indefinitely due to [persistent HTTP connections](https://en.wikipedia.org/wiki/HTTP_persistent_connection) or because of the ongoing requests that do not produce a response. Therefore, in order to close the server, you must track creation of all connections and terminate them yourself.

The basic principle of forcefully closing a HTTP server looks like this:


```js
import {
  createServer,
} from 'http';

const server = createServer(() => {});

server.listen();

const sockets = new Set();

server.on('connection', (socket) => {
  sockets.add(socket);

  server.once('close', () => {
    sockets.delete(socket);
  });
});

/**
 * Forcefully terminates HTTP server.
 */
const close = (callback) => {
  for (const socket of sockets) {
    socket.destroy();

    sockets.delete(socket);
  }

  server.close(callback);
};

```

However, abruptly terminating a HTTP server is not desirable. You want to give time for existing requests to complete (without accepting new requests) and you want to inform the client that it should not attempt to use the same connection again (in case of persist HTTP connections). All of this can be done using an abstraction such as [`http-terminator`](https://github.com/gajus/http-terminator).

[`http-terminator`](https://github.com/gajus/http-terminator) implements the logic for tracking all connections and their termination upon a timeout. `http-terminator` also ensures graceful communication of the server intention to shutdown to any clients that are currently receiving response from this server.

Terminating a server using [`http-terminator`](https://github.com/gajus/http-terminator) is as simple as instantiating the service referencing the HTTP server instance and calling [`terminate`](https://github.com/gajus/http-terminator#http-terminator-api) method:

```js
import http from 'http';
import {
  createHttpTerminator,
} from 'http-terminator';

const server = http.createServer();

const httpTerminator = createHttpTerminator({
  server,
});

await httpTerminator.terminate();

```

By default, [`http-terminator`](https://github.com/gajus/http-terminator) gives 1 second for the server to complete the request. This can be configured using [`httpResponseTimeout` configuration](https://github.com/gajus/http-terminator#api).

Finally, it is worth mentioning that there are several alternatives that implement comparable functionality, e.g.

* https://github.com/hunterloftis/stoppable
* https://github.com/thedillonb/http-shutdown
* https://github.com/tellnes/http-close

The main benefit of [`http-terminator`](https://github.com/gajus/http-terminator) is that:

* it does not monkey-patch Node.js API
* it immediately destroys all sockets without an attached HTTP request
* it allows graceful timeout to sockets with ongoing HTTP requests
* it properly handles HTTPS connections
* it informs connections using keep-alive that server is shutting down by setting a `connection: close` header
* it does not terminate the Node.js process