DEV Community

Arsalan Bardsiri
Arsalan Bardsiri

Posted on

From Monolith to Modular (A basic simple example)

From Monolith to Modular

Subtitle: How I’m learning System Design by breaking my own code.

We often hear about "scaling to millions of users," but we rarely talk about the first critical step: moving from "it works on my machine" to "it works as a system."

As part of my deep dive into system design (following the(https://bytebytego.com/courses/system-design-interview)), I am building the infrastructure for a scalable web application from scratch. My goal is to move beyond theory and actually implement the architectural patterns that power the internet.

Here is what I learned moving from a Single Server architecture to a 3-Tier application.


Phase 1: The Simple Single Server (2-Tier)

Repository: arsalanbardsiri/simple-single-server-app

Every great system starts as a monolith. My first iteration was a classic "2-Tier" application. In this setup, the architecture is deceptively simple:

  1. Client Tier: The user interface (browser).
  2. Server Tier: A single machine handling both the business logic (Web Server) and the data persistence (Database).

The Architecture

Why start here?

It is the fastest way to ship. You have zero network latency between your application and your database because they live on the same hardware. Deployment is a single command. For a student project or a proof-of-concept, this is perfect.

The Wall

However, as I learned from the "Zero to Millions" chapter, this simplicity is a trap.

  • Vertical Scaling Limits: To handle more users, I have to upgrade the entire server (more RAM, better CPU). I cannot just upgrade the database; I have to upgrade the web server too.[1]
  • Single Point of Failure (SPOF): If my web server crashes due to a buggy script, my database goes down with it. The entire system is fragile.[2]
  • Security Risk: In this 2-tier setup, the database often shares the same environment as the public-facing web server, increasing the attack surface.[2]

Phase 2: The Evolution to 3-Tier Architecture

Repository: arsalanbardsiri/3tier-simple-app

To solve the fragility of the single server, I refactored the application into a 3-Tier Architecture. This is the industry standard for a reason. It physically and logically separates the system into three distinct layers.

The Architecture

  1. Presentation Tier: The frontend (Client) that the user sees.
  2. Application Tier: The backend API (Business Logic) that processes requests.
  3. Data Tier: The dedicated database server that stores information.

The "Aha!" Moment

Moving to this architecture introduced complexity—I now have to manage connection strings, network latency, and multiple deployments. So, why do it?

1. Independent Scalability
This is the biggest unlock. If my application performs heavy calculations (CPU intensive), I can add more Application Servers without touching the database. If my application stores massive amounts of logs (Storage intensive), I can upgrade the Database Server without touching the application code.[3]

2. Improved Security
In my single-server app, the database lived on the public-facing server. In the 3-tier app, the Database Tier is hidden behind the Application Tier. It resides in a private network layer, accessible only by the Application Server, never by the public internet.[4]

3. Fault Tolerance
By decoupling the components, I have prepared the system for redundancy. If I need to restart the web server to deploy a patch, the database remains active.


What's Next?

I have successfully separated the concerns, but I still have a Single Point of Failure: I only have one Application Server and one Database Server.

My next step in the ByteByteGo roadmap is to implement a Load Balancer (likely NGINX) to distribute traffic across multiple application servers, ensuring that if one goes down, the users never notice.

Follow my GitHub to see the code evolve:

Top comments (0)