<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Cap-Theorem on IT Comparison</title><link>https://comparison.metacog.co.kr/tags/cap-theorem/</link><description>Recent content in Cap-Theorem on IT Comparison</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Sun, 06 Sep 2026 09:36:30 +0900</lastBuildDate><atom:link href="https://comparison.metacog.co.kr/tags/cap-theorem/index.xml" rel="self" type="application/rss+xml"/><item><title>Strong vs Eventual Consistency: Data Replication Tradeoff</title><link>https://comparison.metacog.co.kr/posts/2026-09-06-strong-vs-eventual-consistency-data-replication-tradeoff/</link><pubDate>Sun, 06 Sep 2026 09:36:30 +0900</pubDate><guid>https://comparison.metacog.co.kr/posts/2026-09-06-strong-vs-eventual-consistency-data-replication-tradeoff/</guid><description>&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;
&lt;p&gt;Strong and eventual consistency describe how distributed systems handle replicated data after a write. &lt;strong class="kw"&gt;Strong consistency&lt;/strong&gt; guarantees every read reflects the latest write by blocking until replicas agree, while &lt;strong class="kw"&gt;eventual consistency&lt;/strong&gt; returns immediately and lets replicas converge in the background. The choice trades write latency and availability against read freshness.&lt;/p&gt;
&lt;h2 id="comparison-diagram"&gt;Comparison Diagram&lt;/h2&gt;
&lt;div class="compare-diagram"&gt;
&lt;svg viewBox="0 0 640 360" xmlns="http://www.w3.org/2000/svg"&gt;&lt;text x="160" y="32" text-anchor="middle" font-size="18" font-weight="bold" style="fill:var(--primary)"&gt;Strong Consistency&lt;/text&gt;&lt;text x="480" y="32" text-anchor="middle" font-size="18" font-weight="bold" style="fill:var(--primary)"&gt;Eventual Consistency&lt;/text&gt;&lt;line x1="320" y1="50" x2="320" y2="340" style="stroke:var(--border)" stroke-width="1.5" stroke-dasharray="4 4"/&gt;&lt;circle cx="55" cy="110" r="20" style="fill:var(--compare-a-soft);stroke:var(--compare-a)" stroke-width="1.5"/&gt;&lt;text x="55" y="115" text-anchor="middle" font-size="11" style="fill:var(--content)"&gt;Client&lt;/text&gt;&lt;rect x="130" y="90" width="70" height="36" rx="4" style="fill:var(--compare-a-soft);stroke:var(--compare-a)" stroke-width="1.5"/&gt;&lt;text x="165" y="112" text-anchor="middle" font-size="11" style="fill:var(--content)"&gt;Primary&lt;/text&gt;&lt;rect x="240" y="55" width="65" height="32" rx="4" style="fill:var(--compare-a-soft);stroke:var(--compare-a)" stroke-width="1.5"/&gt;&lt;text x="272" y="75" text-anchor="middle" font-size="10" style="fill:var(--content)"&gt;Replica 1&lt;/text&gt;&lt;rect x="240" y="128" width="65" height="32" rx="4" style="fill:var(--compare-a-soft);stroke:var(--compare-a)" stroke-width="1.5"/&gt;&lt;text x="272" y="148" text-anchor="middle" font-size="10" style="fill:var(--content)"&gt;Replica 2&lt;/text&gt;&lt;line x1="75" y1="108" x2="128" y2="108" style="stroke:var(--compare-a)" stroke-width="1.5" marker-end="url(#arrowA)"/&gt;&lt;line x1="200" y1="100" x2="238" y2="75" style="stroke:var(--compare-a)" stroke-width="1.5" marker-end="url(#arrowA)"/&gt;&lt;line x1="200" y1="118" x2="238" y2="140" style="stroke:var(--compare-a)" stroke-width="1.5" marker-end="url(#arrowA)"/&gt;&lt;text x="165" y="178" text-anchor="middle" font-size="10" style="fill:var(--secondary)"&gt;write blocks until&lt;/text&gt;&lt;text x="165" y="190" text-anchor="middle" font-size="10" style="fill:var(--secondary)"&gt;all replicas ack&lt;/text&gt;&lt;line x1="55" y1="135" x2="55" y2="210" style="stroke:var(--border)" stroke-width="1"/&gt;&lt;rect x="20" y="235" width="280" height="60" rx="4" style="fill:none;stroke:var(--compare-a)" stroke-width="1.5" stroke-dasharray="3 3"/&gt;&lt;text x="160" y="260" text-anchor="middle" font-size="11" style="fill:var(--content)"&gt;Any read, any replica,&lt;/text&gt;&lt;text x="160" y="278" text-anchor="middle" font-size="11" style="fill:var(--content)"&gt;always returns latest value&lt;/text&gt;&lt;circle cx="395" cy="110" r="20" style="fill:var(--compare-b-soft);stroke:var(--compare-b)" stroke-width="1.5"/&gt;&lt;text x="395" y="115" text-anchor="middle" font-size="11" style="fill:var(--content)"&gt;Client&lt;/text&gt;&lt;rect x="470" y="90" width="70" height="36" rx="4" style="fill:var(--compare-b-soft);stroke:var(--compare-b)" stroke-width="1.5"/&gt;&lt;text x="505" y="112" text-anchor="middle" font-size="11" style="fill:var(--content)"&gt;Node&lt;/text&gt;&lt;rect x="580" y="55" width="55" height="32" rx="4" style="fill:var(--compare-b-soft);stroke:var(--compare-b)" stroke-width="1.5"/&gt;&lt;text x="607" y="75" text-anchor="middle" font-size="10" style="fill:var(--content)"&gt;Replica 1&lt;/text&gt;&lt;rect x="580" y="128" width="55" height="32" rx="4" style="fill:var(--compare-b-soft);stroke:var(--compare-b)" stroke-width="1.5"/&gt;&lt;text x="607" y="148" text-anchor="middle" font-size="10" style="fill:var(--content)"&gt;Replica 2&lt;/text&gt;&lt;line x1="415" y1="103" x2="468" y2="103" style="stroke:var(--compare-b)" stroke-width="1.5" marker-end="url(#arrowB)"/&gt;&lt;line x1="468" y1="117" x2="415" y2="117" style="stroke:var(--compare-b)" stroke-width="1.5" marker-end="url(#arrowB)"/&gt;&lt;text x="440" y="132" text-anchor="middle" font-size="9" style="fill:var(--secondary)"&gt;ACK immediate&lt;/text&gt;&lt;line x1="540" y1="98" x2="578" y2="75" style="stroke:var(--compare-b)" stroke-width="1.5" stroke-dasharray="4 3" marker-end="url(#arrowB)"/&gt;&lt;line x1="540" y1="118" x2="578" y2="140" style="stroke:var(--compare-b)" stroke-width="1.5" stroke-dasharray="4 3" marker-end="url(#arrowB)"/&gt;&lt;text x="550" y="188" text-anchor="middle" font-size="10" style="fill:var(--secondary)"&gt;async, delayed&lt;/text&gt;&lt;rect x="360" y="235" width="260" height="60" rx="4" style="fill:none;stroke:var(--compare-b)" stroke-width="1.5" stroke-dasharray="3 3"/&gt;&lt;text x="490" y="258" text-anchor="middle" font-size="11" style="fill:var(--content)"&gt;Read from Replica 1 may&lt;/text&gt;&lt;text x="490" y="276" text-anchor="middle" font-size="11" style="fill:var(--content)"&gt;return stale value until t+Δ&lt;/text&gt;&lt;defs&gt;&lt;marker id="arrowA" markerWidth="8" markerHeight="8" refX="6" refY="3" orient="auto"&gt;&lt;path d="M0,0 L6,3 L0,6 Z" style="fill:var(--compare-a)"/&gt;&lt;/marker&gt;&lt;marker id="arrowB" markerWidth="8" markerHeight="8" refX="6" refY="3" orient="auto"&gt;&lt;path d="M0,0 L6,3 L0,6 Z" style="fill:var(--compare-b)"/&gt;&lt;/marker&gt;&lt;/defs&gt;&lt;/svg&gt;
&lt;/div&gt;
&lt;h2 id="comparison-table"&gt;Comparison Table&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Strong Consistency&lt;/th&gt;
&lt;th&gt;Eventual Consistency&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Write acknowledgment&lt;/td&gt;
&lt;td&gt;Ack returned only after write is durably applied to all (or a quorum of) replicas&lt;/td&gt;
&lt;td&gt;Ack returned as soon as the write hits the local/primary node&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Replication propagation&lt;/td&gt;
&lt;td&gt;Synchronous — write blocks until replicas confirm&lt;/td&gt;
&lt;td&gt;Asynchronous — replication happens in the background&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Read guarantee&lt;/td&gt;
&lt;td&gt;Every read reflects the most recent write (linearizable)&lt;/td&gt;
&lt;td&gt;Reads may return stale data until replicas converge&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Conflict handling&lt;/td&gt;
&lt;td&gt;Prevented upfront via consensus/locking that serializes writes&lt;/td&gt;
&lt;td&gt;Resolved after the fact via LWW, vector clocks, or CRDTs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Write latency&lt;/td&gt;
&lt;td&gt;Higher — pays network round-trip cost to replicas/quorum&lt;/td&gt;
&lt;td&gt;Lower — commits locally before propagating&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Behavior under partition&lt;/td&gt;
&lt;td&gt;Unavailable or degraded if quorum can&amp;rsquo;t be reached (CP)&lt;/td&gt;
&lt;td&gt;Stays available, serving from whichever replica is reachable (AP)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Typical mechanism&lt;/td&gt;
&lt;td&gt;Consensus protocols like Paxos/Raft, synchronous quorum writes&lt;/td&gt;
&lt;td&gt;Gossip protocols, anti-entropy repair, background sync&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Typical use cases&lt;/td&gt;
&lt;td&gt;Banking ledgers, inventory counts, leader election&lt;/td&gt;
&lt;td&gt;Social feeds, DNS, shopping carts, CDN caches&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="key-differences"&gt;Key Differences&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Strong consistency blocks the write until a &lt;strong class="kw"&gt;quorum&lt;/strong&gt; confirms; eventual consistency acks after a local commit.&lt;/li&gt;
&lt;li&gt;This is the classic &lt;strong class="kw"&gt;CAP tradeoff&lt;/strong&gt;: strong favors consistency during a partition, eventual favors availability.&lt;/li&gt;
&lt;li&gt;Strong relies on &lt;strong class="kw"&gt;consensus protocols&lt;/strong&gt; like Raft; eventual relies on background &lt;strong class="kw"&gt;anti-entropy&lt;/strong&gt; repair.&lt;/li&gt;
&lt;li&gt;Only strong consistency guarantees &lt;strong class="kw"&gt;read-after-write&lt;/strong&gt;; eventual consistency allows a stale-read window.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="when-to-use-each"&gt;When to Use Each&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Strong Consistency&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Consistency vs Availability: The CAP Theorem Tradeoff</title><link>https://comparison.metacog.co.kr/posts/2026-09-06-consistency-vs-availability-the-cap-theorem-tradeoff/</link><pubDate>Sun, 06 Sep 2026 09:35:36 +0900</pubDate><guid>https://comparison.metacog.co.kr/posts/2026-09-06-consistency-vs-availability-the-cap-theorem-tradeoff/</guid><description>&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;
&lt;p&gt;When a distributed system suffers a network partition, it must choose between &lt;strong class="kw"&gt;consistency&lt;/strong&gt; (every node sees the same data, even if that means rejecting requests) and &lt;strong class="kw"&gt;availability&lt;/strong&gt; (every request gets a response, even if the data might be stale). This CAP theorem tradeoff shapes how databases behave under failure and directly affects correctness guarantees versus uptime.&lt;/p&gt;
&lt;h2 id="comparison-diagram"&gt;Comparison Diagram&lt;/h2&gt;
&lt;div class="compare-diagram"&gt;
&lt;svg viewBox="0 0 640 360" xmlns="http://www.w3.org/2000/svg"&gt;&lt;line x1="320" y1="10" x2="320" y2="350" style="stroke:var(--border)" stroke-width="1.5" stroke-dasharray="6,5"/&gt;&lt;text x="160" y="28" text-anchor="middle" style="fill:var(--primary)" font-size="17" font-weight="bold"&gt;Consistency (CP)&lt;/text&gt;&lt;text x="480" y="28" text-anchor="middle" style="fill:var(--primary)" font-size="17" font-weight="bold"&gt;Availability (AP)&lt;/text&gt;&lt;rect x="100" y="44" width="120" height="36" rx="5" style="fill:var(--compare-a-soft);stroke:var(--compare-a)" stroke-width="1.5"/&gt;&lt;text x="160" y="67" text-anchor="middle" style="fill:var(--content)" font-size="13"&gt;Client&lt;/text&gt;&lt;rect x="420" y="44" width="120" height="36" rx="5" style="fill:var(--compare-b-soft);stroke:var(--compare-b)" stroke-width="1.5"/&gt;&lt;text x="480" y="67" text-anchor="middle" style="fill:var(--content)" font-size="13"&gt;Client&lt;/text&gt;&lt;line x1="140" y1="80" x2="105" y2="140" style="stroke:var(--compare-a)" stroke-width="1.5"/&gt;&lt;polygon points="105,140 112,131 118,138" style="fill:var(--compare-a)"/&gt;&lt;line x1="175" y1="140" x2="185" y2="80" style="stroke:var(--compare-a)" stroke-width="1.5" stroke-dasharray="4,3"/&gt;&lt;polygon points="185,80 178,86 182,90" style="fill:var(--compare-a)"/&gt;&lt;text x="210" y="105" text-anchor="middle" style="fill:var(--compare-a)" font-size="11"&gt;503 blocked&lt;/text&gt;&lt;line x1="460" y1="80" x2="425" y2="140" style="stroke:var(--compare-b)" stroke-width="1.5"/&gt;&lt;polygon points="425,140 432,131 438,138" style="fill:var(--compare-b)"/&gt;&lt;line x1="495" y1="140" x2="505" y2="80" style="stroke:var(--compare-b)" stroke-width="1.5"/&gt;&lt;polygon points="505,80 498,86 502,90" style="fill:var(--compare-b)"/&gt;&lt;text x="530" y="105" text-anchor="middle" style="fill:var(--compare-b)" font-size="11"&gt;200 OK (stale)&lt;/text&gt;&lt;rect x="60" y="140" width="100" height="50" rx="5" style="fill:var(--compare-a-soft);stroke:var(--compare-a)" stroke-width="1.5"/&gt;&lt;text x="110" y="170" text-anchor="middle" style="fill:var(--content)" font-size="13"&gt;Node A&lt;/text&gt;&lt;rect x="200" y="140" width="100" height="50" rx="5" style="fill:var(--compare-a-soft);stroke:var(--compare-a)" stroke-width="1.5"/&gt;&lt;text x="250" y="170" text-anchor="middle" style="fill:var(--content)" font-size="13"&gt;Node B&lt;/text&gt;&lt;path d="M180 135 L172 150 L188 165 L180 180 L172 195" style="stroke:var(--border);fill:none" stroke-width="2"/&gt;&lt;text x="180" y="122" text-anchor="middle" style="fill:var(--secondary)" font-size="10"&gt;partition&lt;/text&gt;&lt;rect x="380" y="140" width="100" height="50" rx="5" style="fill:var(--compare-b-soft);stroke:var(--compare-b)" stroke-width="1.5"/&gt;&lt;text x="430" y="170" text-anchor="middle" style="fill:var(--content)" font-size="13"&gt;Node A&lt;/text&gt;&lt;rect x="520" y="140" width="100" height="50" rx="5" style="fill:var(--compare-b-soft);stroke:var(--compare-b)" stroke-width="1.5"/&gt;&lt;text x="570" y="170" text-anchor="middle" style="fill:var(--content)" font-size="13"&gt;Node B&lt;/text&gt;&lt;path d="M500 135 L492 150 L508 165 L500 180 L492 195" style="stroke:var(--border);fill:none" stroke-width="2"/&gt;&lt;text x="500" y="122" text-anchor="middle" style="fill:var(--secondary)" font-size="10"&gt;partition&lt;/text&gt;&lt;text x="160" y="235" text-anchor="middle" style="fill:var(--secondary)" font-size="12"&gt;Waits for quorum, rejects request&lt;/text&gt;&lt;text x="160" y="260" text-anchor="middle" style="fill:var(--content)" font-size="12"&gt;Guarantee: no stale reads&lt;/text&gt;&lt;text x="480" y="235" text-anchor="middle" style="fill:var(--secondary)" font-size="12"&gt;Answers immediately from local data&lt;/text&gt;&lt;text x="480" y="260" text-anchor="middle" style="fill:var(--content)" font-size="12"&gt;Guarantee: no downtime&lt;/text&gt;&lt;/svg&gt;
&lt;/div&gt;
&lt;h2 id="comparison-table"&gt;Comparison Table&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Consistency (CP)&lt;/th&gt;
&lt;th&gt;Availability (AP)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Normal operation (no partition)&lt;/td&gt;
&lt;td&gt;Behaves identically to any healthy cluster; all replicas agree&lt;/td&gt;
&lt;td&gt;Behaves identically to any healthy cluster; all replicas agree&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Behavior when a partition occurs&lt;/td&gt;
&lt;td&gt;Nodes that cannot confirm quorum stop responding&lt;/td&gt;
&lt;td&gt;All nodes keep responding regardless of quorum status&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Write handling during partition&lt;/td&gt;
&lt;td&gt;Writes are rejected or queued until enough replicas are reachable&lt;/td&gt;
&lt;td&gt;Writes are accepted locally and replicated once the partition heals&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Read handling during partition&lt;/td&gt;
&lt;td&gt;Reads are blocked or errored if the latest value can&amp;rsquo;t be confirmed&lt;/td&gt;
&lt;td&gt;Reads are served from whatever local replica is reachable, even if stale&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Client-facing failure mode&lt;/td&gt;
&lt;td&gt;Client sees a timeout or explicit error (e.g. 503)&lt;/td&gt;
&lt;td&gt;Client sees a successful response that may contain outdated data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data guarantee provided&lt;/td&gt;
&lt;td&gt;Linearizability - no two nodes ever disagree on current state&lt;/td&gt;
&lt;td&gt;Liveness - the system always answers, correctness may lag&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Recovery after partition heals&lt;/td&gt;
&lt;td&gt;Resumes cleanly; no conflicting writes existed since they were blocked&lt;/td&gt;
&lt;td&gt;Must reconcile diverging writes via vector clocks, LWW, or CRDTs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Representative systems&lt;/td&gt;
&lt;td&gt;HBase, Zookeeper, MongoDB (default majority writes)&lt;/td&gt;
&lt;td&gt;Cassandra, DynamoDB, Riak&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="key-differences"&gt;Key Differences&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The tradeoff only bites during an actual &lt;strong class="kw"&gt;network partition&lt;/strong&gt; - outside of that, both behave the same.&lt;/li&gt;
&lt;li&gt;Consistency requires a &lt;strong class="kw"&gt;quorum&lt;/strong&gt; agreement before answering, which can mean refusing requests.&lt;/li&gt;
&lt;li&gt;Availability guarantees a response but risks returning &lt;strong class="kw"&gt;stale data&lt;/strong&gt; to the client.&lt;/li&gt;
&lt;li&gt;The choice determines whether you need a &lt;strong class="kw"&gt;conflict resolution&lt;/strong&gt; strategy for divergent writes after recovery.&lt;/li&gt;
&lt;li&gt;Many production databases offer &lt;strong class="kw"&gt;tunable consistency&lt;/strong&gt;, letting you pick per-operation rather than a single global stance.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="when-to-use-each"&gt;When to Use Each&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Consistency (CP)&lt;/strong&gt;&lt;/p&gt;</description></item></channel></rss>