How to: Q. How to improve Node.js performance?
**1. Asynchronous Functions:**

Using asynchronous functions in an application that heavily uses I/O operations will improve it. This is because the CPU will be able to handle multiple requests simultaneously due to non-blocking I/O, while one of these requests is making an Input/Output operation.

**Example:**

```js
var fs = require('fs');

// Performing a blocking I/O
var file = fs.readFileSync('/etc/file.txt');
console.log(file);

// Performing a non-blocking I/O
fs.readFile('/etc/file.txt', function(err, file) {
    if (err) return err;
    console.log(file);
});
```

**2. Query Optimization:**

Basic tips to improve your database performance/optimization overview

* **Indexing** - Indexing is an approach to optimize the performance of a database by minimizing the number of disk accesses required when a query is processed.

* **Avoid SELECT** -  Use the SELECT statement to query only the data you need and avoid extra fetching loads to your database.

```sql
-- query1
SELECT * FROM Customers

-- query2 (optimized)
SELECT FirstName, LastName, Address, City, State, Zip FROM Customers
```

* **Use LIMIT** - LIMIT will return only the specified number of records.

```sql
SELECT FirstName, LastName, Address, City, State, Zip FROM Customers LIMIT 100
```

* **Wildcard (%)** - Use wildcard (%) character appropriately

```sql
-- SELECT customers whose first names start with "Avi"

-- query1
SELECT FirstName from Customers where FirstName like '%avi%'

-- query2 (optimized)
SELECT FirstName from Customers where FirstName like 'avi%'
```

**3. Caching:**

Caching is one of the common ways of improving the Node Js performance. A cache is a memory buffer where frequently accessed data is temporarily stored to be accessed quicker. Cached data is then retrieved without having to access the origin. Caching will improve your app response time and even reduce some costs such as bandwidth and data volumes.

* **Redis cache** is entirely asynchronous with optimal performance to handle cached data requests in a single thread.

* **Memcached** stores data across different nodes. It uses a hashing schema that provides a hash table functionality. These ensure that adding, or removing a server node does not significantly change the mapping of the keys to server nodes.

* **Node-cache** works almost like Memcached with the set, get, and delete methods. It has a timeout that deletes data from the cache when the timeout expires.

* **Nginx** will help maintain load balance. Nginx will help cache static files, that will drastically offload the work of the application server. It offers low memory usage and high concurrency.

**4. Load Balancing:**

It\'s a typical challenge to create performant applications that can handle a huge number of incoming connections. Load balancing is the term for this method. The cluster module to allow load balancing and distribute incoming connections across all workers in an environment\'s numerous CPU cores using a **round-robin** technique.

Using the PM2 process manager to keep applications alive indefinitely is another option. PM2 includes a cluster feature that allows you to run numerous processes over all cores without having to worry about changing the code to use the native cluster module.

**5. Real-time Monitoring:**

Gauging the current level of performance of an application may require running different kinds of tests, such as the following:

* **Load testing:** refers to the practice of simulating the expected usage of a system and measuring its response as the workload increases.

* **Stress testing:** designed to measure how a system performs beyond the limits of normal working conditions. Its goal is to determine how much the system can handle before it fails and how it attempts to recover from a failure.

* **Spike testing:** helps to test the behavior of an application when it receives a drastic increase or decrease in load.

* **Scalability testing:** used to find the point at which the application stops scaling and identify the reasons behind it.

* **Volume testing:** determines if a system can cope with large amounts of data.

* **Endurance testing:** helps evaluate the behavior of a software application under sustained load for a long period, to catch problems such as memory leaks.

**6. Use HTTP/2:**

The HTTP/2 in a Node.js application make web browsing faster and easier while reducing bandwidth usage. HTTP/2 is aimed at increasing performance and addressing concerns with HTTP/1.x.

HTTP/2 has the following features:

* **Header Compression** - This disables unnecessary headers and compels all HTTP headers to be sent compressed.
* **Multiplexing** - This allows multiple requests to simultaneously retrieve resources and response messages over a single TCP connection.

**7. Stateless Authentication:**

Stateless authentication on the client-side with the help of JSON Web Token ( **JWT** ) provides great speed to the application. In this Stateless Authentication procedure, a web