Master-Slave Architecture is a replication setup where:
One master (primary) node handles all write operations.
One or more slave (secondary/replica) nodes handle read-only queries and replicate data from the master.
✅ Writes go to Master
✅ Reads go to Slaves (for load distribution)
🔁 Slaves sync with Master periodically or in real-time
🔁 Diagram Overview
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Master-Slave Architecture — Try It Yourself</title>
<style>
.infographic-masterslave {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--good: #16a34a;
--good-soft: #dcfce7;
--bad: #dc2626;
--bad-soft: #fee2e2;
--warn: #b45309;
--warn-soft: #fef3c7;
--on-accent: #ffffff;
--display-font: Georgia, 'Iowan Old Style', serif;
--body-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
--mono-font: 'SF Mono', Consolas, monospace;
background: var(--paper);
color: var(--ink);
font-family: var(--body-font);
max-width: 820px;
margin: 0 auto;
box-sizing: border-box;
overflow-x: hidden;
}
.infographic-masterslave[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--good: #4ade80;
--good-soft: #123420;
--bad: #f87171;
--bad-soft: #3a1414;
--warn: #fbbf24;
--warn-soft: #3a2f0e;
--on-accent: #101418;
}
.infographic-masterslave * { box-sizing: border-box; }
.ms-head { text-align: center; margin-bottom: 0.25rem; }
.ms-head h2 { font-family: var(--display-font); font-size: 1.85rem; margin: 0 0 0.5rem; }
.ms-head p { color: var(--ink-soft); font-size: 0.95rem; margin: 0 auto; max-width: 560px; line-height: 1.55; }
.ms-frame { background: var(--paper-alt); border: 1px solid var(--line); border-radius: 10px; padding: 1.25rem; margin-top: 1.5rem; }
.ms-diagram-scroll { overflow-x: auto; }
.ms-diagram-scroll svg { width: 100%; height: auto; display: block; min-width: 420px; }
.ms-node-box { fill: var(--paper); stroke: var(--accent); stroke-width: 2; transition: fill 0.4s, stroke 0.4s; }
.ms-node-box.is-master { fill: var(--accent); }
.ms-node-text { font-size: 13px; font-weight: 700; font-family: var(--body-font); text-anchor: middle; fill: var(--ink); }
.ms-node-text.is-onaccent { fill: var(--on-accent); }
.ms-version-text { font-size: 11px; font-family: var(--mono-font); text-anchor: middle; fill: var(--ink-soft); transition: fill 0.3s; }
.ms-version-text.is-stale { fill: var(--warn); font-weight: 700; }
.ms-version-text.is-fresh { fill: var(--good); font-weight: 700; }
.ms-label-text { font-size: 11px; font-family: var(--body-font); text-anchor: middle; fill: var(--ink-soft); }
.ms-edge { stroke: var(--ink-soft); stroke-width: 2; fill: none; marker-end: url(#msArrow); }
.ms-edge.is-flowing { stroke: var(--accent); stroke-width: 2.5; stroke-dasharray: 6 5; animation: ms-flow 0.6s linear infinite; }
@keyframes ms-flow { to { stroke-dashoffset: -22; } }
.ms-edge.is-blocked { stroke: var(--bad); }
.ms-node-box.is-read-pulse { animation: ms-read-pulse 0.6s ease; }
@keyframes ms-read-pulse {
0% { stroke: var(--accent); stroke-width: 2; }
40% { stroke: var(--accent); stroke-width: 5; }
100% { stroke: var(--accent); stroke-width: 2; }
}
.ms-scan-ring {
fill: none; stroke: var(--accent); stroke-width: 2; opacity: 0;
transform-origin: 555px 80px;
}
.ms-scan-ring.is-active { animation: ms-scan-ring 0.7s ease-out; }
@keyframes ms-scan-ring {
0% { opacity: 0.9; transform: scale(0.6); }
100% { opacity: 0; transform: scale(1.6); }
}
.ms-node-box.is-blocked-shake { animation: ms-shake 0.45s ease; stroke: var(--bad); }
@keyframes ms-shake {
0%, 100% { transform: translateX(0); }
20% { transform: translateX(-6px); }
40% { transform: translateX(6px); }
60% { transform: translateX(-4px); }
80% { transform: translateX(4px); }
}
.ms-blocked-x {
opacity: 0; font-size: 26px; font-weight: 900; fill: var(--bad); text-anchor: middle;
}
.ms-blocked-x.is-active { animation: ms-blocked-x 0.7s ease; }
@keyframes ms-blocked-x {
0% { opacity: 0; transform: scale(0.4); }
30% { opacity: 1; transform: scale(1.15); }
60% { opacity: 1; transform: scale(1); }
100% { opacity: 0; transform: scale(1); }
}
.ms-run-row { display: flex; justify-content: center; gap: 0.6rem; margin-top: 1.25rem; flex-wrap: wrap; }
.ms-run-btn {
font: inherit; font-size: 0.85rem; background: var(--accent); color: var(--on-accent);
border: none; border-radius: 7px; padding: 0.6rem 1.1rem; cursor: pointer;
}
.ms-run-btn:hover { opacity: 0.9; }
.ms-run-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.ms-run-btn.is-danger { background: var(--bad); }
.ms-run-btn.is-secondary { background: var(--paper); color: var(--ink); border: 1px solid var(--line); }
.ms-msg {
margin-top: 1rem; padding: 0.65rem 0.9rem; border-radius: 8px; font-size: 0.85rem;
line-height: 1.55; display: none;
}
.ms-msg.is-visible { display: block; }
.ms-msg.st-good { background: var(--good-soft); color: var(--good); }
.ms-msg.st-bad { background: var(--bad-soft); color: var(--bad); }
.ms-msg.st-warn { background: var(--warn-soft); color: var(--warn); }
@media (prefers-reduced-motion: reduce) {
.infographic-masterslave *, .infographic-masterslave *::before, .infographic-masterslave *::after {
transition-duration: 0.001ms !important; animation-duration: 0.001ms !important;
}
}
</style>
</head>
<body>
<div class="infographic-masterslave" id="masterslave">
<div class="ms-head">
<h2>What is Master-Slave Architecture</h2>
<p>One master handles every write. Replicas only ever copy from it — try writing, then reading, and watch what happens in between.</p>
</div>
<div class="ms-frame">
<div class="ms-diagram-scroll">
<svg viewBox="0 0 640 300" role="img" aria-label="User connected to Master database, which replicates to Replica-1 and Replica-2">
<defs>
<marker id="msArrow" markerWidth="8" markerHeight="8" refX="4" refY="4" orient="auto">
<path d="M0,0 L8,4 L0,8 z" fill="var(--ink-soft)"></path>
</marker>
</defs>
<!-- User <-> Master -->
<path class="ms-edge" d="M95,150 L215,150" marker-end="url(#msArrow)"></path>
<path class="ms-edge" d="M215,158 L95,158" marker-end="url(#msArrow)"></path>
<text class="ms-label-text" x="155" y="138">Read / Write</text>
<!-- Master -> Replica 1 -->
<path class="ms-edge" id="msEdge1" d="M335,140 L505,80" marker-end="url(#msArrow)"></path>
<text class="ms-label-text" x="420" y="95">Replication Stream</text>
<!-- Master -> Replica 2 -->
<path class="ms-edge" id="msEdge2" d="M335,165 L505,225" marker-end="url(#msArrow)"></path>
<text class="ms-label-text" x="420" y="245">Replication Stream</text>
<!-- User node -->
<circle cx="55" cy="150" r="28" fill="var(--paper)" stroke="var(--accent)" stroke-width="2"></circle>
<text class="ms-node-text" x="55" y="155">👤</text>
<text class="ms-node-text" x="55" y="200">User</text>
<!-- Master node -->
<rect class="ms-node-box is-master" x="245" y="115" width="90" height="70" rx="8"></rect>
<text class="ms-node-text is-onaccent" x="290" y="145">DB</text>
<text class="ms-node-text is-onaccent" x="290" y="163" font-size="10">Master</text>
<text class="ms-version-text" id="msMasterVersion" x="290" y="207">version 0</text>
<!-- Replica 1 node -->
<g id="msReplica1Group">
<circle class="ms-scan-ring" id="msScanRing" cx="555" cy="80" r="45"></circle>
<rect class="ms-node-box" id="msReplica1Box" x="510" y="45" width="90" height="70" rx="8"></rect>
<text class="ms-node-text" x="555" y="75">DB</text>
<text class="ms-node-text" x="555" y="93" font-size="10">Replica-1</text>
<text class="ms-version-text" id="msReplica1Version" x="555" y="137">version 0</text>
<text class="ms-blocked-x" id="msBlockedX" x="555" y="88">✕</text>
</g>
<!-- Replica 2 node -->
<rect class="ms-node-box" x="510" y="190" width="90" height="70" rx="8"></rect>
<text class="ms-node-text" x="555" y="220">DB</text>
<text class="ms-node-text" x="555" y="238" font-size="10">Replica-2</text>
<text class="ms-version-text" id="msReplica2Version" x="555" y="282">version 0</text>
</svg>
</div>
<div class="ms-run-row">
<button class="ms-run-btn" id="msWriteBtn" type="button">✍️ Write to Master</button>
<button class="ms-run-btn is-secondary" id="msReadBtn" type="button">📖 Read from Replica-1</button>
<button class="ms-run-btn is-danger" id="msWriteReplicaBtn" type="button">🚫 Try Write to Replica-1</button>
</div>
<p class="ms-msg" id="msMsg"></p>
</div>
</div>
<script>
(function () {
const wrapper = document.getElementById('masterslave');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') {
dark = true;
} else if (bodyAttr === 'false') {
dark = false;
} else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
})();
(function () {
let masterVersion = 0;
let replica1Version = 0;
let replica2Version = 0;
const masterVersionEl = document.getElementById('msMasterVersion');
const replica1VersionEl = document.getElementById('msReplica1Version');
const replica2VersionEl = document.getElementById('msReplica2Version');
const edge1 = document.getElementById('msEdge1');
const edge2 = document.getElementById('msEdge2');
const writeBtn = document.getElementById('msWriteBtn');
const readBtn = document.getElementById('msReadBtn');
const writeReplicaBtn = document.getElementById('msWriteReplicaBtn');
const msg = document.getElementById('msMsg');
function showMsg(text, kind) {
msg.textContent = text;
msg.className = 'ms-msg is-visible st-' + kind;
}
function renderVersions() {
masterVersionEl.textContent = 'version ' + masterVersion;
replica1VersionEl.textContent = 'version ' + replica1Version;
replica1VersionEl.className = 'ms-version-text' + (replica1Version < masterVersion ? ' is-stale' : (replica1Version > 0 ? ' is-fresh' : ''));
replica2VersionEl.textContent = 'version ' + replica2Version;
replica2VersionEl.className = 'ms-version-text' + (replica2Version < masterVersion ? ' is-stale' : (replica2Version > 0 ? ' is-fresh' : ''));
}
writeBtn.addEventListener('click', () => {
writeBtn.disabled = true;
masterVersion++;
renderVersions();
showMsg('✔️ Write acknowledged by Master immediately (version ' + masterVersion + '). Replicas have not caught up yet — try reading from Replica-1 right now.', 'good');
edge1.classList.add('is-flowing');
edge2.classList.add('is-flowing');
setTimeout(() => {
replica1Version = masterVersion;
renderVersions();
edge1.classList.remove('is-flowing');
}, 1600);
setTimeout(() => {
replica2Version = masterVersion;
renderVersions();
edge2.classList.remove('is-flowing');
writeBtn.disabled = false;
}, 2200);
});
readBtn.addEventListener('click', () => {
const box = document.getElementById('msReplica1Box');
const ring = document.getElementById('msScanRing');
box.classList.remove('is-read-pulse');
ring.classList.remove('is-active');
void box.offsetWidth;
box.classList.add('is-read-pulse');
ring.classList.add('is-active');
if (replica1Version < masterVersion) {
showMsg('⚠️ Stale read from Replica-1 — it\u2019s still on version ' + replica1Version + ' while Master is already on version ' + masterVersion + '. This gap is called replication lag.', 'warn');
} else {
showMsg('✔️ Read from Replica-1 — up to date at version ' + replica1Version + '.', 'good');
}
});
writeReplicaBtn.addEventListener('click', () => {
const box = document.getElementById('msReplica1Box');
const xMark = document.getElementById('msBlockedX');
box.classList.remove('is-blocked-shake');
xMark.classList.remove('is-active');
void box.offsetWidth;
box.classList.add('is-blocked-shake');
xMark.classList.add('is-active');
showMsg('❌ Blocked — replicas are read-only in this architecture. Every write must go through the Master.', 'bad');
});
renderVersions();
})();
</script>
</body>
</html>.demo {
font-family: system-ui, sans-serif;
padding: 16px;
}
.demo h1 {
color: #2563eb;
margin: 0 0 8px;
}
.demo p {
color: #4b5563;
margin: 0;
}document.querySelector('.demo h1')?.addEventListener('click', () => {
alert('Hello from live preview!');
});⚙️ How It Works
Operation Type | Performed By | Notes |
|---|---|---|
INSERT/UPDATE/DELETE | Master | Only master can modify data |
SELECT/READ | Slaves (or Master) | Slaves can reduce load on master |
Replication | Master → Slaves | Asynchronous or Synchronous |
🟢 Advantages
Benefit | Explanation |
|---|---|
✅ Improved Read Performance | Multiple slaves can handle read-heavy workloads |
✅ Backup & Redundancy | Slaves can be used as backups or failovers |
✅ Simplified Writes | Only one node handles writes, so no write conflicts |
✅ Horizontal Read Scaling | Add more slaves to support more read clients |
🔴 Disadvantages
Limitation | Impact |
|---|---|
❌ Single Point of Failure (SPoF) | If master fails, writes stop (unless failover configured) |
❌ Replication Lag | Slaves may lag behind the master (eventual consistency) |
❌ No Write Scaling | Only one master; can't scale write operations easily |
❌ Complex Failover | Promoting a slave to master requires coordination and possible downtime |
🧩 Use Cases
Use Case | Reason |
|---|---|
📘 Content-heavy websites | Most operations are read-heavy |
📈 Analytics dashboards | Run heavy reads on slaves without overloading the master |
🛒 E-commerce product pages | Customers read from slaves; checkout writes to master |
💾 Database backup systems | Backups can be taken from slaves without affecting production writes |
🔄 Synchronous vs Asynchronous Replication
Mode | Description | Pros | Cons |
|---|---|---|---|
🔁 Synchronous | Slaves acknowledge data before master confirms write | Strong consistency | Slower performance |
🕒 Asynchronous | Master confirms write immediately; slaves catch up later | Faster performance | Possibility of stale reads or data loss during failover |
🛠️ Real-World Systems Using It
Database | Notes |
|---|---|
✅ MySQL | Has native master-slave replication |
✅ PostgreSQL | Supports streaming replication |
✅ MongoDB | Primary-Secondary model (similar to master-slave) |
✅ Redis | Master-slave replication for performance and HA |
✅ SQL Server | Supports log shipping and transactional replication |
✅ Summary
Feature | Master-Slave |
|---|---|
✅ Write Scalability | ❌ No (single master) |
✅ Read Scalability | ✅ Yes (multiple slaves) |
✅ Fault Tolerance | ✅ Partial (if failover configured) |
✅ Consistency | ❌ Weak (if async), ✅ Strong (if sync) |
✅ Use Case Fit | Read-heavy workloads, backup, redundancy |