Can you build a scalable Application with Express?
Can you build a scalable Application with Express?
I have been working with Nodejs and Express for the past three years. one of the questions that I have repeatedly seen in the community or developers keeps asking is whether Express is scalable. I had the same doubt when I started with Express. But, eventually, I found an answer to that question. Let me share my learning with you in this article.
Before getting into that main topic, let me ask you what’s a scalable application?. There are many definitions to it. In simple terms, We can call an application scalable if it handles heavy traffic or a high number of users. Whenever there is high traffic or many users, the application should work just like before without any performance degradation.
If you measure application scalability by the number of users only, then you’re missing some of the other crucial factors. For example, consider a scenario where an application has messy code and can still handle millions of users. But, changing a piece of code can make the whole system more cluttered.
As a developer, can we be able to work on that code?. Developer experience is as necessary as user experience while building a scalable application.
So, we will focus on whether Express can be scalable in terms of customers and developer experience.
When building a scalable application with Nodejs, people prefer to follow opinionated rules to manage their codebase. So there are different frameworks available in Nodejs to build the backend. However, Express is one of the most popular frameworks in the Node.js Ecosystem.
Even though it is popular and simple to use, we have to admit that the Express application has no strict folder structure. So, it makes a lot of opinionated structure, which becomes hard to maintain when the codebase starts to grow.
However, we have few ways to solve that problem nowadays. They are,
Architecture is one of the important factors in building a scalable application. We suggest following an architectural pattern based on the requirement. For example, suppose you are building a simple web application. You can use the MVC pattern. On the other hand, if you want to develop an enterprise-level application to decouple from framework dependency, you can go with a clean architecture pattern.
It all comes down to the application requirement. But, do consider designing an architecture before starting to build the application. It comes a long way.
Some of the architectural designs are,
The Clean Architecture by uncle bob
The Clean Architecture Implementaion in Nodejs, Express
CQRS Event sourcing Architecture
There are two ways to scale an application. They are horizontal scaling and vertical scaling.
Horizontal scaling means adding more machines to existing infrastructure, whereas vertical scaling means adding more resources such as CPU and RAM to existing machines.
When deploying the Express application, we can either deploy via pm2 or containerize, orchestrate the application and deploy.
PM2 or Container Orchestration
PM2 uses Nodejs cluster mode to create multiple processes. Cluster mode helps to distribute the incoming traffic to multiple processes. PM2 cluster mode distributes the traffic to multiple processes in a single server.
On the other hand, Docker can scale and distribute traffic across a single server and multiple servers with the help of a load balancer. It is efficient to run a container per core that can utilize all available CPU cores than multiple processes in a single server instance.
So, scaling up and scaling down an Express application will be easy if we containerize it and orchestrate it via tools like Kubernetes and Docker.
Let’s scale our Express application with Kubernetes Autoscaling. To check if Kubernetes can autoscale and handle such a high load, we will do a stress test on an express application with MongoDB as a database.
We are not going to build and deploy an Express application from scratch. Because we do not want to re-invent the wheel. We are going to stress test an existing application that uses Express and Kubernetes.
learnk8s.io has a well-written article about building and deploying a Nodejs application with Kubernetes
We’ll just deploy them locally and test it’s scalability. you can find the source code here
Note: If you’re new to Kubernetes, Checkout Kubernetes for Nodejs developers article.
To deploy the application and database, we need to run the command,
kubectl apply -f kube
It will deploy the application in the pods.
Once we deploy the application, we can autoscale the application deployment using the command,
kubectl autoscale deployment knote --cpu-percent=50 --min=1 --max=10
Here, we autoscale
knote deployment when a particular pod reaches 50% of CPU usage. It will increase the number of pods running. We are configuring minimum 1 replica to maximum 10.
To stress-test the Kubernetes pods, we can use load generator in Kubernetes with bash commands,
kubectl run -i --tty load-generator --rm --image=busybox --restart=Never -- /bin/sh -c "while sleep 0.01; do wget -q -0- http://knote; done"
Here, we have a shell script to ping kubernetes pods every 0.01 seconds. Here, the pod is http://knote.
Before running the command, we can verify the request metrics of the particular pod using the command,
kubectl get hpa
It will give us the following info,
Once we run the load generator, you can see the CPU usage spikes up, and Kubernetes pods auto-scales based on the CPU usage of each pod.
To summarize, Here are the key points to note on building a scalable application with Express.
- Business logic dictates how scalable the service, and architectural design plays an important role in it.
- Do monitor and load test the application to measure the scalability
- Leverage the power of Async/Await in Node.js applications for efficiency and better performance.
- Containerization and orchestration tools like Docker and Kubernetes can help to scale the application.