All articlesArchitecture

2-Tier to 3-Tier Architecture: Migration Journey With Modular Monolith and GraphQL

A real-world case study of migrating a two-tier architecture to a three-tier architecture.

Petar IvanovPetar Ivanov
6 min read
On this page

A while ago, I worked for a client who had a diverse portfolio of digital products.

They’ve struggled to develop new features, reuse business logic and functionality across products, and also scale the engineering team.

By digging deeper into the case, I’ve found they have:

  • bad architecture, which doesn’t support their growth
  • years of accumulated technical debt

The root cause turned out to be a 2-Tier Architecture that had outlived its purpose.

In today’s article, I’ll share how I tackled this challenge by migrating their system from a Two-Tier Architecture to a Three-Tier Architecture, introducing a scalable, robust GraphQL API.


IcePanel is a collaborative diagramming and modelling tool for designing software architecture. Create interactive, layered views for different stakeholders from a single source of truth.


Before we dive into the actual migration journey, let’s ensure we understand what a 2-Tier and a 3-Tier architecture are.

What is Two-Tier Architecture?

2-Tier Architecture is a simple setup in which your application talks directly to a database.

You have a presentation layer (the front-end) and a data layer (the database).

That’s it. No middle layer.

Think of it like a simple website or app that sends requests directly to the database, retrieves the data, and displays it to users.

Diagram created in IcePanel.


What is Three-Tier Architecture?

3-Tier Architecture adds an essential middle layer between your front-end and database. Now you have:

  1. Presentation Layer - the front-end (what users see).
  2. Business Logic Layer - the API (where the magic happens).
  3. Data Layer - the database (where data lives).

The middle layer handles all the business logic, security, and data processing.

Diagram created in IcePanel. Link to the diagram.

The main difference between a 2-Tier and a 3-Tier architecture is the separation of concerns.

In a Two-Tier architecture, your front-end must know too much about your data, whereas in a Three-Tier architecture, the business logic layer acts as a smart middleman.

This smart middleman protects your data and enables the whole system to be more flexible.


The Starting Architecture (Two-Tier)

Now, let me show you what the client’s system looked like before the migration.

Diagram created in IcePanel.

They had three main services, all sharing one MySQL database:

  • Portal - The customer-facing web portal. The front-end was React, but the back-end was built with CakePHP 2 (an outdated PHP framework).
  • Admin - The internal management web portal of the company. Everyone in the company used it to run the business, from operations to finance. Also built with CakePHP 2.
  • API - A small REST API with just three methods for customers. Again, Cake PHP 2.

All three services are connected directly to the same MySQL database.

The database was the integration point for everything.

This setup created several serious problems.

The Top Technical Challenges

  • Duplicated logic - The same business logic and rules were duplicated in multiple services.
  • Database as an integration point - Having multiple services write to the same database is risky. There is no single source of truth for business logic and data validation. Also, it is very hard to update or migrate the database when having multiple clients.
  • Technical debt - CakePHP 2 reached end of life. There was a need to modernize the tech stack by using well-adapted technologies.
  • Hard to scale the engineering team - This was hard to find developers to work on front-end and back-end with the present technologies. There was a need to enable full-stack developers.
  • Slow feature development - With the challenges mentioned above, feature development was slow, hindering the business's growth.

To address these challenges, we introduced a new middle layer—a GraphQL API.

The Final Architecture (Three-Tier)

The GraphQL API became the heart of the system.

It sits between all front-ends and the database.

Diagram created in IcePanel. Link to the diagram.

The Main Architectural Improvements

The new architecture solved our major pain points:

  • Centralized business logic - All business-related logic lives in one place now. The GraphQL API is the single source of truth for all features.
  • Single database owner - Only the GraphQL API can access the database. This makes the system safer and easier to refactor.
  • Modern tech stack - We built the API using Node.js, a technology already used by the company. Apart from that, GraphQL provides flexible, efficient data fetching to accommodate the needs of different API clients.
  • Full-stack friendly - Having the same core technology, JavaScript, on the front-end and back-end, enabled the company to hire Full-Stack JavaScript developers.
  • Ready for microservices - To ensure the system's future flexibility and the company’s growth, the API was designed as a Modular Monolith, so that, when needed, internal modules could be extracted into separate services.

The Migration Approach

We didn’t rebuild everything overnight.

This was too risky from both a business and an engineering perspective.

The business must continue operating while the groundwork is being done under the hood.

That’s why we took an iterative approach:

  • Phase 1: Build the GraphQL API - We created the new API layer, starting with the most critical business logic, shared across multiple services.
  • Phase 2: Migrate Portal - The Portal front-end started using the GraphQL API. We moved features one by one and tested thoroughly.
  • Phase 3: Update Admin - We upgraded Admin to a modern version of CakePHP. Then we gradually moved its logic to the GraphQL API, starting with shared functionality.
  • Phase 4: Rewrite REST API - The customer-facing REST API had only three methods, so we rewrote it in Node.js to align with the new stack.
  • Phase 5: Migrate Admin to React - We started migrating the Admin to React, instead of CakePHP, prioritizing newly incoming feature requests.

📌 TL;DR

  • 2-Tier Architecture is when multiple clients or services directly communicate with the Database.
  • 3-Tier Architecture is when multiple clients or services communicate with a middle layer, usually an API, which then communicates with the actual DB.
  • Having three clients communicating with a DB means duplicated business logic everywhere.
  • Having a middle layer, in this case a GraphQL API, means a single user communicates with the DB, removing duplicate business logic.
  • Centralizing business logic in the GraphQL API eliminated duplicate code, made onboarding new teammates easier, enabled quicker feature delivery, and created a system ready to scale into microservices when needed.

Related articles

Whenever you’re ready, here’s how I can help you:

  1. 1.

    The Conscious React: React architecture, design & clean code — 100+ production tips across 6 chapters, updated for React 19, plus 4 companion repos you can clone and run.

  2. 2.

    The Conscious Node: Node.js architecture, design & clean code — 157 production tips across 10 chapters, from module boundaries to the transactional outbox and zero-downtime deploys.

  3. 3.

    The JavaScript Architect Bundle: Both books + all React companion repos + CLAUDE.md rulesets + both playbooks. The complete path from developer to architect.

  4. 4.

    Free Resources: Architecture playbooks, cheat-sheets, and the JavaScript Architect Roadmap — practical guides for leveling up to senior.

The T-Shaped Dev

Join 30K+ engineers leveling up to architect

One practical tip on JavaScript, React, Node.js, and software architecture every week. No spam, unsubscribe anytime.

Petar Ivanov

Written by

Petar Ivanov

Software engineer, author, and speaker. I help JavaScript developers grow from Mid → Senior → Architect — production-grade React, Node.js, and AI systems.