[Translation] 6 small tips to prepare NodeJS for high loads

[Translation] 6 small tips to prepare NodeJS for high loads

The service with face recognition "Look-A-Like" served thousands of users at the same time

Developing at NodeJS as a hobby is fun, but when it comes to production for many users, there are a couple of things you should know to avoid long response times and crashes.

As part of working with MyHeritage, we developed the doppelgänger service for Eurovision 2019, which you can use to download of the contestants you are most like.

In addition to the face recognition logic, the application had a very clear requirement: it had to serve tens of thousands of simultaneous users, because Eurovision is watched by millions of people around the world.

We realized very quickly that the load balancer in front of an application configured using Auto Scaling is not enough for resiliency. The following helped us a lot:

  1. Rely on the best, but prepare for the worst: Measure how many simultaneous users will be served by your application in time X (in one instance). For example, in our case, testing showed that we could serve 200 simultaneous users in each EC2 instance for 10 seconds, so when we learned that we had to serve 10,000 simultaneous users, we just had to prepare 50 servers behind the balancer. For the test, we used a great tool called JMeter .

    And this tutorial helped a lot in preparation for taking measurements.
  2. Avoid blocking: blocking operations (like fs.readSync ) are tempting because the code looks cleaner, but they literally kill performance. Instead, use async / await operations, because during the execution of asynchronous operation, the CPU will be available for other tasks (see Event loop ).

    To: const res = fs.readSync ('file.txt');
    After: const res = await fs.readAsync ('file.txt');
  3. Increase memory limit: Node is set to a default limit of 1 GB. If the server is available, say, 4 GB specifically for your application, you will need to set the maximum memory limit manually using the CLI with the following flag: - max-old-space-size
    Example: node - max-old-space-size = 4096 server.js
  4. Make sure you use all the processor cores: by default, Node works in the same thread. If you did not specifically set up a configuration that would run several threads, save money by choosing a server with 1 core.
  5. Reduce the number of hits to the application: set the forced HTTPS and all redirects as high as possible (for example, at the proxy level). This will allow the application to not be distracted by the superfluous, and therefore be more accessible to requests that are really important.
  6. Error handling: Use logging, such as Logz.io/AWS CloudWatch, to track errors that may cause the application to crash. DO NOT REPORT everything to services like Slack, because messages usually go in a crowd and can easily clog the channel. We used an excellent library called Winston to log in to NodeJS.

In our case, these tips led to a ten-fold improvement in performance and helped keep the production environment clean, even when thousands of users had to be served at the same time.

Thanks for reading.

Source text: [Translation] 6 small tips to prepare NodeJS for high loads