Case Study · Database Architecture & Migration

The license savings paid for
an entirely new infrastructure.

A company was spending heavily on MS SQL Server licensing — cost that delivered no competitive advantage, just the right to keep their data where it already was. We redesigned their data architecture, migrated to MongoDB without disrupting business hours, and redirected every rupee of licensing savings into a 3-node high-availability cluster. Same budget. Triple the infrastructure. Zero downtime.

DomainDatabase Architecture & Migration
EngagementArchitecture Consulting & Delivery
ClientConfidential
BeforeSingle server · High licensing cost
⬛
Application Server
↓
🗄
MS SQL Server
Single instance · No failover
$$$ License
⚠ Single point of failure
→
After3-node cluster · Zero licensing cost
NGINX Load Balancer
↓
App 1
App 2
App 3
↓
MongoDB Primary
Read + Write
Secondary 1
Read replica
Secondary 2
Read replica
✓ Auto-failover · No single point of failure
100%
Licensing cost eliminated

MS SQL Server license spend dropped to zero — redirected entirely to infrastructure

3×
Infrastructure scale

From 1 server to a 3-node cluster with load balancer — same budget, triple the capacity

↑HA
High availability achieved

Automatic failover in seconds — no single point of failure in the data layer

<4m
Total downtime

Business hours untouched throughout — final cutover under 4 minutes on a weekend window

The Challenge

Paying for a licence. Getting a single point of failure.

The client was running their entire operation on a single MS SQL Server instance. The annual licensing and support cost was substantial — a recurring spend that scaled with the vendor's pricing model, not the company's actual usage or growth. Worse, the money was buying them something inherently fragile: one database server, no redundancy, no failover. If it went down, the business went down with it.

The engineering team was experienced with SQL but locked into a relational mindset that did not always fit the application's data — nested structures, variable-schema records, and document-centric reads were being forced through a normalised relational model, adding join complexity and hurting query performance on the workloads that mattered.

The ask was clear but demanding: move off SQL Server, eliminate the license cost, redesign the architecture for scale and resilience, and do it without any disruption during the working day. The business could not afford a migration window that impacted customers or operations.

The problems
  • Heavy annual SQL Server licensing with no flexibility
  • Single database instance — no redundancy, no HA
  • Relational model misaligned with document-heavy data
  • Stored procedures creating tight coupling to SQL Server
  • No read scaling — every query hit the single primary
  • Migration could not impact business-hour operations
The constraints
  • Zero downtime during business hours — non-negotiable
  • Existing engineering team must own the new stack after handover
  • Same total budget — no additional infrastructure spend approved
  • All historical data must migrate without loss or corruption
  • Rollback must be possible at every stage
Architecture Redesign

Fluid layers. Plug-and-play components.

This was not a straight swap of SQL Server for MongoDB. The architecture was redesigned from the ground up — decoupled, layered, and built so that any component could be replaced, scaled, or upgraded without touching the others.

Client Layer
Web, mobile, and API consumers — decoupled from data layer via versioned API contracts.
Web clientsMobile appsThird-party API consumers
↓
Load Balancer
NGINX distributes traffic across the application tier. Health checks route around unhealthy nodes automatically.
NGINX reverse proxyHealth-check routingSSL termination
↓
Application Tier
Stateless application nodes — any node can serve any request. Horizontal scaling by adding nodes with no configuration change.
App Node 1App Node 2App Node 3 (new)
↓
ODM / Data Access Layer
Mongoose schema layer provides validation, middleware hooks, and a query API. The application code is decoupled from raw MongoDB — the ODM is the only component that knows the storage engine.
Mongoose schemasQuery APIValidation middlewareConnection pooling
↓
MongoDB Replica Set
3-node replica set with automatic primary election. Reads distributed across secondaries. Any node failure is handled automatically with no application restart.
Primary (read + write)Secondary 1 (read replica)Secondary 2 (read replica)Automatic failover
Plug-and-play by design

Each layer communicates only with the layer immediately above and below it through defined interfaces. The database layer has no knowledge of the application layer. The application layer has no knowledge of the load balancer configuration. Adding a fourth application node, swapping the load balancer, or scaling the MongoDB cluster requires changes to exactly one layer — not the whole stack.

Migration Approach

Six phases. Zero business-hour disruption.

The migration was designed so that at every stage, SQL Server remained the source of truth and a full rollback was possible. No phase was declared complete until the next phase was ready to take over.

01
Weeks 1–2

Architecture audit & schema redesign

We began with a complete audit of the existing SQL Server schema — every table, relationship, stored procedure, and index. Rather than mapping SQL tables directly to MongoDB collections (a common mistake), we redesigned the data model around document semantics: embedding related data where reads are frequent, referencing where write amplification would be a concern. The new schema was built for the query patterns the application actually used, not the normalisation rules of a relational model.

Schema analysisQuery pattern mappingDocument modellingDenormalisation strategy
02
Weeks 2–3

MongoDB cluster setup & HA configuration

A 3-node MongoDB replica set was provisioned on the new infrastructure — primary + two secondaries — with an NGINX load balancer in front of the application tier. Read preference was configured to distribute reads across secondaries, offloading the primary. Automatic failover was tested: when the primary was taken down deliberately, a secondary was elected within seconds with no application error.

Replica setNGINX load balancerRead preference configFailover testing
03
Weeks 3–5

Dual-write migration layer

A custom migration middleware was inserted into the application write path. Every write went to both SQL Server and MongoDB simultaneously. This dual-write phase allowed MongoDB data to be validated against SQL Server as the source of truth — record counts, field values, referential integrity — before any traffic was shifted. No data migration script was trusted until it had been verified against live production writes.

Dual-write middlewareLive data validationZero data loss guaranteeParallel run
04
Weeks 4–6

Historical data migration

A batched ETL pipeline migrated historical records from SQL Server to MongoDB in off-peak windows — nights and weekends — without touching business-hour traffic. Records were migrated, transformed to the new document schema, validated, and checksummed. The pipeline was resumable: if interrupted, it picked up from the last verified batch. Migration ran over several weeks alongside the dual-write layer, with completeness verified at each stage.

Batched ETL pipelineOff-peak migration windowsChecksum validationResumable migration
05
Weeks 6–7

Gradual traffic cutover

Read traffic was shifted to MongoDB gradually — starting at 5% via feature flag, monitoring error rates and latency. Increased to 25%, 50%, 75%, then 100% over several days, with automatic rollback triggers if error thresholds were breached. Write traffic was cut over last, on a weekend maintenance window that was communicated to users as a brief scheduled maintenance — actual downtime was under 4 minutes.

Feature flag rolloutCanary traffic shiftingAutomatic rollbackUnder 4 min downtime
06
Weeks 7–9

Staff training & SQL Server decommission

The engineering and operations teams received structured training on MongoDB — query language, aggregation pipelines, index strategy, replica set administration, and backup procedures. MongoDB Compass was deployed as the primary GUI. Runbooks were written for common operational tasks. Only after the team demonstrated comfort with the new stack was SQL Server decommissioned and the licenses allowed to lapse.

MongoDB trainingAggregation pipelinesCompass deploymentOperational runbooks
Schema Transformation

From tables to documents — a different way of thinking.

SQL Server (Before)
-- 3 tables, 2 JOINs per read
 
CREATE TABLE Orders (
OrderId INT PRIMARY KEY,
CustomerId INT FK,
CreatedAt DATETIME
);
 
CREATE TABLE OrderItems (
ItemId INT PRIMARY KEY,
OrderId INT FK,
ProductId INT FK,
Qty INT,
Price DECIMAL
);
 
SELECT o.*, i.*, p.*
FROM Orders o
JOIN OrderItems i ON i.OrderId = o.OrderId
JOIN Products p ON p.ProductId = i.ProductId
WHERE o.OrderId = 123;
→
MongoDB (After)
// 1 collection, 0 JOINs
 
{
"_id": ObjectId("..."),
"createdAt": ISODate("..."),
"customer": {
"id": "cust_001",
"name": "Acme Corp"
},
"items": [
{ "product": "Widget A",
"qty": 3,
"price": 49.99 }
]
}
 
// Single document fetch
db.orders.findOne({ _id: id });
Related data embedded in the document — one read, one network round-trip, no JOIN overhead. Write patterns that change frequently are referenced rather than embedded, keeping document sizes predictable.
Technologies

The stack after migration

MongoDB
Primary database — 3-node replica set
NGINX
Load balancer + reverse proxy across app tier
Mongoose
ODM layer for schema validation and query API
Custom ETL pipeline
Batched historical data migration with validation
MongoDB Compass
GUI for operations team — queries and index management
Replica Set
1 primary + 2 secondaries, automatic failover
Node.js
Application tier — updated to Mongoose from SQL ORM
Feature Flags
Controlled read/write traffic cutover with rollback
mongodump / mongorestore
Backup and disaster recovery procedures
Aggregation Pipeline
Complex reporting queries replacing stored procedures
Atlas Search (optional)
Full-text search layer to replace SQL LIKE queries
PM2 / Systemd
Process management across the 3-node application cluster
Work with us

Carrying a database license you've outgrown?

If licensing costs are consuming budget that should go into infrastructure, performance, or product — we can audit your stack, plan the migration, and execute it without disrupting your operations.