<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Aaroophan Varatharajan</title>
    <description>The latest articles on DEV Community by Aaroophan Varatharajan (@aaroophan).</description>
    <link>https://dev.to/aaroophan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3709879%2F2daaf611-2e1b-4cf4-b89a-3afcbeb29250.gif</url>
      <title>DEV Community: Aaroophan Varatharajan</title>
      <link>https://dev.to/aaroophan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aaroophan"/>
    <language>en</language>
    <item>
      <title>The Distributed File System That Wins Depends on What You’re Afraid Of</title>
      <dc:creator>Aaroophan Varatharajan</dc:creator>
      <pubDate>Fri, 09 Oct 2026 07:21:01 +0000</pubDate>
      <link>https://dev.to/aaroophan/the-distributed-file-system-that-wins-depends-on-what-youre-afraid-of-2mf0</link>
      <guid>https://dev.to/aaroophan/the-distributed-file-system-that-wins-depends-on-what-youre-afraid-of-2mf0</guid>
      <description>&lt;h4&gt;
  
  
  Why NFS, AFS, Coda, and GFS Make Different Trade-Offs for Different Failures
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fthwyogc862nri95jb9p9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fthwyogc862nri95jb9p9.png" alt="A technical comparison of Sun NFS, AFS, Coda, and GFS, examining how transparency, caching, scalability, availability, replication, consistency, reliability, and security constraints shaped each distributed file system." width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;A technical comparison of Sun NFS, AFS, Coda, and GFS, examining how transparency, caching, scalability, availability, replication, consistency, reliability, and security constraints shaped each distributed file system.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;At first, this looks like a comparison problem.&lt;/p&gt;

&lt;p&gt;Put &lt;strong&gt;Sun NFS, AFS, Coda, and GFS&lt;/strong&gt; in four columns.&lt;br&gt;&lt;br&gt;
Add &lt;em&gt;transparency, performance, scalability, availability, reliability, security&lt;/em&gt;.&lt;br&gt;&lt;br&gt;
Give each system a score.&lt;/p&gt;

&lt;p&gt;Highest total &lt;strong&gt;&lt;em&gt;✨wins✨&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Perfectly reasonable.&lt;br&gt;&lt;br&gt;
And almost &lt;strong&gt;immediately wrong.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The problem is that these systems are not four contestants solving the same problem with different levels of competence. They entered the room carrying different fears.&lt;/p&gt;

&lt;p&gt;NFS is worried about remote files feeling remote.&lt;br&gt;&lt;br&gt;
AFS is worried about thousands of clients exhausting the servers.&lt;br&gt;&lt;br&gt;
Coda is worried about the network simply disappearing.&lt;br&gt;&lt;br&gt;
GFS assumes machines will fail routinely and asks how to keep massive data processing moving anyway.&lt;/p&gt;

&lt;p&gt;So the useful question is not: &lt;strong&gt;Which distributed file system is best?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It is: &lt;strong&gt;Best under which constraint?&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Transparency Looks Easy Until the Network Starts Having Opinions
&lt;/h3&gt;

&lt;p&gt;The first instinct is simple: if a file is remote, hide that fact.&lt;/p&gt;

&lt;p&gt;Sun NFS takes this intuition seriously. Its protocol is explicitly designed for &lt;strong&gt;transparent remote access&lt;/strong&gt; , with RPC carrying operations across the network and XDR providing a common representation across different machines, operating systems, network architectures, and transport protocols.&lt;/p&gt;

&lt;p&gt;NFS is the diplomat here. It wants everybody to speak file system without caring too much about where the bytes live.&lt;/p&gt;

&lt;p&gt;Its &lt;strong&gt;stateless server&lt;/strong&gt; follows the same philosophy. The server avoids maintaining protocol state about its clients, which makes recovery after failure dramatically simpler: clients can retry operations instead of requiring the server to reconstruct an elaborate shared history.&lt;/p&gt;

&lt;p&gt;That feels beautifully clean.&lt;/p&gt;

&lt;p&gt;Then scale arrives.&lt;/p&gt;

&lt;p&gt;AFS wants the same kind of location-transparent experience, but it expects thousands of workstations. If every read keeps dragging Vice, the trusted server side, back into the conversation, Vice eventually becomes the colleague who is somehow invited to every meeting.&lt;/p&gt;

&lt;p&gt;So AFS gives Venus, the client cache manager, more responsibility.&lt;/p&gt;

&lt;p&gt;Venus caches entire files locally. Reads and writes can then happen against the cached copy, while Vice keeps the responsibilities that actually require server authority. The system preserves a homogeneous, location-transparent namespace while deliberately pushing work toward clients.&lt;/p&gt;

&lt;p&gt;The simple mental model was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;transparency means hiding the network.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AFS reveals the deeper model:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;transparency also depends on deciding&lt;/em&gt; &lt;strong&gt;&lt;em&gt;who must participate in each operation&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That distinction becomes surprisingly expensive later.&lt;/p&gt;




&lt;h3&gt;
  
  
  Mobility Exposes the Assumption AFS Was Still Making
&lt;/h3&gt;

&lt;p&gt;AFS caching solves a lot.&lt;/p&gt;

&lt;p&gt;But it quietly assumes that the server is still reachable when the client actually needs it.&lt;/p&gt;

&lt;p&gt;That assumption feels harmless until a portable workstation leaves the network.&lt;/p&gt;

&lt;p&gt;Now the cached copy is sitting there, perfectly usable, while the system technically has nobody authoritative to talk to.&lt;/p&gt;

&lt;p&gt;The obvious conservative answer is to stop.&lt;/p&gt;

&lt;p&gt;No server, no update.&lt;/p&gt;

&lt;p&gt;Safe. Consistent. Miserable.&lt;/p&gt;

&lt;p&gt;Coda refuses that bargain.&lt;/p&gt;

&lt;p&gt;It inherits much of the AFS model but introduces two complementary mechanisms: &lt;strong&gt;server replication&lt;/strong&gt; and &lt;strong&gt;disconnected operation&lt;/strong&gt;. During disconnected operation, a caching site temporarily assumes the role of a replication site, allowing useful work to continue even when the shared repository is inaccessible. The design explicitly identifies portable workstations as a major use case.&lt;/p&gt;

&lt;p&gt;This is where the architecture gets uncomfortable.&lt;/p&gt;

&lt;p&gt;If a disconnected client can modify data, another client may modify its own copy elsewhere.&lt;/p&gt;

&lt;p&gt;Now both copies are sincere.&lt;/p&gt;

&lt;p&gt;Both have history.&lt;br&gt;&lt;br&gt;
Both think they are right.&lt;/p&gt;

&lt;p&gt;Coda chooses an &lt;strong&gt;optimistic&lt;/strong&gt; strategy because preventing all such divergence would destroy much of the availability it is trying to create. Conflict detection and later reconciliation become the price of continued operation.&lt;/p&gt;

&lt;p&gt;That is the hidden constraint:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mobility is not just remote access from another machine. It is maintaining useful authority when the normal authority is unreachable.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once that requirement appears, “just stay consistent” stops being a complete answer.&lt;/p&gt;




&lt;h3&gt;
  
  
  Performance Stops Being a Number
&lt;/h3&gt;

&lt;p&gt;It is tempting to ask which system is fastest.&lt;/p&gt;

&lt;p&gt;Fast at what?&lt;/p&gt;

&lt;p&gt;GFS makes this question impossible to ignore.&lt;/p&gt;

&lt;p&gt;Its world contains large files, streaming reads, append-heavy writes, commodity machines, many clients, and applications that care more about &lt;strong&gt;high sustained bandwidth&lt;/strong&gt; than low latency.&lt;/p&gt;

&lt;p&gt;Under those assumptions, traditional file-system instincts start looking suspicious.&lt;/p&gt;

&lt;p&gt;GFS uses a single master for metadata and many chunkservers for data. Clients ask the master where chunks live, then communicate directly with chunkservers for the actual data path. The master knows where everything is, but it very deliberately refuses to carry everybody’s luggage.&lt;/p&gt;

&lt;p&gt;Large chunks reduce metadata overhead and repeated master interaction.&lt;/p&gt;

&lt;p&gt;Replication assumes failures will happen.&lt;/p&gt;

&lt;p&gt;Record append reflects the actual workload instead of pretending random overwrite is equally important.&lt;/p&gt;

&lt;p&gt;This is specialization without apology.&lt;/p&gt;

&lt;p&gt;AFS reaches performance from the opposite direction.&lt;/p&gt;

&lt;p&gt;Its enemy is server interaction.&lt;/p&gt;

&lt;p&gt;Whole-file transfer and client caching mean Venus can satisfy much of the workload locally. Callback-based cache validation further reduces the need for clients to repeatedly ask servers whether cached data is still valid. Howard and colleagues identify whole-file transfer and caching as central to AFS’s ability to scale gracefully.&lt;/p&gt;

&lt;p&gt;So GFS says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;make the data path bypass central metadata control.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AFS says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;make repeated data access bypass the server entirely.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;NFS stays more conservative. Its stateless RPC model gives it simplicity and portability, but that same simplicity keeps the client-server relationship comparatively chatty. Even the protocol specification acknowledges that server simplicity can become awkward when clients want richer file-system semantics.&lt;/p&gt;

&lt;p&gt;Nobody is “faster.”&lt;/p&gt;

&lt;p&gt;They are removing different bottlenecks.&lt;/p&gt;




&lt;h3&gt;
  
  
  Scalability Is Usually Someone Becoming Tired
&lt;/h3&gt;

&lt;p&gt;Scale has a habit of revealing whichever component everyone politely assumed would cope.&lt;/p&gt;

&lt;p&gt;In AFS, that component is Vice.&lt;/p&gt;

&lt;p&gt;So Venus takes work away from it.&lt;/p&gt;

&lt;p&gt;In GFS, that component could be the master.&lt;/p&gt;

&lt;p&gt;So clients cache metadata and transfer data directly with chunkservers.&lt;/p&gt;

&lt;p&gt;In NFS, statelessness keeps servers conceptually simple, but repeated remote interactions remain part of the model.&lt;/p&gt;

&lt;p&gt;In Coda, scale is complicated further because availability mechanisms themselves create state: replicas must be tracked, cached versions must be reconciled, and disconnected clients eventually have to return carrying edits made in another reality.&lt;/p&gt;

&lt;p&gt;This is why scalability is not just “add more machines.”&lt;/p&gt;

&lt;p&gt;Adding machines adds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;more metadata,&lt;/li&gt;
&lt;li&gt;more coordination,&lt;/li&gt;
&lt;li&gt;more replicas,&lt;/li&gt;
&lt;li&gt;more failure combinations,&lt;/li&gt;
&lt;li&gt;more opportunities for stale state,&lt;/li&gt;
&lt;li&gt;more people asking the same exhausted authority for answers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The architecture scales when it decides which conversations no longer need to happen.&lt;/p&gt;




&lt;h3&gt;
  
  
  Availability and Reliability Look Similar Until Something Actually Fails
&lt;/h3&gt;

&lt;p&gt;Coda and GFS both care deeply about failure, but their definitions of surviving it are different.&lt;/p&gt;

&lt;p&gt;Coda asks: &lt;strong&gt;Can the user keep working?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Server replication protects against some server and network failures. Disconnected operation covers the much uglier case where no appropriate server can be reached at all.&lt;/p&gt;

&lt;p&gt;GFS asks: &lt;strong&gt;Can the storage service keep functioning while components routinely die?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Its answer includes chunk replication, monitoring, master recovery mechanisms, stale-replica detection, and checksums. Google explicitly designed GFS around the assumption that component failures are normal in clusters built from inexpensive commodity hardware.&lt;/p&gt;

&lt;p&gt;Same word: &lt;strong&gt;availability&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Different anxiety.&lt;/p&gt;

&lt;p&gt;And reliability gets even more specific.&lt;/p&gt;

&lt;p&gt;A replica existing somewhere is not enough.&lt;/p&gt;

&lt;p&gt;What if it missed an update?&lt;br&gt;&lt;br&gt;
What if its disk corrupted the data?&lt;br&gt;&lt;br&gt;
What if a client reads from something that looks alive but belongs to yesterday?&lt;/p&gt;

&lt;p&gt;GFS uses &lt;strong&gt;chunk version numbers&lt;/strong&gt; to identify stale replicas and &lt;strong&gt;checksums&lt;/strong&gt; to detect corrupted data. Replication is therefore not just duplication; replicas must remain trustworthy enough to participate. The verification work around GFS further examines its relaxed and eventual consistency behaviour, showing that consistency here is an explicit system property rather than a vague promise.&lt;/p&gt;

&lt;p&gt;The replica does not get authority merely because it still has a pulse.&lt;/p&gt;

&lt;p&gt;That is a useful distinction.&lt;/p&gt;




&lt;h3&gt;
  
  
  Data Integrity Reveals Why Availability Has a Price
&lt;/h3&gt;

&lt;p&gt;The seductive model of replication is: &lt;em&gt;make three copies and relax.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Distributed systems do not relax.&lt;/p&gt;

&lt;p&gt;GFS coordinates mutations across replicas and uses versioning and &lt;em&gt;checksumming&lt;/em&gt; to identify stale or damaged copies. Its relaxed consistency model is not equivalent to abandoning integrity; instead, the system defines what applications may observe and shapes the interface around workloads that can tolerate those guarantees.&lt;/p&gt;

&lt;p&gt;Coda makes a different trade.&lt;/p&gt;

&lt;p&gt;It wants updates to remain possible across disconnection and partitions.&lt;/p&gt;

&lt;p&gt;That means temporary divergence can be legitimate.&lt;/p&gt;

&lt;p&gt;The system therefore needs mechanisms for detecting conflicts and reconciling them later.&lt;/p&gt;

&lt;p&gt;This can feel like integrity has been weakened.&lt;/p&gt;

&lt;p&gt;A better way to see it is that the definition of integrity changed because the availability requirement changed.&lt;/p&gt;

&lt;p&gt;GFS tries hard to keep replicas participating in one coordinated storage reality.&lt;/p&gt;

&lt;p&gt;Coda sometimes permits two realities to exist temporarily because refusing the second reality would mean refusing the user.&lt;/p&gt;

&lt;p&gt;Neither choice is free.&lt;/p&gt;

&lt;p&gt;That is the part the tidy architecture diagrams usually leave out.&lt;/p&gt;




&lt;h3&gt;
  
  
  Security Is Where Old Trust Assumptions Start Showing
&lt;/h3&gt;

&lt;p&gt;NFS began with portability, transparency, and simple recovery as dominant concerns.&lt;/p&gt;

&lt;p&gt;Its classic design consequently places considerable trust in the surrounding authentication environment. The protocol’s early security model relies on mechanisms such as AUTH_UNIX, while the stateless server must repeatedly reason about permissions without maintaining rich client state.&lt;/p&gt;

&lt;p&gt;That trade becomes increasingly uncomfortable as the environment gets less friendly.&lt;/p&gt;

&lt;p&gt;AFS and Coda operate with a more explicit trusted-server model, and Coda’s design includes authentication and encrypted communication because mobility, caching, and replication make misplaced trust especially expensive.&lt;/p&gt;

&lt;p&gt;GFS is different again. Its foundational design discussion spends enormous attention on failure tolerance, replication, throughput, and consistency, but adversarial multi-tenant security is not one of its central design axes.&lt;/p&gt;

&lt;p&gt;That does not automatically mean “insecure.”&lt;/p&gt;

&lt;p&gt;It means something more important when comparing architectures: &lt;strong&gt;&lt;em&gt;absence of emphasis is not evidence of strength.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A system deserves credit for the problem it actually solves, not for requirements we wish it had discussed.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Leaderboard Was the Wrong Abstraction
&lt;/h3&gt;

&lt;p&gt;Once all these constraints are visible, the rankings become almost embarrassingly contextual.&lt;/p&gt;

&lt;p&gt;Sun NFS is compelling when the problem is &lt;strong&gt;transparent remote access across heterogeneous systems&lt;/strong&gt; and the architecture should stay comparatively simple. Its RPC/XDR model and statelessness follow directly from that goal.&lt;/p&gt;

&lt;p&gt;AFS becomes compelling when the problem is &lt;strong&gt;large shared-workstation populations&lt;/strong&gt; and servers cannot remain involved in every access. Whole-file caching, Venus, Vice, callbacks, and volumes are consequences of scale.&lt;/p&gt;

&lt;p&gt;Coda becomes compelling when &lt;strong&gt;connectivity itself cannot be trusted&lt;/strong&gt;. Server replication and disconnected operation follow from the requirement that users continue working through failures and mobility.&lt;/p&gt;

&lt;p&gt;GFS becomes compelling when the environment is &lt;strong&gt;large, data-intensive, append-heavy, and built from hardware expected to fail&lt;/strong&gt;. Large chunks, a metadata master, direct client-to-chunkserver communication, replication, checksums, and relaxed semantics all follow from that workload.&lt;/p&gt;

&lt;p&gt;That is the deeper pattern.&lt;/p&gt;

&lt;p&gt;Architecture starts looking strange when we stare only at the solution.&lt;/p&gt;

&lt;p&gt;Once we reconstruct the constraint that came before it, the weird parts become almost inevitable.&lt;/p&gt;

&lt;p&gt;The stateless server was not minimalism for vibes.&lt;/p&gt;

&lt;p&gt;Whole-file caching was not an optimization somebody added because caches are fashionable.&lt;/p&gt;

&lt;p&gt;Disconnected operation was not a feature bolted onto AFS.&lt;/p&gt;

&lt;p&gt;GFS did not relax traditional semantics because correctness became unfashionable.&lt;/p&gt;

&lt;p&gt;Each system moved because its original mental model eventually met a requirement it could no longer ignore.&lt;/p&gt;

&lt;p&gt;That is what mature architecture means to The Origami Software Engineer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not a collection of universally correct choices,&lt;br&gt;&lt;br&gt;
but a record of which assumptions survived contact with the constraints.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That’s not failure.&lt;br&gt;&lt;br&gt;
That’s evolution.&lt;/p&gt;




&lt;h3&gt;
  
  
  The “I liked this” Starter Pack:
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Don’t let your fingers get lazy now.
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Like :&lt;/strong&gt; It tells me this was worth writing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A Comment:&lt;/strong&gt; Tell me your thoughts, your favorite snack, or a better title for this blog.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Boost it:&lt;/strong&gt; Especially with that one developer who definitely needs this.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Thanks for being here. It genuinely helps more than you know!&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;— Aaroophan Varatharajan&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Find me elsewhere:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Professional stuff:&lt;/strong&gt; &lt;a href="http://linkedin.com/in/Aaroophan" rel="noopener noreferrer"&gt;linkedin.com/in/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code stuff:&lt;/strong&gt; &lt;a href="http://github.com/Aaroophan" rel="noopener noreferrer"&gt;github.com/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UI stuff:&lt;/strong&gt; &lt;a href="https://aaroophan.dev/Aaroophan" rel="noopener noreferrer"&gt;aaroophan.dev/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Life stuff:&lt;/strong&gt; &lt;a href="http://instagram.com/aaroophan" rel="noopener noreferrer"&gt;instagram.com/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>computerscience</category>
      <category>operatingsystems</category>
      <category>distributedsystems</category>
      <category>technology</category>
    </item>
    <item>
      <title>When "Just Make the Interface Easy" Stops Being Enough: Rethinking Human Computer Interaction</title>
      <dc:creator>Aaroophan Varatharajan</dc:creator>
      <pubDate>Sun, 04 Oct 2026 14:18:39 +0000</pubDate>
      <link>https://dev.to/aaroophan/when-just-make-the-interface-easy-stops-being-enough-rethinking-human-computer-interaction-1bh5</link>
      <guid>https://dev.to/aaroophan/when-just-make-the-interface-easy-stops-being-enough-rethinking-human-computer-interaction-1bh5</guid>
      <description>&lt;h4&gt;
  
  
  Why goals, tasks, translation, ergonomics, interaction styles, error recovery, context, and perceived value shape usable systems
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fubn37na0wzqxn0mo6qno.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fubn37na0wzqxn0mo6qno.png" alt="A technical exploration of Human-Computer Interaction covering Norman’s execution and evaluation gulfs, Abowd and Beale’s interaction framework, ergonomics, WIMP, interaction styles, error recovery, context, fluidity, and user value." width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;A technical exploration of Human-Computer Interaction covering Norman’s execution and evaluation gulfs, Abowd and Beale’s interaction framework, ergonomics, WIMP, interaction styles, error recovery, context, fluidity, and user value.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Interaction looks simple from a distance.&lt;/p&gt;

&lt;p&gt;A user wants something. A system can do something. Put an interface between them, make the controls obvious, and the problem should mostly disappear.&lt;/p&gt;

&lt;p&gt;That intuition is &lt;strong&gt;&lt;em&gt;✨reasonable✨&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It is also where the trouble starts.&lt;/p&gt;

&lt;p&gt;The deeper you follow interaction, the less it looks like a screen-design problem and the more it looks like two very different worlds trying to understand each other without exhausting, confusing, or misleading either side. &lt;em&gt;(&lt;/em&gt;&lt;a href="https://www.hcibook.com/e3/text/chaps/ch3" rel="noopener noreferrer"&gt;&lt;em&gt;HCI Book&lt;/em&gt;&lt;/a&gt;&lt;em&gt;)&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  The Seductive Model: User In, System Out
&lt;/h3&gt;

&lt;p&gt;At first, interaction is simply &lt;strong&gt;communication between user and system&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That gives us a wonderfully clean picture: the user says something, the computer responds, and everybody goes home happy.&lt;/p&gt;

&lt;p&gt;Except communication is not the same as understanding.&lt;/p&gt;

&lt;p&gt;The interaction already carries four kinds of pressure: &lt;strong&gt;interaction models&lt;/strong&gt; must translate between user and system, &lt;strong&gt;ergonomics&lt;/strong&gt; must deal with physical characteristics, &lt;strong&gt;interaction styles&lt;/strong&gt; determine the nature of the dialogue, and &lt;strong&gt;context&lt;/strong&gt; brings social, organizational, and motivational forces into the room.&lt;/p&gt;

&lt;p&gt;So the interface is not merely passing messages.&lt;/p&gt;

&lt;p&gt;It is trying to keep two different realities synchronized.&lt;/p&gt;




&lt;h3&gt;
  
  
  Domain, Goal, and Task: The First Crack
&lt;/h3&gt;

&lt;p&gt;The first useful separation is deceptively small.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;domain&lt;/strong&gt; is the area of work under study.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;goal&lt;/strong&gt; is what the user wants to achieve.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;task&lt;/strong&gt; is how the user goes about achieving it through operations or actions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Suppose the domain is graphic design and the goal is to create a solid red triangle. Selecting the fill tool and clicking the triangle is merely the task.&lt;/p&gt;

&lt;p&gt;That distinction matters because interfaces are very good at making us obsess over tasks.&lt;/p&gt;

&lt;p&gt;Buttons. Menus. Clicks. Steps.&lt;/p&gt;

&lt;p&gt;But the user did not arrive because they wanted to click a fill tool.&lt;/p&gt;

&lt;p&gt;They wanted the triangle.&lt;/p&gt;

&lt;p&gt;Once that becomes clear, the interface stops being the purpose and starts becoming what it always was: the negotiator.&lt;/p&gt;




&lt;h3&gt;
  
  
  Norman Gives the Negotiator a Workflow
&lt;/h3&gt;

&lt;p&gt;Donald Norman makes the interaction much more precise.&lt;/p&gt;

&lt;p&gt;The user establishes a goal, formulates an intention, specifies actions at the interface, executes them, perceives the resulting system state, interprets that state, and evaluates it against the original goal.&lt;/p&gt;

&lt;p&gt;This creates the &lt;strong&gt;execution/evaluation loop&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
And it feels reassuringly orderly.&lt;/p&gt;

&lt;p&gt;The user knows what they want. Their intention becomes an action. The system responds. The user observes the response and decides whether the goal was achieved.&lt;/p&gt;

&lt;p&gt;This should work.&lt;br&gt;&lt;br&gt;
It does work.&lt;br&gt;&lt;br&gt;
Except when the user and system disagree about what any of those steps mean.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Gulfs: Where a Correct System Can Still Feel Wrong
&lt;/h3&gt;

&lt;p&gt;Now the hidden constraint becomes visible.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Gulf of Execution&lt;/strong&gt; appears when the actions the user formulates are not the actions the system allows.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Gulf of Evaluation&lt;/strong&gt; appears when the state the user expects is not how the system actually presents that state.&lt;/p&gt;

&lt;p&gt;Nothing necessarily crashed.&lt;br&gt;&lt;br&gt;
Nothing necessarily malfunctioned.&lt;/p&gt;

&lt;p&gt;The system may be completely correct internally while feeling almost hostile externally.&lt;/p&gt;

&lt;p&gt;Then human error divides again.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;slip&lt;/strong&gt; happens when the user understands the system and the goal, formulates the correct action, but performs the wrong action.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;mistake&lt;/strong&gt; can begin earlier: the user may not even have the correct goal.&lt;/p&gt;

&lt;p&gt;That distinction quietly changes responsibility.&lt;/p&gt;

&lt;p&gt;A slip suggests &lt;strong&gt;better interface design&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A mistake suggests &lt;strong&gt;better understanding of the system&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;"User error" was never one thing.&lt;/p&gt;




&lt;h3&gt;
  
  
  Abowd and Beale Reveal the Translation Problem
&lt;/h3&gt;

&lt;p&gt;The next model makes the tension harder to ignore.&lt;/p&gt;

&lt;p&gt;Abowd and Beale introduce four participants: &lt;strong&gt;User, Input, System, Output.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each has its own language.&lt;/p&gt;

&lt;p&gt;The user’s intentions must become actions at the interface. Those actions must become alterations of system state. That state must become output. The output must then become something the user can interpret.&lt;/p&gt;

&lt;p&gt;Interaction is therefore &lt;strong&gt;translation between languages&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And the uncomfortable conclusion follows naturally:&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Problems in interaction = Problems in translation.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The system is not necessarily broken.&lt;/p&gt;

&lt;p&gt;The translation chain is.&lt;/p&gt;

&lt;p&gt;That is why apparently small interface decisions can create surprisingly large misunderstandings. &lt;em&gt;(&lt;/em&gt;&lt;a href="https://www.hcibook.com/e3-docs/slides/notes-pdf/e3-chap-03-6up.pdf" rel="noopener noreferrer"&gt;&lt;em&gt;HCI Book&lt;/em&gt;&lt;/a&gt;&lt;em&gt;)&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Ergonomics Reminds Software That Humans Have Bodies
&lt;/h3&gt;

&lt;p&gt;It is tempting to keep solving this as a language problem.&lt;/p&gt;

&lt;p&gt;Then ergonomics walks in carrying chairs, lighting, noise, physical position, button placement, colour, temperature, and human fatigue.&lt;/p&gt;

&lt;p&gt;Suddenly the abstraction has a body.&lt;/p&gt;

&lt;p&gt;Controls may need grouping according to function or frequency of use. Seating may need to accommodate different users. Colour choices need awareness of colour-blindness. The physical environment changes what is usable.&lt;/p&gt;

&lt;p&gt;The difference between office and industrial interfaces makes this wonderfully obvious.&lt;/p&gt;

&lt;p&gt;Office data may be textual, slow-changing, and used in a clean environment.&lt;/p&gt;

&lt;p&gt;Industrial data may be numeric, fast-changing, and surrounded by dirt.&lt;/p&gt;

&lt;p&gt;Then comes the perfect little reality check: &lt;strong&gt;The oil soaked mouse.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Nothing is technically wrong with the mouse.&lt;/p&gt;

&lt;p&gt;The context simply made our &lt;em&gt;"obvious"&lt;/em&gt; solution cursed.&lt;/p&gt;




&lt;h3&gt;
  
  
  Glass Interfaces Solve One Problem and Introduce Another
&lt;/h3&gt;

&lt;p&gt;Replacing traditional dials and knobs with screens and keypads feels like progress.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;glass interface&lt;/strong&gt; can be cheaper, more flexible, provide precise values, and show multiple representations of the same information.&lt;/p&gt;

&lt;p&gt;Very seductive.&lt;/p&gt;

&lt;p&gt;But physical controls knew where they lived.&lt;/p&gt;

&lt;p&gt;The glass interface may lose physical location and context while becoming more complex.&lt;/p&gt;

&lt;p&gt;So the solution is not always replacement.&lt;/p&gt;

&lt;p&gt;Sometimes the design needs both.&lt;/p&gt;

&lt;p&gt;That becomes even more important with &lt;strong&gt;indirect manipulation&lt;/strong&gt;. In an office interface, the user often manipulates an artificial world directly. In an industrial interface, the user may manipulate the real world &lt;em&gt;through&lt;/em&gt; the interface.&lt;/p&gt;

&lt;p&gt;Now feedback and delays matter.&lt;/p&gt;

&lt;p&gt;The interface may say the command was accepted while the physical process is still catching up.&lt;/p&gt;

&lt;p&gt;The screen and reality are no longer the same clock.&lt;/p&gt;




&lt;h3&gt;
  
  
  Interaction Styles Are Different Kinds of Conversation
&lt;/h3&gt;

&lt;p&gt;Once interaction is understood as dialogue, the next question becomes obvious: &lt;strong&gt;What kind of conversation should this be?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;command line interface&lt;/strong&gt; gives direct access and works beautifully for repetitive tasks and expert users, but asks the user to remember its vocabulary.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Menus&lt;/strong&gt; make options visible and replace some recall with recognition.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Natural language&lt;/strong&gt; feels wonderfully familiar until vagueness and ambiguity arrive. The practical retreat is often to understand a subset or pick out key words.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Question/answer interfaces&lt;/strong&gt; guide novices but restrict functionality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Query languages&lt;/strong&gt; such as SQL offer power, but demand understanding of structure and syntax.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Form-fills&lt;/strong&gt; borrow familiarity from paper forms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Spreadsheets&lt;/strong&gt; extend that idea while maintaining consistency between values and formulas.&lt;/p&gt;

&lt;p&gt;None of these styles is simply "better."&lt;/p&gt;

&lt;p&gt;Each changes who carries the cognitive load.&lt;/p&gt;




&lt;h3&gt;
  
  
  WIMP Makes Interaction Easy, Then Becomes an Ecosystem
&lt;/h3&gt;

&lt;p&gt;Then comes &lt;strong&gt;WIMP&lt;/strong&gt; : &lt;strong&gt;Windows, Icons, Menus, Pointers.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Point-and-click interaction reduces typing. Windows divide the display into independent areas. Icons represent objects or actions. Pointers let the user select things. Menus expose available operations.&lt;/p&gt;

&lt;p&gt;It feels almost effortless.&lt;/p&gt;

&lt;p&gt;Then the family expands.&lt;/p&gt;

&lt;p&gt;Buttons invoke actions. Radio buttons represent mutually exclusive choices. Check boxes support non-exclusive choices. Toolbars provide fast access to common actions. Palettes keep actions available when menus disappear. Dialogue boxes request information and then, ideally, go away.&lt;/p&gt;

&lt;p&gt;Each component exists because another interaction created friction.&lt;/p&gt;

&lt;p&gt;Menus save recall but consume screen space, so pop-up menus appear only when needed.&lt;/p&gt;

&lt;p&gt;Toolbars provide speed but can become rows of mysterious icons whispering, &lt;em&gt;"…but what do they do?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Palettes exist because sometimes the menu is not there when you need it.&lt;/p&gt;

&lt;p&gt;The interface keeps evolving because every simplification has a boundary. &lt;em&gt;(&lt;/em&gt;&lt;a href="https://www.hcibook.com/hcibook/toc.html" rel="noopener noreferrer"&gt;&lt;em&gt;HCI Book&lt;/em&gt;&lt;/a&gt;&lt;em&gt;)&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  "Look" Was Never Enough
&lt;/h3&gt;

&lt;p&gt;This is where &lt;strong&gt;interactivity&lt;/strong&gt; starts to matter.&lt;/p&gt;

&lt;p&gt;It is easy to focus on look.&lt;/p&gt;

&lt;p&gt;The harder question is feel.&lt;/p&gt;

&lt;p&gt;Two WIMP systems may contain windows, icons, menus, pointers, and buttons while behaving differently.&lt;/p&gt;

&lt;p&gt;Hence: &lt;strong&gt;Appearance + Behaviour = Look and Feel&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Speech-driven interfaces make the same lesson obvious in another form.&lt;/p&gt;

&lt;p&gt;Speech recognition may misunderstand the user. A robust dialogue can therefore reflect its interpretation back:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"You want a ticket from New York to Boston?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now the user can correct it.&lt;/p&gt;

&lt;p&gt;The system is not pretending to be perfect.&lt;/p&gt;

&lt;p&gt;It is making misunderstanding repairable.&lt;/p&gt;




&lt;h3&gt;
  
  
  Initiative, Error, and the Right to Recover
&lt;/h3&gt;

&lt;p&gt;Another hidden question appears: &lt;strong&gt;Who has the initiative?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Traditional question/answer interaction often gives it to the computer.&lt;/p&gt;

&lt;p&gt;WIMP usually gives it to the user.&lt;/p&gt;

&lt;p&gt;Then a &lt;strong&gt;modal dialog box&lt;/strong&gt; appears and refuses to leave until the user responds.&lt;/p&gt;

&lt;p&gt;Sometimes that is appropriate for errors or essential steps.&lt;/p&gt;

&lt;p&gt;Use it everywhere and the interface becomes the colleague who keeps blocking the doorway to ask one more &lt;em&gt;"quick question"&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Errors themselves cannot always be avoided either.&lt;/p&gt;

&lt;p&gt;So the design shifts from impossible perfection to &lt;strong&gt;error and repair&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Make the error easy to detect.&lt;/p&gt;

&lt;p&gt;Then make repair possible.&lt;/p&gt;

&lt;p&gt;That is a much more humane model of interaction because it accepts something the earlier mental model tried to hide:&lt;/p&gt;

&lt;p&gt;Humans and systems will occasionally misunderstand each other.&lt;/p&gt;

&lt;p&gt;Good interaction survives the misunderstanding.&lt;/p&gt;




&lt;h3&gt;
  
  
  Context Changes the Same Interface Without Touching the Code
&lt;/h3&gt;

&lt;p&gt;By now it is tempting to believe we finally have the whole picture.&lt;/p&gt;

&lt;p&gt;Then &lt;strong&gt;context&lt;/strong&gt; widens it again.&lt;/p&gt;

&lt;p&gt;Interaction is affected by other people, competition, desire to impress, fear of failure, allegiance, ambition, self-satisfaction, and organizational pressures.&lt;/p&gt;

&lt;p&gt;An inadequate system can create frustration and reduce motivation.&lt;/p&gt;

&lt;p&gt;The software may not have changed at all.&lt;/p&gt;

&lt;p&gt;The interaction has.&lt;/p&gt;

&lt;p&gt;That is the uncomfortable part: usability does not live entirely inside the interface.&lt;/p&gt;

&lt;p&gt;The surrounding social and organizational environment can change how people behave with exactly the same system. &lt;em&gt;(&lt;/em&gt;&lt;a href="https://hcibook.com/e3/text/exercises/ex3.3" rel="noopener noreferrer"&gt;&lt;em&gt;HCI Book&lt;/em&gt;&lt;/a&gt;&lt;em&gt;)&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  "Can Use" Becomes "Want to Use"
&lt;/h3&gt;

&lt;p&gt;For work systems, making interaction possible may sometimes be enough.&lt;/p&gt;

&lt;p&gt;For home, entertainment, and shopping, another condition appears.&lt;/p&gt;

&lt;p&gt;People must &lt;strong&gt;want to use it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now the conversation shifts toward &lt;strong&gt;experience, engagement and fun&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Experience can sit between anxiety and boredom.&lt;/p&gt;

&lt;p&gt;Education may involve things a learner can just accomplish with help.&lt;/p&gt;

&lt;p&gt;The interaction is no longer judged only by whether the task can technically be completed.&lt;/p&gt;

&lt;p&gt;The user’s willingness to remain in the interaction becomes part of the design.&lt;/p&gt;




&lt;h3&gt;
  
  
  Physical Design Turns Certainty Into Trade-offs
&lt;/h3&gt;

&lt;p&gt;Then physical design brings constraints that refuse to cooperate.&lt;/p&gt;

&lt;p&gt;Ergonomic constraints say controls need sufficient size.&lt;/p&gt;

&lt;p&gt;Physical constraints say there may not be enough room.&lt;/p&gt;

&lt;p&gt;Safety constraints may favour one position for adults and another for children.&lt;/p&gt;

&lt;p&gt;Aesthetic constraints want the design to look good.&lt;/p&gt;

&lt;p&gt;Economic constraints quietly ask who is paying for all this.&lt;/p&gt;

&lt;p&gt;There is no magic arrangement where every constraint wins.&lt;/p&gt;

&lt;p&gt;There are &lt;strong&gt;design trade-offs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The gas-cooker example makes this painfully clear: front controls may be safer and easier for adults, while rear controls may be safer for children.&lt;/p&gt;

&lt;p&gt;The problem is not finding the &lt;em&gt;"correct"&lt;/em&gt; position.&lt;br&gt;&lt;br&gt;
The problem is understanding which constraint each position satisfies.&lt;/p&gt;




&lt;h3&gt;
  
  
  Fluidity Is When Physical and Logical State Stop Arguing
&lt;/h3&gt;

&lt;p&gt;That leads naturally to &lt;strong&gt;fluidity&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Do external physical aspects reflect logical effect?&lt;/p&gt;

&lt;p&gt;Does the physical state reveal the logical state?&lt;/p&gt;

&lt;p&gt;Do inverse actions create inverse effects?&lt;/p&gt;

&lt;p&gt;Spring-back controls show why this matters.&lt;/p&gt;

&lt;p&gt;They can support large selection sets efficiently, but they introduce &lt;strong&gt;hidden state&lt;/strong&gt; because the control returns physically while the logical state may remain elsewhere.&lt;/p&gt;

&lt;p&gt;The control looks innocent.&lt;/p&gt;

&lt;p&gt;The state has moved on.&lt;/p&gt;

&lt;p&gt;Now the user has to remember what the control no longer reveals.&lt;/p&gt;

&lt;p&gt;A compliant interaction avoids that kind of drift where possible: state remains evident, and controls can reflect what both user and machine are doing.&lt;/p&gt;




&lt;h3&gt;
  
  
  Value Was the Constraint Hiding Under Everything
&lt;/h3&gt;

&lt;p&gt;After all the models, controls, translations, ergonomics, styles, errors, and trade-offs, the final condition is almost embarrassingly simple.&lt;/p&gt;

&lt;p&gt;People use something &lt;strong&gt;only if it has perceived value and that value exceeds cost&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Value might be getting work done, having fun, or doing something good for others.&lt;/p&gt;

&lt;p&gt;Cost might be money, download time, or learning effort.&lt;/p&gt;

&lt;p&gt;Then &lt;strong&gt;discounted future&lt;/strong&gt; makes the equation nastier.&lt;/p&gt;

&lt;p&gt;People heavily discount future value and future cost.&lt;/p&gt;

&lt;p&gt;That helps explain resistance to learning: The learning effort is happening now, while the promised benefit lives somewhere in the future wearing a tiny "trust me" badge.&lt;/p&gt;

&lt;p&gt;Hence the design pressure toward: &lt;strong&gt;Low barriers and high perceived present value.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Organizations face the same issue through &lt;strong&gt;coercion, enculturation, and emergence&lt;/strong&gt; : force behaviour, build shared values, or design the process so individual value becomes organizational value.&lt;/p&gt;

&lt;p&gt;Different mechanisms.&lt;br&gt;&lt;br&gt;
Same underlying problem.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Interface Was Never the Real Goal
&lt;/h3&gt;

&lt;p&gt;The general lesson sounds almost too simple after everything required to reach it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;If you want someone to do something,&lt;/em&gt; &lt;strong&gt;&lt;em&gt;make it easy for them&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;.&lt;br&gt;&lt;br&gt;
And&lt;/em&gt; &lt;strong&gt;&lt;em&gt;understand their values&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;"Easy" now means much more than fewer clicks.&lt;/p&gt;

&lt;p&gt;The goal must survive translation into action.&lt;br&gt;&lt;br&gt;
The available actions must fit the user’s intention.&lt;br&gt;&lt;br&gt;
The system state must be perceivable and interpretable.&lt;br&gt;&lt;br&gt;
Errors must be repairable.&lt;br&gt;&lt;br&gt;
Physical controls must fit their environment.&lt;br&gt;&lt;br&gt;
Interaction styles must fit their users.&lt;br&gt;&lt;br&gt;
Constraints must be traded consciously.&lt;br&gt;&lt;br&gt;
The eventual value must justify the cost of learning and acting.&lt;br&gt;&lt;br&gt;
The Origami Software Engineer must keep all of this aligned.&lt;/p&gt;

&lt;p&gt;That is why interaction design keeps growing beyond the interface.&lt;/p&gt;

&lt;p&gt;Every time the model becomes more realistic, another hidden assumption becomes visible.&lt;/p&gt;

&lt;p&gt;That’s not failure.&lt;br&gt;&lt;br&gt;
That’s evolution.&lt;/p&gt;




&lt;h3&gt;
  
  
  The "I liked this" Starter Pack:
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Don’t let your fingers get lazy now.
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Like :&lt;/strong&gt; It tells me this was worth writing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A Comment:&lt;/strong&gt; Tell me your thoughts, your favorite snack, or a better title for this blog.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Boost it:&lt;/strong&gt; Especially with that one developer who definitely needs this.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Thanks for being here. It genuinely helps more than you know!&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;— Aaroophan Varatharajan&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Find me elsewhere:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Professional stuff:&lt;/strong&gt; &lt;a href="http://linkedin.com/in/Aaroophan" rel="noopener noreferrer"&gt;linkedin.com/in/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code stuff:&lt;/strong&gt; &lt;a href="http://github.com/Aaroophan" rel="noopener noreferrer"&gt;github.com/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UI stuff:&lt;/strong&gt; &lt;a href="https://aaroophan.dev/Aaroophan" rel="noopener noreferrer"&gt;aaroophan.dev/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Life stuff:&lt;/strong&gt; &lt;a href="http://instagram.com/aaroophan" rel="noopener noreferrer"&gt;instagram.com/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>computerscience</category>
      <category>ux</category>
      <category>softwareengineering</category>
      <category>userexperience</category>
    </item>
    <item>
      <title>“Send” Is Not One Operation: Rethinking Distributed Computing #5</title>
      <dc:creator>Aaroophan Varatharajan</dc:creator>
      <pubDate>Sat, 26 Sep 2026 13:24:58 +0000</pubDate>
      <link>https://dev.to/aaroophan/send-is-not-one-operation-rethinking-distributed-computing-5-1gc7</link>
      <guid>https://dev.to/aaroophan/send-is-not-one-operation-rethinking-distributed-computing-5-1gc7</guid>
      <description>&lt;h4&gt;
  
  
  &lt;em&gt;The dangerous part of&lt;/em&gt; &lt;code&gt;send(message)&lt;/code&gt; &lt;em&gt;is how much meaning we quietly pack into the word&amp;nbsp;“send.”&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl8sv2abzrosrhajjjaom.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl8sv2abzrosrhajjjaom.png" alt="Why send(message) is not one operation. Explore transient vs. persistent communication, synchronous vs. asynchronous messaging, queues, publish/subscribe, message brokers, MPI, collective communication, delivery guarantees, ordering, and the contracts hidden behind distributed communication." width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"Why send(message) is not one operation. Explore transient vs. persistent communication, synchronous vs. asynchronous messaging, queues, publish/subscribe, message brokers, MPI, collective communication, delivery guarantees, ordering, and the contracts hidden behind distributed communication."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Two processes need to communicate.&lt;/p&gt;

&lt;p&gt;One has some data.&lt;br&gt;&lt;br&gt;
The other needs it.&lt;/p&gt;

&lt;p&gt;So we do the obvious thing: &lt;code&gt;send(message)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;There.&lt;/em&gt; &lt;strong&gt;&lt;em&gt;✨Sent✨&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Except distributed systems have a habit of taking perfectly ordinary verbs and asking uncomfortable follow-up questions.&lt;/p&gt;

&lt;p&gt;Where is the message now?&lt;br&gt;&lt;br&gt;
Is it still in the sender’s memory?&lt;br&gt;&lt;br&gt;
Has the operating system accepted it?&lt;br&gt;&lt;br&gt;
Has it crossed the network?&lt;br&gt;&lt;br&gt;
Has the receiving machine stored it?&lt;br&gt;&lt;br&gt;
Has the receiving process seen it?&lt;br&gt;&lt;br&gt;
Has the receiving process processed it?&lt;br&gt;&lt;br&gt;
Can the sender disappear now?&lt;br&gt;&lt;br&gt;
Can the receiver be offline?&lt;br&gt;&lt;br&gt;
And when &lt;code&gt;send()&lt;/code&gt; returns, &lt;strong&gt;which one of those things are we actually claiming happened?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That is the trap.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;“Send” sounds like one operation because human communication lets us get away with vague semantics.&lt;/p&gt;

&lt;p&gt;Distributed communication cannot.&lt;/p&gt;

&lt;p&gt;The system eventually has to define exactly what survives, who waits, where the message lives, and what counts as success.&lt;/p&gt;

&lt;p&gt;And once we start answering those questions, &lt;code&gt;send(message)&lt;/code&gt; turns out to be several very different contracts wearing the same verb.&lt;/p&gt;




&lt;h3&gt;
  
  
  First Question: How Long Should the Message Stay&amp;nbsp;Alive?
&lt;/h3&gt;

&lt;p&gt;Suppose Alice sends a message to Bob.&lt;/p&gt;

&lt;p&gt;Bob is not running.&lt;/p&gt;

&lt;p&gt;What should happen?&lt;/p&gt;

&lt;p&gt;One perfectly reasonable answer is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Then the message cannot be delivered.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is &lt;strong&gt;transient communication&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The communication system keeps the message only while the communicating applications and supporting communication infrastructure are active enough to handle it. If the receiver needs to be present when the message arrives, absence matters.&lt;/p&gt;

&lt;p&gt;Transport-level communication often has this flavour.&lt;/p&gt;

&lt;p&gt;The sender and receiver are participating in the same live conversation.&lt;/p&gt;

&lt;p&gt;That works beautifully when both sides are expected to exist at roughly the same time.&lt;/p&gt;

&lt;p&gt;Then consider email.&lt;/p&gt;

&lt;p&gt;Alice sends a message at 2 p.m.&lt;br&gt;&lt;br&gt;
Bob opens his mail at 9 p.m.&lt;/p&gt;

&lt;p&gt;Nobody finds this surprising.&lt;/p&gt;

&lt;p&gt;We quietly introduced a completely different contract.&lt;/p&gt;

&lt;p&gt;The communication system takes responsibility for preserving the message until Bob can receive it.&lt;/p&gt;

&lt;p&gt;That is &lt;strong&gt;persistent communication&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The sender does not have to remain running after submitting the message.&lt;br&gt;&lt;br&gt;
The receiver does not need to be running when the sender submits it.&lt;/p&gt;

&lt;p&gt;Somewhere between them, the infrastructure remembers.&lt;/p&gt;

&lt;p&gt;The distinction is not really about messaging syntax.&lt;/p&gt;

&lt;p&gt;It is about &lt;strong&gt;who owns the message while the receiver is absent&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Transient communication says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I will carry this while the conversation exists.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Persistent communication says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Give it to me. I will keep it until the other side can deal with it.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Same word.&lt;br&gt;&lt;br&gt;
Very different promise.&lt;/p&gt;




&lt;h3&gt;
  
  
  Second Question: When Is the Sender Allowed to Continue?
&lt;/h3&gt;

&lt;p&gt;Now suppose Bob &lt;em&gt;is&lt;/em&gt; available.&lt;/p&gt;

&lt;p&gt;Alice sends the message.&lt;/p&gt;

&lt;p&gt;Can Alice immediately continue doing other work?&lt;/p&gt;

&lt;p&gt;That gives us another axis entirely.&lt;/p&gt;

&lt;p&gt;With &lt;strong&gt;asynchronous communication&lt;/strong&gt;, the sender submits the message for transmission and continues.&lt;/p&gt;

&lt;p&gt;The message may still be sitting in a local buffer.&lt;/p&gt;

&lt;p&gt;It may be inside an intermediate communication server.&lt;br&gt;&lt;br&gt;
It may not be anywhere near Bob yet.&lt;/p&gt;

&lt;p&gt;Alice has handed off responsibility and moved on.&lt;/p&gt;

&lt;p&gt;With &lt;strong&gt;synchronous communication&lt;/strong&gt;, Alice waits.&lt;/p&gt;

&lt;p&gt;But even this turns out not to have one obvious meaning.&lt;/p&gt;

&lt;p&gt;What exactly is she waiting for?&lt;/p&gt;

&lt;p&gt;Perhaps she waits until the message reaches a buffer on Bob’s machine.&lt;/p&gt;

&lt;p&gt;That is &lt;strong&gt;receipt-based synchronization&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Or perhaps she waits until the message is actually delivered to Bob’s application.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;That is stronger.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Or perhaps she waits until Bob processes the message and sends something back.&lt;/p&gt;

&lt;p&gt;That is &lt;strong&gt;response-based synchronization&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now the innocent verb &lt;code&gt;send&lt;/code&gt; has become a ladder of guarantees.&lt;/p&gt;

&lt;p&gt;Submitted.&lt;br&gt;&lt;br&gt;
Buffered.&lt;br&gt;&lt;br&gt;
Received by host.&lt;br&gt;&lt;br&gt;
Delivered to application.&lt;br&gt;&lt;br&gt;
Processed.&lt;br&gt;&lt;br&gt;
Responded to.&lt;/p&gt;

&lt;p&gt;Each level tells Alice more.&lt;br&gt;&lt;br&gt;
Each level can also make Alice wait longer.&lt;/p&gt;

&lt;p&gt;And this is the part that is easy to miss:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Persistent vs. Transient&lt;/strong&gt; and &lt;strong&gt;Synchronous vs. Asynchronous&lt;/strong&gt; are not the same question.&lt;/p&gt;

&lt;p&gt;One asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;How long can the communication system preserve the message?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The other asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;How long must the sender wait?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Those two choices can be combined.&lt;/p&gt;

&lt;p&gt;A message can be persistent and asynchronous, like the intuitive model of email.&lt;/p&gt;

&lt;p&gt;Persistent and synchronous communication can wait until durable storage exists at the receiving side without requiring the receiving application itself to be running.&lt;/p&gt;

&lt;p&gt;Transient asynchronous communication can let the sender continue immediately while relying only on temporary buffering.&lt;/p&gt;

&lt;p&gt;Transient synchronous communication can wait for receipt, delivery, or even a response while still assuming the live communication context exists.&lt;/p&gt;

&lt;p&gt;We did not make messaging complicated for fun.&lt;br&gt;&lt;br&gt;
We discovered that &lt;em&gt;“sent”&lt;/em&gt; was hiding multiple independent decisions.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Queue Says, “I’ll Hold&amp;nbsp;It”
&lt;/h3&gt;

&lt;p&gt;Once persistence matters, a useful character enters the story.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;message queue&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of requiring Alice and Bob to meet directly, Alice puts a message into a queue.&lt;/p&gt;

&lt;p&gt;Bob retrieves it later.&lt;/p&gt;

&lt;p&gt;The queue sits between them like a patient intermediary saying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;You two do not actually need to coordinate your calendars.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Applications communicate by placing messages into queues and removing them when ready.&lt;/p&gt;

&lt;p&gt;That produces &lt;strong&gt;loosely coupled communication&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Alice does not necessarily need Bob to be active.&lt;br&gt;&lt;br&gt;
Bob does not necessarily need Alice to still exist.&lt;/p&gt;

&lt;p&gt;Neither side has to wait for the other to reach the exact same point in its lifecycle.&lt;/p&gt;

&lt;p&gt;AWS describes SQS in essentially this role: a durable queue that helps decouple distributed components, allowing producers and consumers to operate without requiring them to be concurrently available.&lt;/p&gt;

&lt;p&gt;That is a profound change in ownership.&lt;/p&gt;

&lt;p&gt;In direct transient communication, Alice and Bob are responsible for meeting each other.&lt;/p&gt;

&lt;p&gt;With persistent messaging, the queue accepts part of that responsibility.&lt;/p&gt;

&lt;p&gt;And because it does, the interface itself changes.&lt;/p&gt;

&lt;p&gt;Instead of one vague &lt;code&gt;send&lt;/code&gt;, queue systems expose operations with much clearer meanings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Put&lt;/strong&gt; appends a message.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Get&lt;/strong&gt; waits until a message exists and removes it.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Poll&lt;/strong&gt; checks without waiting.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Notify&lt;/strong&gt; arranges for a handler to be called when a message becomes available.&lt;/p&gt;

&lt;p&gt;The verbs are more precise because the state of the communication is now explicit.&lt;/p&gt;

&lt;p&gt;The message can exist independently of both applications.&lt;/p&gt;




&lt;h3&gt;
  
  
  Queued Does Not Mean Processed
&lt;/h3&gt;

&lt;p&gt;This creates another seductive assumption.&lt;/p&gt;

&lt;p&gt;If Alice successfully puts the message in the queue, perhaps the job is done.&lt;/p&gt;

&lt;p&gt;Not quite.&lt;/p&gt;

&lt;p&gt;What has actually happened?&lt;/p&gt;

&lt;p&gt;The queue accepted responsibility for the message.&lt;/p&gt;

&lt;p&gt;That is valuable.&lt;/p&gt;

&lt;p&gt;It is not the same thing as Bob processing it.&lt;/p&gt;

&lt;p&gt;Bob may not read the queue immediately.&lt;br&gt;&lt;br&gt;
Bob may fail while processing.&lt;/p&gt;

&lt;p&gt;The message may remain waiting.&lt;/p&gt;

&lt;p&gt;A queue can therefore give the sender confidence about &lt;strong&gt;handoff&lt;/strong&gt; without automatically giving confidence about &lt;strong&gt;application completion&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Modern queue systems make this distinction visible. In Amazon SQS, for example, a message can remain stored until a consumer retrieves it; while being processed it can remain hidden for a visibility period, and the consumer deletes it only after successful processing. (&lt;a href="https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.html" rel="noopener noreferrer"&gt;docs.aws.amazon.com&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;That lifecycle exists because these are different events:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The communication system has the message.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The application has completed the work represented by the message.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Again, “sent” was too vague.&lt;/p&gt;

&lt;p&gt;The queue forces us to become honest.&lt;/p&gt;




&lt;h3&gt;
  
  
  Then We Stop Naming the&amp;nbsp;Receiver
&lt;/h3&gt;

&lt;p&gt;Queues decouple sender and receiver in &lt;strong&gt;time&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But Alice may still be sending work toward a particular destination.&lt;/p&gt;

&lt;p&gt;What if she does not know who should receive the information?&lt;/p&gt;

&lt;p&gt;Suppose Alice produces an event:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Order 781 was completed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Several systems may care.&lt;/p&gt;

&lt;p&gt;Billing.&lt;br&gt;&lt;br&gt;
Analytics.&lt;br&gt;&lt;br&gt;
Inventory.&lt;br&gt;&lt;br&gt;
Notifications.&lt;/p&gt;

&lt;p&gt;Perhaps systems we have not even built yet.&lt;/p&gt;

&lt;p&gt;Making Alice explicitly call every consumer creates another dependency problem.&lt;/p&gt;

&lt;p&gt;So we change the communication model again.&lt;/p&gt;

&lt;p&gt;Alice becomes a &lt;strong&gt;publisher&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;She publishes the event, usually to a &lt;strong&gt;topic&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Interested systems become &lt;strong&gt;subscribers&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The publish/subscribe infrastructure determines who should receive which messages.&lt;/p&gt;

&lt;p&gt;Now communication has been decoupled in several dimensions.&lt;/p&gt;

&lt;p&gt;The publisher and subscriber do not necessarily need to be online at the same time.&lt;/p&gt;

&lt;p&gt;They do not necessarily need to know each other’s addresses.&lt;/p&gt;

&lt;p&gt;And the publisher does not need to stop and wait for every subscriber to finish processing the event.&lt;/p&gt;

&lt;p&gt;AWS’s SNS documentation describes this fan-out model directly: publishers send through a topic, which distributes messages to multiple subscribers; combined with queues, messages can also be persisted for later asynchronous processing.&lt;/p&gt;

&lt;p&gt;The publisher says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This happened.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Bob, please execute method X.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is a different relationship entirely.&lt;/p&gt;

&lt;p&gt;The components are becoming less aware of one another.&lt;/p&gt;

&lt;p&gt;Which is excellent for loose coupling.&lt;/p&gt;

&lt;p&gt;It also means the communication infrastructure is taking on more responsibility.&lt;/p&gt;




&lt;h3&gt;
  
  
  Somebody Still Has to Understand the&amp;nbsp;Message
&lt;/h3&gt;

&lt;p&gt;There is another hidden assumption.&lt;/p&gt;

&lt;p&gt;Alice publishes:&lt;/p&gt;

&lt;p&gt;{ customer: 17, total: 4500 }&lt;/p&gt;

&lt;p&gt;Bob expects:&lt;/p&gt;

&lt;p&gt;{ customerId: 17, amount: 4500 }&lt;/p&gt;

&lt;p&gt;The message arrived perfectly.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Congratulations.&lt;/em&gt; &lt;strong&gt;Nobody understands each other.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Transport success does not imply semantic compatibility.&lt;/p&gt;

&lt;p&gt;Applications still need &lt;strong&gt;agreed message formats, schemas, commands, and meanings.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One option is standardization.&lt;/p&gt;

&lt;p&gt;Make every participant agree on the same format.&lt;/p&gt;

&lt;p&gt;That works until integrating independently developed systems becomes painful.&lt;/p&gt;

&lt;p&gt;Another option is a &lt;strong&gt;message broker&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The broker sits between applications and can transform incoming messages into representations understood by destination applications.&lt;/p&gt;

&lt;p&gt;Now the intermediary is no longer merely storing and forwarding.&lt;/p&gt;

&lt;p&gt;It may be translating.&lt;br&gt;&lt;br&gt;
Routing.&lt;br&gt;&lt;br&gt;
Filtering.&lt;br&gt;&lt;br&gt;
Mediating between different expectations.&lt;/p&gt;

&lt;p&gt;The system has bought more decoupling by moving more responsibility into the communication layer.&lt;/p&gt;

&lt;p&gt;There is always a bill somewhere.&lt;/p&gt;




&lt;h3&gt;
  
  
  A Message Bus Is Not a Conveyor&amp;nbsp;Belt
&lt;/h3&gt;

&lt;p&gt;Once many applications communicate through shared infrastructure, we can go further and define a &lt;strong&gt;message bus&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Applications agree on message schemas.&lt;/p&gt;

&lt;p&gt;They agree on command messages.&lt;br&gt;&lt;br&gt;
They use shared infrastructure for sending those messages to recipients.&lt;/p&gt;

&lt;p&gt;This feels pleasantly orderly.&lt;/p&gt;

&lt;p&gt;Then comes another assumption worth losing:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;If I sent A and then B, surely everyone receives A and then B.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Not necessarily.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Routing can change.&lt;br&gt;&lt;br&gt;
Messages can be buffered.&lt;br&gt;&lt;br&gt;
Internal optimization can alter paths.&lt;br&gt;&lt;br&gt;
Different transports may behave differently.&lt;/p&gt;

&lt;p&gt;Some messaging infrastructures explicitly provide ordering guarantees, while others do not or provide them only under particular configurations. For example, AWS distinguishes standard queues, which can deliver messages more than once and occasionally out of order, from FIFO queues with stronger ordering guarantees. (&lt;a href="https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/standard-queues.html" rel="noopener noreferrer"&gt;&lt;em&gt;docs.aws.amazon.com&lt;/em&gt;&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;This is another reminder that &lt;strong&gt;ordering is a guarantee, not a vibe&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If application correctness depends on order, the communication contract must actually provide that order or the application has to reconstruct it.&lt;/p&gt;

&lt;p&gt;By now, our simple message has acquired quite a résumé.&lt;/p&gt;

&lt;p&gt;Persistence.&lt;br&gt;&lt;br&gt;
Synchronization.&lt;br&gt;&lt;br&gt;
Delivery guarantees.&lt;br&gt;&lt;br&gt;
Destination independence.&lt;br&gt;&lt;br&gt;
Schemas.&lt;br&gt;&lt;br&gt;
Routing.&lt;br&gt;&lt;br&gt;
Ordering.&lt;/p&gt;

&lt;p&gt;And we still have not reached the strangest version of &lt;code&gt;send&lt;/code&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  MPI Wants Speed More Than&amp;nbsp;Comfort
&lt;/h3&gt;

&lt;p&gt;Message queues are excellent when components need loose coupling and persistent asynchronous communication.&lt;/p&gt;

&lt;p&gt;But consider a very different environment.&lt;/p&gt;

&lt;p&gt;A parallel scientific program runs across hundreds or thousands of processors connected by a high-speed network.&lt;/p&gt;

&lt;p&gt;The processes are alive together.&lt;br&gt;&lt;br&gt;
They are cooperating on one computation.&lt;/p&gt;

&lt;p&gt;Milliseconds of messaging middleware overhead may be deeply unwelcome.&lt;/p&gt;

&lt;p&gt;Persistence after one process disappears is not necessarily the primary goal.&lt;/p&gt;

&lt;p&gt;What matters is &lt;strong&gt;fast, explicit communication between parallel processes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Enter the &lt;strong&gt;Message-Passing Interface&lt;/strong&gt;, or MPI.&lt;/p&gt;

&lt;p&gt;MPI is designed for distributed-memory parallel applications and provides standardized communication primitives that can be used across different hardware platforms.&lt;/p&gt;

&lt;p&gt;It is deliberately more explicit.&lt;/p&gt;

&lt;p&gt;Processes have ranks.&lt;/p&gt;

&lt;p&gt;They belong to &lt;strong&gt;communicators&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Messages have destinations and tags.&lt;/p&gt;

&lt;p&gt;The programmer controls how data moves.&lt;/p&gt;

&lt;p&gt;This gives MPI performance and flexibility.&lt;/p&gt;

&lt;p&gt;It also gives the programmer enough rope to construct some wonderfully sophisticated deadlocks.&lt;/p&gt;

&lt;p&gt;The abstraction is no longer trying to pretend that communication is someone else’s problem.&lt;/p&gt;

&lt;p&gt;MPI looks at the programmer and says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;You wanted control. Here is control.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  &lt;code&gt;MPI_Send&lt;/code&gt; Still Does Not Mean What You&amp;nbsp;Think
&lt;/h3&gt;

&lt;p&gt;Consider: &lt;code&gt;MPI_Send(...)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It is a &lt;strong&gt;blocking send&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Easy.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So it must block until the receiver receives the message.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Right?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not necessarily.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The MPI standard says that a blocking standard-mode send does not return until the send buffer can safely be reused. The implementation may accomplish that by copying the message into a temporary system buffer, or by transferring it into the matching receive. Whether buffering is used in standard mode is left to MPI.&lt;/p&gt;

&lt;p&gt;That means &lt;code&gt;MPI_Send&lt;/code&gt; can return even though the destination process has not yet executed its matching receive.&lt;/p&gt;

&lt;p&gt;Now make the message larger.&lt;/p&gt;

&lt;p&gt;The MPI implementation may decide that buffering it is too expensive.&lt;/p&gt;

&lt;p&gt;The same call may now have to wait for the receiver.&lt;/p&gt;

&lt;p&gt;The source code still says: &lt;code&gt;MPI_Send(...)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The observed behaviour changed because the implementation’s buffering strategy changed.&lt;/p&gt;

&lt;p&gt;This is why MPI programs that secretly depend on “small messages are buffered, therefore my send won’t wait” are living on borrowed time.&lt;/p&gt;

&lt;p&gt;A different MPI implementation can expose the assumption.&lt;br&gt;&lt;br&gt;
A different buffer threshold can expose it.&lt;br&gt;&lt;br&gt;
A different message size can expose it.&lt;/p&gt;

&lt;p&gt;The code did not become wrong because the message grew.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;The code was already relying on a guarantee MPI never made.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That is an uncomfortable but useful distinction.&lt;/p&gt;




&lt;h3&gt;
  
  
  MPI Has More Than One Kind of Send for a&amp;nbsp;Reason
&lt;/h3&gt;

&lt;p&gt;Once we understand the ambiguity, MPI’s multiple send primitives stop looking like API clutter.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;buffered send&lt;/strong&gt; explicitly uses buffering.&lt;br&gt;&lt;br&gt;
A &lt;strong&gt;synchronous send&lt;/strong&gt; waits until the corresponding receive has begun.&lt;br&gt;&lt;br&gt;
A standard send leaves more of the buffering decision to the implementation.&lt;/p&gt;

&lt;p&gt;Nonblocking operations allow communication to begin while the process continues with other work, with completion handled separately.&lt;/p&gt;

&lt;p&gt;The MPI standard deliberately provides these communication modes because buffering changes both performance and synchronization behaviour; standard mode may buffer, while synchronous mode lets the programmer require stronger coordination with the matching receive. (&lt;a href="https://www.mpi-forum.org/docs/mpi-4.1/mpi41-report/node66.htm" rel="noopener noreferrer"&gt;&lt;em&gt;mpi-forum.org&lt;/em&gt;&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;These are not several spellings of the same operation.&lt;/p&gt;

&lt;p&gt;They express different contracts.&lt;/p&gt;

&lt;p&gt;And once again, the right question is not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Which send function is coolest?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;What must be true before this process is allowed to continue?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is the recurring question underneath almost every communication abstraction we have touched.&lt;/p&gt;




&lt;h3&gt;
  
  
  Receiving Requires Its Own&amp;nbsp;Contract
&lt;/h3&gt;

&lt;p&gt;Sending is only half the story.&lt;/p&gt;

&lt;p&gt;An MPI receiver must decide what messages it is willing to accept.&lt;/p&gt;

&lt;p&gt;Messages can be matched using a &lt;strong&gt;source&lt;/strong&gt;, a &lt;strong&gt;tag&lt;/strong&gt;, and a &lt;strong&gt;communicator&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The communicator defines the group of processes participating in that communication universe.&lt;/p&gt;

&lt;p&gt;The process rank identifies participants inside that group.&lt;/p&gt;

&lt;p&gt;Tags distinguish messages that might otherwise look similar.&lt;/p&gt;

&lt;p&gt;A receive may accept a message from a specific process or use &lt;code&gt;MPI_ANY_SOURCE&lt;/code&gt; when the sender does not need to be known in advance.&lt;/p&gt;

&lt;p&gt;And a blocking &lt;code&gt;MPI_Recv&lt;/code&gt; waits until a matching message arrives.&lt;/p&gt;

&lt;p&gt;This explicit matching exists because in a parallel program there may be many messages in flight at once.&lt;/p&gt;

&lt;p&gt;The receiver cannot simply say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Give me&lt;/em&gt; “the message”.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Which message?&lt;br&gt;&lt;br&gt;
From whom?&lt;br&gt;&lt;br&gt;
For which phase of the algorithm?&lt;br&gt;&lt;br&gt;
Inside which group of processes?&lt;/p&gt;

&lt;p&gt;Communication correctness increasingly depends not just on moving bytes, but on ensuring the &lt;strong&gt;right communication operations find each other&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;MPI has made the hidden relationship between sender and receiver visible.&lt;/p&gt;




&lt;h3&gt;
  
  
  Then Point-to-Point Becomes&amp;nbsp;Awkward
&lt;/h3&gt;

&lt;p&gt;Suppose several processes are independently calculating pieces of one result.&lt;/p&gt;

&lt;p&gt;At the end, Process 0 needs the total.&lt;/p&gt;

&lt;p&gt;We could build that using individual sends.&lt;/p&gt;

&lt;p&gt;Process 1 sends its partial result to Process 0.&lt;br&gt;&lt;br&gt;
Process 2 sends its partial result.&lt;br&gt;&lt;br&gt;
Process 3 sends its partial result.&lt;br&gt;&lt;br&gt;
Process 0 receives everything and adds it.&lt;/p&gt;

&lt;p&gt;That works.&lt;br&gt;&lt;br&gt;
Then the process count grows.&lt;/p&gt;

&lt;p&gt;We can make the algorithm more clever by combining partial results through a tree.&lt;/p&gt;

&lt;p&gt;Now processes exchange intermediate sums.&lt;br&gt;&lt;br&gt;
Fewer communication steps.&lt;br&gt;&lt;br&gt;
Better use of parallelism.&lt;/p&gt;

&lt;p&gt;And eventually an obvious question appears:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why should every program rebuild the same communication pattern manually?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is where &lt;strong&gt;collective communication&lt;/strong&gt; becomes natural.&lt;/p&gt;

&lt;p&gt;Instead of describing dozens of individual point-to-point messages, express the group operation itself.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;MPI_Reduce&lt;/code&gt; says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Combine values contributed by the processes and place the result at one destination.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;MPI_Allreduce&lt;/code&gt; says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Combine them and give the result to everybody.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;MPI_Bcast&lt;/code&gt; says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;One process has data; distribute it to the group.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;MPI_Scatter&lt;/code&gt; says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Divide data from one process among the group.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;MPI_Gather&lt;/code&gt; says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Collect distributed pieces onto one process.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;MPI defines these explicitly as collective operations involving groups of processes rather than as mere convenience wrappers around an arbitrary collection of sends.&lt;/p&gt;

&lt;p&gt;The abstraction has moved upward.&lt;/p&gt;

&lt;p&gt;We are no longer saying how each pair of processes should communicate.&lt;br&gt;&lt;br&gt;
We are describing &lt;strong&gt;what the group is trying to accomplish&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  A Collective Is a Group&amp;nbsp;Contract
&lt;/h3&gt;

&lt;p&gt;This is where collective communication can punish a point-to-point mental model.&lt;/p&gt;

&lt;p&gt;Suppose Process 0 calls &lt;code&gt;MPI_Reduce&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
Process 1 decides to be clever and calls &lt;code&gt;MPI_Recv&lt;/code&gt; instead.&lt;/p&gt;

&lt;p&gt;They both seem related to receiving data.&lt;br&gt;&lt;br&gt;
They are not interchangeable.&lt;/p&gt;

&lt;p&gt;The program is erroneous.&lt;/p&gt;

&lt;p&gt;Collective operations have collective semantics.&lt;/p&gt;

&lt;p&gt;The processes participating in the communicator need to participate compatibly.&lt;/p&gt;

&lt;p&gt;The MPI standard requires all processes in the communicator’s group to call the collective routine, and collective operations must be executed in the same order across that communication group.&lt;/p&gt;

&lt;p&gt;This can feel annoyingly strict until the deeper model becomes visible.&lt;/p&gt;

&lt;p&gt;A collective operation is not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Process 0 happens to receive several messages.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;This group of processes is participating in one coordinated communication operation.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The communicator defines who belongs to that contract.&lt;br&gt;&lt;br&gt;
The operation defines what role their data plays.&lt;/p&gt;

&lt;p&gt;The ordering lets MPI match collective operations correctly and select efficient implementation strategies.&lt;/p&gt;

&lt;p&gt;Once we accept that, the rules stop looking arbitrary.&lt;/p&gt;

&lt;p&gt;The operation is bigger than any one sender.&lt;/p&gt;




&lt;h3&gt;
  
  
  “Send” Was Really a Question About Responsibility
&lt;/h3&gt;

&lt;p&gt;Look back at how far we travelled from: &lt;code&gt;send(message)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Transient communication asked whether the receiver needed to be present.&lt;/p&gt;

&lt;p&gt;Persistent communication moved responsibility for storing the message into the communication system.&lt;/p&gt;

&lt;p&gt;Asynchronous communication allowed the sender to continue after submission.&lt;/p&gt;

&lt;p&gt;Synchronous communication made the sender wait for stronger evidence.&lt;/p&gt;

&lt;p&gt;Receipt-based synchronization waited for the receiving host.&lt;br&gt;&lt;br&gt;
Delivery-based synchronization waited for the receiving application.&lt;br&gt;&lt;br&gt;
Response-based synchronization waited for processing to come back around.&lt;/p&gt;

&lt;p&gt;Queues separated sender and receiver in time.&lt;/p&gt;

&lt;p&gt;Publish/subscribe separated them in space and knowledge of one another.&lt;/p&gt;

&lt;p&gt;Message brokers took responsibility for translating between different message formats.&lt;/p&gt;

&lt;p&gt;MPI moved toward explicit, high-performance communication where buffering and synchronization became programmer-visible concerns.&lt;/p&gt;

&lt;p&gt;Collective communication went further and made the whole &lt;strong&gt;group operation&lt;/strong&gt; the unit of meaning.&lt;/p&gt;

&lt;p&gt;None of these mechanisms exists because engineers could not settle on one good &lt;code&gt;send()&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;They exist because distributed applications need different answers to the same questions:&lt;/p&gt;

&lt;p&gt;Who owns the message now?&lt;br&gt;&lt;br&gt;
How long will it survive?&lt;br&gt;&lt;br&gt;
Who must be alive?&lt;br&gt;&lt;br&gt;
Who has to wait?&lt;br&gt;&lt;br&gt;
What counts as delivery?&lt;br&gt;&lt;br&gt;
What ordering is guaranteed?&lt;br&gt;&lt;br&gt;
Who participates?&lt;br&gt;&lt;br&gt;
What happens when the operation involves an entire group instead of one sender and one receiver?&lt;/p&gt;

&lt;p&gt;Once those questions differ, the communication operation has to differ too.&lt;/p&gt;




&lt;h3&gt;
  
  
  Make the Contract Say What the System&amp;nbsp;Means
&lt;/h3&gt;

&lt;p&gt;The broader mistake is treating communication like physical movement.&lt;/p&gt;

&lt;p&gt;Alice had bytes.&lt;br&gt;&lt;br&gt;
Now Bob has bytes.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Done.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;But useful distributed communication is &lt;em&gt;rarely&lt;/em&gt; just about where the bytes are.&lt;/p&gt;

&lt;p&gt;It is about &lt;strong&gt;what the participants are allowed to assume after the communication operation returns&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A queue lets the producer assume the infrastructure accepted responsibility.&lt;/p&gt;

&lt;p&gt;A response-based call lets the sender assume processing reached a response.&lt;/p&gt;

&lt;p&gt;A synchronous MPI send gives a different synchronization relationship than a buffered one.&lt;/p&gt;

&lt;p&gt;A collective says something about an entire group, not merely two endpoints.&lt;/p&gt;

&lt;p&gt;Those are semantic guarantees.&lt;br&gt;&lt;br&gt;
And stronger guarantees are not free.&lt;/p&gt;

&lt;p&gt;Persistence requires storage.&lt;br&gt;&lt;br&gt;
Synchronization introduces waiting.&lt;br&gt;&lt;br&gt;
Loose coupling requires intermediaries.&lt;br&gt;&lt;br&gt;
Ordering restricts implementation freedom.&lt;br&gt;&lt;br&gt;
Collective coordination requires compatible participation.&lt;br&gt;&lt;br&gt;
Performance improves when we stop demanding guarantees we do not need.&lt;br&gt;&lt;br&gt;
Correctness improves when we stop assuming guarantees we were never given.&lt;/p&gt;

&lt;p&gt;So the next time The Origami Software Engineer’s API says &lt;code&gt;send&lt;/code&gt;,&amp;nbsp;&lt;br&gt;&lt;br&gt;
the useful question is not simply:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Where will this message go?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;What exactly will be true when this operation says it is finished?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is when messaging stops looking like a collection of oddly named primitives and starts looking like a set of deliberate contracts between independent processes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“Send” was never one operation.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;We just started with a mental model too small to notice.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That’s not failure.&lt;br&gt;&lt;br&gt;
That’s evolution.&lt;/p&gt;




&lt;h3&gt;
  
  
  The “I liked this” Starter Pack:
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Don’t let your fingers get lazy now.
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Like :&lt;/strong&gt; It tells me this was worth writing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A Comment:&lt;/strong&gt; Tell me your thoughts, your favorite snack, or a better title for this blog.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Boost it:&lt;/strong&gt; Especially with that one developer who definitely needs this.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Thanks for being here. It genuinely helps more than you know!&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;— Aaroophan Varatharajan&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Find me elsewhere:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Professional stuff:&lt;/strong&gt; &lt;a href="http://linkedin.com/in/Aaroophan" rel="noopener noreferrer"&gt;linkedin.com/in/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code stuff:&lt;/strong&gt; &lt;a href="http://github.com/Aaroophan" rel="noopener noreferrer"&gt;github.com/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UI stuff:&lt;/strong&gt; &lt;a href="https://aaroophan.dev/Aaroophan" rel="noopener noreferrer"&gt;aaroophan.dev/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Life stuff:&lt;/strong&gt; &lt;a href="http://instagram.com/aaroophan" rel="noopener noreferrer"&gt;instagram.com/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>distributedcomputing</category>
      <category>computerscience</category>
      <category>softwareengineering</category>
      <category>systemdesignconcepts</category>
    </item>
    <item>
      <title>A Remote Function Call Will Never Really Be Local: Rethinking Distributed Computing #4</title>
      <dc:creator>Aaroophan Varatharajan</dc:creator>
      <pubDate>Sat, 26 Sep 2026 13:24:47 +0000</pubDate>
      <link>https://dev.to/aaroophan/a-remote-function-call-will-never-really-be-local-rethinking-distributed-computing-4-bli</link>
      <guid>https://dev.to/aaroophan/a-remote-function-call-will-never-really-be-local-rethinking-distributed-computing-4-bli</guid>
      <description>&lt;h4&gt;
  
  
  &lt;em&gt;The API can hide the distance. It cannot erase what the distance&amp;nbsp;changes.&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F807q5g981stutlz79qht.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F807q5g981stutlz79qht.png" alt="Explore the CAP theorem through practical examples of replication, network partitions, split brain, quorum, consistency, and availability and learn what distributed systems sacrifice when communication fails." width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;"Explore the CAP theorem through practical examples of replication, network partitions, split brain, quorum, consistency, and availability and learn what distributed systems sacrifice when communication fails."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Suppose a client needs some work done by another component.&lt;/p&gt;

&lt;p&gt;On one machine, this is boring in the best possible way.&lt;/p&gt;

&lt;p&gt;Call a procedure.&lt;br&gt;&lt;br&gt;
Pass some arguments.&lt;br&gt;&lt;br&gt;
The procedure runs.&lt;br&gt;&lt;br&gt;
Get the result back.&lt;br&gt;&lt;br&gt;
✨&lt;strong&gt;&lt;em&gt;Continue&lt;/em&gt;&lt;/strong&gt;✨&lt;/p&gt;

&lt;p&gt;Then we move that procedure onto another computer.&lt;/p&gt;

&lt;p&gt;The first instinct is almost irresistible:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Why should the application care?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If the remote machine exposes the same operation, perhaps we can make calling it look exactly like calling a local procedure.&lt;/p&gt;

&lt;p&gt;Instead of forcing every application developer to think in sockets, packets, addresses, message formats, and transport protocols, give them something familiar.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;result = calculate(x, y)&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The caller should not have to stare into the abyss and think:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  open socket&lt;/li&gt;
&lt;li&gt;  encode x&lt;/li&gt;
&lt;li&gt;  encode y&lt;/li&gt;
&lt;li&gt;  construct message&lt;/li&gt;
&lt;li&gt;  send bytes&lt;/li&gt;
&lt;li&gt;  wait&lt;/li&gt;
&lt;li&gt;  receive bytes&lt;/li&gt;
&lt;li&gt;  decode result&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the promise of &lt;strong&gt;Remote Procedure Call&lt;/strong&gt;, or RPC.&lt;/p&gt;

&lt;p&gt;Call a procedure on another machine &lt;strong&gt;just as you would call a local procedure&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Birrell and Nelson’s original RPC design was built around exactly this idea:&lt;br&gt;&lt;br&gt;
Provide communication between programs across a network through the familiar abstraction of a procedure call. (&lt;/em&gt;&lt;a href="https://www.microsoft.com/en-us/research/publication/implementing-remote-procedure-calls/" rel="noopener noreferrer"&gt;Microsoft&lt;/a&gt;&lt;em&gt;)&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is an excellent abstraction.&lt;/p&gt;

&lt;p&gt;Which is why it is worth understanding where the abstraction stops.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Network Does Not Know What a Function&amp;nbsp;Is
&lt;/h3&gt;

&lt;p&gt;Before RPC can hide the network, something still has to use the network.&lt;/p&gt;

&lt;p&gt;Distributed communication commonly happens over IP using transports such as &lt;strong&gt;TCP&lt;/strong&gt; or &lt;strong&gt;UDP&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;TCP gives us a connection-oriented byte stream.&lt;/p&gt;

&lt;p&gt;UDP gives us connectionless datagrams.&lt;/p&gt;

&lt;p&gt;Neither one understands: &lt;code&gt;calculate(x, y)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The network understands messages and bytes.&lt;/p&gt;

&lt;p&gt;So somewhere between the line of application code and the remote implementation, the procedure call has to be transformed into communication.&lt;/p&gt;

&lt;p&gt;That is where RPC begins doing its little stage trick.&lt;/p&gt;

&lt;p&gt;The application calls a &lt;strong&gt;client stub&lt;/strong&gt; as though it were an ordinary procedure.&lt;/p&gt;

&lt;p&gt;The stub builds a message and passes it to the communication middleware.&lt;/p&gt;

&lt;p&gt;The message crosses the network.&lt;/p&gt;

&lt;p&gt;On the server, middleware passes it to a &lt;strong&gt;server stub&lt;/strong&gt;, or skeleton.&lt;/p&gt;

&lt;p&gt;The server side reconstructs the arguments and calls the real local implementation.&lt;/p&gt;

&lt;p&gt;The implementation returns a result.&lt;/p&gt;

&lt;p&gt;Then the whole journey happens in reverse.&lt;/p&gt;

&lt;p&gt;Server implementation → skeleton → middleware → network → client middleware → client stub → application.&lt;/p&gt;

&lt;p&gt;The application sees: &lt;code&gt;result = calculate(x, y)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The distributed system sees a round trip between two independent processes.&lt;/p&gt;

&lt;p&gt;The ONC RPC specification describes essentially this model: the caller sends a call message containing the procedure parameters, waits for a reply message containing the results, and resumes once that reply arrives. (&lt;a href="https://www.rfc-editor.org/info/rfc5531/" rel="noopener noreferrer"&gt;&lt;em&gt;RFC Editor&lt;/em&gt;&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;The procedure call did not cross the network.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A representation of the procedure call did.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That distinction is going to become expensive.&lt;/p&gt;




&lt;h3&gt;
  
  
  Even the Arguments Cannot Travel as Themselves
&lt;/h3&gt;

&lt;p&gt;Suppose &lt;code&gt;x&lt;/code&gt; is an integer.&lt;/p&gt;

&lt;p&gt;Easy enough.&lt;/p&gt;

&lt;p&gt;Put the integer into the message.&lt;/p&gt;

&lt;p&gt;Except two machines may not even represent that integer identically.&lt;/p&gt;

&lt;p&gt;One architecture may use one byte order.&lt;/p&gt;

&lt;p&gt;Another may use another.&lt;/p&gt;

&lt;p&gt;Strings may have different encoding or alignment rules.&lt;/p&gt;

&lt;p&gt;Floating-point representations have to agree.&lt;/p&gt;

&lt;p&gt;Arrays and structures have to be flattened into something that can travel and reconstructed at the other end.&lt;/p&gt;

&lt;p&gt;Memory addresses are even more suspicious. A pointer that means something inside the client’s address space does not suddenly become meaningful inside the server’s address space.&lt;/p&gt;

&lt;p&gt;So the stub has another responsibility.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Marshalling.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Data is encoded into a transmissible representation.&lt;/p&gt;

&lt;p&gt;On the receiving side it is &lt;strong&gt;unmarshalled&lt;/strong&gt;, or decoded, back into usable data structures.&lt;/p&gt;

&lt;p&gt;Protocols therefore need agreed representations for parameters and results. ONC RPC, for example, uses External Data Representation to describe the messages exchanged between participants. (&lt;a href="https://www.rfc-editor.org/info/rfc5531/" rel="noopener noreferrer"&gt;&lt;em&gt;RFC Editor&lt;/em&gt;&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;This is the first crack in the illusion.&lt;/p&gt;

&lt;p&gt;A local call can hand another procedure values that already live in the same computational world.&lt;/p&gt;

&lt;p&gt;A remote call has to &lt;strong&gt;translate one machine’s world into something another machine can reconstruct&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The API may look local.&lt;/p&gt;

&lt;p&gt;The data most definitely knows it travelled.&lt;/p&gt;




&lt;h3&gt;
  
  
  Then We Have to Find the Procedure
&lt;/h3&gt;

&lt;p&gt;There is another detail a local call gets almost for free.&lt;/p&gt;

&lt;p&gt;When code calls a local procedure, the runtime knows where that procedure is.&lt;/p&gt;

&lt;p&gt;A remote service may be somewhere else entirely.&lt;/p&gt;

&lt;p&gt;Which machine?&lt;br&gt;&lt;br&gt;
Which process?&lt;br&gt;&lt;br&gt;
Which endpoint?&lt;br&gt;&lt;br&gt;
Which version?&lt;/p&gt;

&lt;p&gt;So remote invocation needs &lt;strong&gt;binding&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A client has to discover and connect to the service that implements the desired interface.&lt;/p&gt;

&lt;p&gt;That may involve some kind of directory or registry.&lt;/p&gt;

&lt;p&gt;Once bound, the client can continue pretending that it simply possesses something callable.&lt;/p&gt;

&lt;p&gt;This is location transparency doing useful work.&lt;/p&gt;

&lt;p&gt;The client wants:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Give me the service that performs this operation.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It does not necessarily want:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Please make me personally manage the physical location and network configuration of the process currently implementing it.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Even formal RPC specifications separate the call protocol from the higher-level mechanism that binds a client to a particular service and transport endpoint. (&lt;a href="https://www.rfc-editor.org/info/rfc5531/" rel="noopener noreferrer"&gt;&lt;em&gt;RFC Editor&lt;/em&gt;&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Again, perfectly reasonable abstraction.&lt;br&gt;&lt;br&gt;
Again, the machinery underneath has not disappeared.&lt;/p&gt;

&lt;p&gt;We have hidden &lt;strong&gt;where&lt;/strong&gt; the call goes.&lt;br&gt;&lt;br&gt;
We still have to deal with &lt;strong&gt;what happens while it is going there&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Local Calls Have a Very Comfortable Timeline
&lt;/h3&gt;

&lt;p&gt;Consider an ordinary synchronous procedure call.&lt;/p&gt;

&lt;p&gt;You call.&lt;br&gt;&lt;br&gt;
You wait.&lt;br&gt;&lt;br&gt;
The procedure returns.&lt;br&gt;&lt;br&gt;
You continue.&lt;/p&gt;

&lt;p&gt;RPC can reproduce that programming model.&lt;/p&gt;

&lt;p&gt;But once the operation becomes communication, other interaction patterns suddenly become useful.&lt;/p&gt;

&lt;p&gt;The client may send a message and wait for a response.&lt;br&gt;&lt;br&gt;
Or send without waiting at all: &lt;strong&gt;fire and forget&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Or send and wait only for an acknowledgement that the request was received.&lt;/p&gt;

&lt;p&gt;A client may block.&lt;br&gt;&lt;br&gt;
It may poll.&lt;br&gt;&lt;br&gt;
It may provide a callback.&lt;/p&gt;

&lt;p&gt;The call may be asynchronous or use deferred synchronization.&lt;/p&gt;

&lt;p&gt;The ONC RPC model itself notes that implementations are not restricted to the simple blocking model; asynchronous execution is possible so the client can continue doing useful work while the remote operation proceeds. (&lt;a href="https://www.rfc-editor.org/info/rfc5531/" rel="noopener noreferrer"&gt;&lt;em&gt;RFC Editor&lt;/em&gt;&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Why does a supposedly local-looking call suddenly need all these options?&lt;/p&gt;

&lt;p&gt;Because latency exists.&lt;/p&gt;

&lt;p&gt;A local function call is usually close enough that waiting is the natural default.&lt;/p&gt;

&lt;p&gt;A remote invocation can spend meaningful time crossing a network, waiting in another process, doing work, and crossing the network again.&lt;/p&gt;

&lt;p&gt;Distribution changed the cost of waiting.&lt;/p&gt;

&lt;p&gt;So even before anything fails, the network has already leaked into the programming model.&lt;/p&gt;

&lt;p&gt;Then something fails.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Timeout Is Where the Illusion Gets&amp;nbsp;Cursed
&lt;/h3&gt;

&lt;p&gt;The client sends a request.&lt;br&gt;&lt;br&gt;
Nothing comes back.&lt;br&gt;&lt;br&gt;
So it waits.&lt;br&gt;&lt;br&gt;
Eventually it times out.&lt;/p&gt;

&lt;p&gt;What happened?&lt;/p&gt;

&lt;p&gt;That sounds like a simple question. &lt;em&gt;It is not.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Perhaps the request packet was lost before reaching the server.&lt;br&gt;&lt;br&gt;
Perhaps the request reached the server, but the acknowledgement was lost.&lt;br&gt;&lt;br&gt;
Perhaps the server executed the procedure and the reply was lost.&lt;br&gt;&lt;br&gt;
Perhaps the network became unavailable.&lt;br&gt;&lt;br&gt;
Perhaps the server process failed.&lt;br&gt;&lt;br&gt;
Perhaps the entire server machine failed.&lt;/p&gt;

&lt;p&gt;From the client’s point of view, several very different realities can collapse into exactly the same observation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;No reply arrived.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This does not happen in the same way with an ordinary local procedure call.&lt;/p&gt;

&lt;p&gt;The network has introduced ambiguity.&lt;/p&gt;

&lt;p&gt;And ambiguity is where “&lt;em&gt;remote is just like local&lt;/em&gt;” finally stops being an innocent simplification.&lt;/p&gt;




&lt;h3&gt;
  
  
  Fine. Retransmit It.
&lt;/h3&gt;

&lt;p&gt;For ordinary communication failures, there are reasonable techniques.&lt;/p&gt;

&lt;p&gt;Give requests unique identifiers or sequence numbers.&lt;br&gt;&lt;br&gt;
Use acknowledgements.&lt;br&gt;&lt;br&gt;
Detect duplicates.&lt;br&gt;&lt;br&gt;
If a message appears to have been lost, retransmit it.&lt;/p&gt;

&lt;p&gt;This works beautifully for a lost packet.&lt;/p&gt;

&lt;p&gt;Client sends request.&lt;br&gt;&lt;br&gt;
No acknowledgement.&lt;br&gt;&lt;br&gt;
Timeout.&lt;br&gt;&lt;br&gt;
Client sends request again.&lt;br&gt;&lt;br&gt;
Server receives it.&lt;br&gt;&lt;br&gt;
Reply arrives.&lt;/p&gt;

&lt;p&gt;_Problem solved.&lt;br&gt;&lt;br&gt;
_Except there is another possible history.&lt;/p&gt;

&lt;p&gt;Client sends request.&lt;br&gt;&lt;br&gt;
Server receives it.&lt;br&gt;&lt;br&gt;
Server performs the operation.&lt;br&gt;&lt;br&gt;
The acknowledgement or reply disappears.&lt;br&gt;&lt;br&gt;
Client times out.&lt;br&gt;&lt;br&gt;
Client sends the request again.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now the server has seen the same operation twice.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For something harmless, perhaps that does not matter.&lt;br&gt;&lt;br&gt;
For an operation with side effects, it matters quite a lot.&lt;/p&gt;

&lt;p&gt;Imagine the remote procedure is: &lt;code&gt;TransferMoney(100)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The client did not ask: &lt;code&gt;MaybeTransferMoneySomeNumberOfTimes(100)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Retries make the transport more reliable.&lt;/p&gt;

&lt;p&gt;They can simultaneously make the operation less obviously correct.&lt;/p&gt;

&lt;p&gt;This is why duplicate detection exists. A server can recognize an identifier it has already processed and avoid executing the same logical request again. ONC RPC similarly uses transaction IDs to match requests and replies and describes retaining those IDs as a way of obtaining a degree of execute-at-most-once behaviour. (&lt;a href="https://www.rfc-editor.org/info/rfc5531/" rel="noopener noreferrer"&gt;&lt;em&gt;RFC Editor&lt;/em&gt;&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;The retry mechanism is not merely recovering lost packets.&lt;/p&gt;

&lt;p&gt;It is trying to recover the &lt;strong&gt;meaning of the original invocation&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Did the Server Run&amp;nbsp;It?
&lt;/h3&gt;

&lt;p&gt;Now we reach the unpleasant question.&lt;/p&gt;

&lt;p&gt;The client sends a request.&lt;br&gt;&lt;br&gt;
The server executes it.&lt;/p&gt;

&lt;p&gt;Before the client receives the reply, communication disappears.&lt;/p&gt;

&lt;p&gt;What should the client conclude?&lt;/p&gt;

&lt;p&gt;The tempting answer is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The call failed.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But what exactly does &lt;em&gt;failed&lt;/em&gt; mean?&lt;/p&gt;

&lt;p&gt;It certainly means the client did not receive a successful result.&lt;br&gt;&lt;br&gt;
It does &lt;strong&gt;not&lt;/strong&gt; necessarily mean the server did not perform the operation.&lt;/p&gt;

&lt;p&gt;That is the hidden difference.&lt;/p&gt;

&lt;p&gt;The client knows what it observed.&lt;/p&gt;

&lt;p&gt;It does not automatically know what happened on the other machine.&lt;/p&gt;

&lt;p&gt;Even with a reliable transport such as TCP, receiving a reply allows the caller to know the remote operation executed, but receiving no reply does not prove that it never executed. The RPC specification states this distinction explicitly. (&lt;a href="https://www.rfc-editor.org/info/rfc5531/" rel="noopener noreferrer"&gt;&lt;em&gt;RFC Editor&lt;/em&gt;&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;That gives a timeout a very different meaning from the one our local-call intuition wants to assign to it.&lt;/p&gt;

&lt;p&gt;A timeout does not say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;The procedure did not execute.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;I can no longer determine the outcome from the communication I received.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That sounds like a small wording difference.&lt;/p&gt;

&lt;p&gt;It changes application design.&lt;/p&gt;

&lt;p&gt;Retries.&lt;br&gt;&lt;br&gt;
Idempotency.&lt;br&gt;&lt;br&gt;
Error handling.&lt;br&gt;&lt;br&gt;
Transaction semantics.&lt;br&gt;&lt;br&gt;
Recovery.&lt;/p&gt;

&lt;p&gt;All of them eventually run into the same question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Did nothing happen, or did something happen and I simply failed to hear about it?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The network can make those realities indistinguishable from the caller’s side.&lt;/p&gt;




&lt;h3&gt;
  
  
  Failure Transparency Has a&amp;nbsp;Limit
&lt;/h3&gt;

&lt;p&gt;RPC originally aimed for a highly transparent programming model.&lt;/p&gt;

&lt;p&gt;Hide location.&lt;br&gt;&lt;br&gt;
Hide communication.&lt;br&gt;&lt;br&gt;
Hide parameter conversion.&lt;/p&gt;

&lt;p&gt;Make remote interaction feel ordinary.&lt;/p&gt;

&lt;p&gt;But failures are where complete transparency becomes dangerous.&lt;/p&gt;

&lt;p&gt;If a local-looking call can fail because another machine disappeared, the caller eventually needs some way to know that this failure category exists.&lt;/p&gt;

&lt;p&gt;Modern RPC designs therefore acknowledge the things the abstraction cannot safely erase: network failures, remote process failures, communication latency, asynchronous behaviour, and the possibility that a request’s outcome is uncertain.&lt;/p&gt;

&lt;p&gt;A remote call is still a convenient abstraction.&lt;/p&gt;

&lt;p&gt;It is just no longer pretending that distribution has no semantic consequences.&lt;/p&gt;

&lt;p&gt;This is a healthier contract.&lt;/p&gt;

&lt;p&gt;The abstraction says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;You do not need to manually construct network messages for every invocation.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It does &lt;strong&gt;not&lt;/strong&gt; say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;You may reason as though there is no network.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Those are very different promises.&lt;/p&gt;




&lt;h3&gt;
  
  
  Then We Tried It With&amp;nbsp;Objects
&lt;/h3&gt;

&lt;p&gt;Once procedures could be invoked remotely, the next progression was natural.&lt;/p&gt;

&lt;p&gt;What about objects?&lt;/p&gt;

&lt;p&gt;That leads from RPC toward &lt;strong&gt;Remote Method Invocation&lt;/strong&gt;, or RMI.&lt;/p&gt;

&lt;p&gt;Instead of invoking a standalone remote procedure, a client invokes a method on a remote object.&lt;/p&gt;

&lt;p&gt;The client first binds to that distributed object.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;proxy&lt;/strong&gt; representing the remote interface lives on the client side, playing a role similar to the RPC client stub.&lt;/p&gt;

&lt;p&gt;The proxy serializes or marshals the invocation into messages.&lt;/p&gt;

&lt;p&gt;On the server, a &lt;strong&gt;skeleton&lt;/strong&gt; receives the invocation, unmarshals it, and calls the actual object’s implementation.&lt;/p&gt;

&lt;p&gt;Results travel back in the opposite direction.&lt;/p&gt;

&lt;p&gt;But an important boundary remains.&lt;/p&gt;

&lt;p&gt;The remote object’s entire memory does not magically teleport into the client.&lt;/p&gt;

&lt;p&gt;What becomes remotely accessible is its &lt;strong&gt;interface&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The interface says what operations can be invoked.&lt;/p&gt;

&lt;p&gt;The implementation and state still live elsewhere.&lt;/p&gt;

&lt;p&gt;Java RMI makes that separation explicit: a remote interface declares the methods that can be invoked from another virtual machine, and failures during remote invocation include communication problems as well as marshalling and protocol errors. (&lt;a href="https://docs.oracle.com/en/java/javase/17/docs/specs/rmi/objmodel.html" rel="noopener noreferrer"&gt;&lt;em&gt;Oracle Docs&lt;/em&gt;&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;The object may look near.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Its state is still remote.&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Remote Exceptions Are the Abstraction Admitting the&amp;nbsp;Truth
&lt;/h3&gt;

&lt;p&gt;RMI produces one particularly honest design choice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remote exceptions.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Suppose the remote method itself throws an application exception.&lt;/p&gt;

&lt;p&gt;That failure can be marshalled into a response, sent back to the client, reconstructed, and raised as an exception on the caller’s side.&lt;/p&gt;

&lt;p&gt;From the application’s point of view, that can feel pleasantly local.&lt;/p&gt;

&lt;p&gt;But remote invocation also has failure modes that exist &lt;em&gt;because the method is remote&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The server may be unreachable.&lt;br&gt;&lt;br&gt;
The connection may fail.&lt;br&gt;&lt;br&gt;
Arguments may fail to marshal.&lt;br&gt;&lt;br&gt;
The response may fail to unmarshal.&lt;br&gt;&lt;br&gt;
The protocol may fail.&lt;/p&gt;

&lt;p&gt;Java RMI therefore requires remote interfaces to account for &lt;code&gt;RemoteException&lt;/code&gt;, which represents communication-related failures that can occur during a remote invocation. (&lt;a href="https://docs.oracle.com/en/java/javase/26/docs/api/java.rmi/java/rmi/RemoteException.html?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;&lt;em&gt;Oracle Docs&lt;/em&gt;&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;That requirement is almost philosophical.&lt;/p&gt;

&lt;p&gt;The API still gives us the elegance of: &lt;code&gt;RemoteObject.DoSomething()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;But the type system quietly taps us on the shoulder:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Remember. This can fail in ways a local method cannot.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is not the abstraction giving up.&lt;br&gt;&lt;br&gt;
That is the abstraction becoming honest.&lt;/p&gt;




&lt;h3&gt;
  
  
  Transparency Should Remove Work, Not&amp;nbsp;Reality
&lt;/h3&gt;

&lt;p&gt;RPC succeeded because the original idea was good.&lt;/p&gt;

&lt;p&gt;The Origami Software Engineer should not have to rebuild networking primitives every time one program needs to ask another program to do something.&lt;/p&gt;

&lt;p&gt;Stubs are useful.&lt;br&gt;&lt;br&gt;
Marshalling is useful.&lt;br&gt;&lt;br&gt;
Binding is useful.&lt;br&gt;&lt;br&gt;
Location transparency is useful.&lt;br&gt;&lt;br&gt;
Remote interfaces are useful.&lt;/p&gt;

&lt;p&gt;Turning messages into something that resembles ordinary procedure or method invocation is one of the most productive abstractions in distributed computing. The original RPC work and later standardized RPC protocols both preserve that familiar call model while explicitly dealing with binding, message representation, transport, and failure semantics. (&lt;a href="https://www.microsoft.com/en-us/research/publication/implementing-remote-procedure-calls/" rel="noopener noreferrer"&gt;&lt;em&gt;Microsoft&lt;/em&gt;&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;The mistake is not using the abstraction.&lt;br&gt;&lt;br&gt;
The mistake is believing it literally.&lt;/p&gt;

&lt;p&gt;A local procedure call and a remote procedure call may share syntax.&lt;/p&gt;

&lt;p&gt;They do not share physics.&lt;/p&gt;

&lt;p&gt;One crosses an address-space boundary.&lt;/p&gt;

&lt;p&gt;The other crosses machines, networks, representations, clocks, failure domains, and potentially administrative boundaries.&lt;/p&gt;

&lt;p&gt;One can usually tell you whether control returned.&lt;/p&gt;

&lt;p&gt;The other may leave you asking whether the operation happened at all.&lt;/p&gt;

&lt;p&gt;So good distributed abstractions do something subtler than making the network disappear.&lt;/p&gt;

&lt;p&gt;They hide the mechanics that programmers should not have to repeat.&lt;/p&gt;

&lt;p&gt;Then they expose the consequences that programmers cannot safely ignore.&lt;/p&gt;

&lt;p&gt;The remote function call was never going to become truly local.&lt;/p&gt;

&lt;p&gt;It did something more useful.&lt;br&gt;&lt;br&gt;
It became familiar without pretending that distance was free.&lt;/p&gt;

&lt;p&gt;That’s not failure.&lt;br&gt;&lt;br&gt;
That’s evolution.&lt;/p&gt;




&lt;h3&gt;
  
  
  The “I liked this” Starter Pack:
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Don’t let your fingers get lazy now.
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Like :&lt;/strong&gt; It tells me this was worth writing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A Comment:&lt;/strong&gt; Tell me your thoughts, your favorite snack, or a better title for this blog.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Boost it:&lt;/strong&gt; Especially with that one developer who definitely needs this.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Thanks for being here. It genuinely helps more than you know!&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;— Aaroophan Varatharajan&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Find me elsewhere:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Professional stuff:&lt;/strong&gt; &lt;a href="http://linkedin.com/in/Aaroophan" rel="noopener noreferrer"&gt;linkedin.com/in/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code stuff:&lt;/strong&gt; &lt;a href="http://github.com/Aaroophan" rel="noopener noreferrer"&gt;github.com/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UI stuff:&lt;/strong&gt; &lt;a href="https://aaroophan.dev/Aaroophan" rel="noopener noreferrer"&gt;aaroophan.dev/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Life stuff:&lt;/strong&gt; &lt;a href="http://instagram.com/aaroophan" rel="noopener noreferrer"&gt;instagram.com/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>distributedcomputing</category>
      <category>computerscience</category>
      <category>softwareengineering</category>
      <category>systemdesignconcepts</category>
    </item>
    <item>
      <title>Navigating the CAP Theorem: Rethinking Distributed Computing #3</title>
      <dc:creator>Aaroophan Varatharajan</dc:creator>
      <pubDate>Sat, 26 Sep 2026 13:24:29 +0000</pubDate>
      <link>https://dev.to/aaroophan/navigating-the-cap-theorem-rethinking-distributed-computing-3-1ppk</link>
      <guid>https://dev.to/aaroophan/navigating-the-cap-theorem-rethinking-distributed-computing-3-1ppk</guid>
      <description>&lt;h4&gt;
  
  
  &lt;em&gt;Replication gives us another copy of the truth. Then the network disappears, and both copies have to decide whether they are still allowed to call themselves true.&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmpr3nsyu0n6sgu6h9qbf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmpr3nsyu0n6sgu6h9qbf.png" alt="A practical guide to the CAP theorem, exploring consistency, availability, network partitions, split brain, quorum, and why distributed systems must choose what correctness means when communication fails." width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"A practical guide to the CAP theorem, exploring consistency, availability, network partitions, split brain, quorum, and why distributed systems must choose what correctness means when communication fails."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Imagine a hotel booking system running on one server.&lt;/p&gt;

&lt;p&gt;Bob asks for Room 12.&lt;br&gt;&lt;br&gt;
The server checks.&lt;br&gt;&lt;br&gt;
Room 12 is available.&lt;br&gt;&lt;br&gt;
Bob gets the room.&lt;/p&gt;

&lt;p&gt;There is something &lt;strong&gt;✨&lt;em&gt;beautifully&lt;/em&gt;✨&lt;/strong&gt; uncomplicated about this. One server owns the state, so there is one obvious answer to the question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Is Room 12 available?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But one server is also one failure away from having &lt;em&gt;no booking system at all.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So we do the sensible thing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Add another server.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Perhaps one serves one region and another serves somewhere else. Keep their booking records synchronized. If one machine becomes unavailable, the other can continue serving customers.&lt;/p&gt;

&lt;p&gt;More redundancy.&lt;br&gt;&lt;br&gt;
More availability.&lt;br&gt;&lt;br&gt;
More confidence.&lt;/p&gt;

&lt;p&gt;Until Bob asks Server A for Room 12 at exactly the wrong moment, while Dong asks Server B for the same room.&lt;/p&gt;

&lt;p&gt;Normally, the servers coordinate.&lt;/p&gt;

&lt;p&gt;This time, the connection between them has disappeared.&lt;/p&gt;

&lt;p&gt;Server A checks what it knows.&lt;br&gt;&lt;br&gt;
Available.&lt;/p&gt;

&lt;p&gt;Server B checks what it knows.&lt;br&gt;&lt;br&gt;
Also available.&lt;/p&gt;

&lt;p&gt;Bob gets Room 12.&lt;br&gt;&lt;br&gt;
Dong gets Room 12.&lt;/p&gt;

&lt;p&gt;Both servers behaved perfectly according to the reality they could see.&lt;br&gt;&lt;br&gt;
And together they produced an impossible hotel.&lt;/p&gt;

&lt;p&gt;That is the uncomfortable beginning of CAP.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Problem Is Not That Either Server Is&amp;nbsp;Wrong
&lt;/h3&gt;

&lt;p&gt;At first, it is tempting to blame synchronization.&lt;/p&gt;

&lt;p&gt;Surely the servers should simply synchronize before confirming the booking.&lt;/p&gt;

&lt;p&gt;That does solve the problem while communication is working.&lt;/p&gt;

&lt;p&gt;But now keep the network partition.&lt;/p&gt;

&lt;p&gt;Server A cannot reach Server B.&lt;/p&gt;

&lt;p&gt;What should A do when Bob asks for the room?&lt;/p&gt;

&lt;p&gt;There are two obvious choices.&lt;/p&gt;

&lt;p&gt;It can say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I cannot verify the current state, so I refuse to complete the request.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The data remains safe from contradictory bookings.&lt;/p&gt;

&lt;p&gt;But Bob has encountered an unavailable service even though Server A itself is alive and perfectly capable of computing.&lt;/p&gt;

&lt;p&gt;Or Server A can say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I cannot reach B, but according to my local state the room is free, so I will continue.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Bob gets a response.&lt;/p&gt;

&lt;p&gt;The service remains available.&lt;/p&gt;

&lt;p&gt;But Server B may independently tell Dong exactly the same thing.&lt;/p&gt;

&lt;p&gt;The system cannot guarantee both behaviours simultaneously.&lt;/p&gt;

&lt;p&gt;That tension is what the &lt;strong&gt;CAP theorem&lt;/strong&gt; formalizes.&lt;/p&gt;

&lt;p&gt;In the usual formulation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Consistency&lt;/strong&gt; means clients observe one coherent, up-to-date view of the data.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Availability&lt;/strong&gt; means requests to non-failing parts of the system receive responses.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Partition tolerance&lt;/strong&gt; means the system must cope with communication being lost between parts of the network.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Gilbert and Lynch formally showed that in an asynchronous network subject to partitions, a distributed service cannot guarantee both strong consistency and availability during such a partition.&lt;/p&gt;

&lt;p&gt;The network has forced a decision.&lt;/p&gt;

&lt;p&gt;Not because the architecture was badly implemented.&lt;/p&gt;

&lt;p&gt;Because the two servers no longer have enough information to make both promises.&lt;/p&gt;




&lt;h3&gt;
  
  
  “Pick Two” Is a Little Too Comfortable
&lt;/h3&gt;

&lt;p&gt;CAP is often introduced as a triangle:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consistency. Availability. Partition Tolerance.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pick two.&lt;/p&gt;

&lt;p&gt;It is memorable.&lt;br&gt;&lt;br&gt;
It is also dangerously easy to interpret as a shopping list.&lt;/p&gt;

&lt;p&gt;Want consistency and availability? Choose &lt;strong&gt;CA&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Want availability and partition tolerance? Choose &lt;strong&gt;AP&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Want consistency and partition tolerance? Choose &lt;strong&gt;CP&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The diagram makes these choices look wonderfully symmetrical.&lt;/p&gt;

&lt;p&gt;Reality is less cooperative.&lt;/p&gt;

&lt;p&gt;In an actual distributed system, we do not control whether a cable is cut, a switch fails, packets disappear, or two healthy machines temporarily lose their ability to communicate.&lt;/p&gt;

&lt;p&gt;We do not get to configure: &lt;code&gt;network.partition = false&lt;/code&gt;and move on with our day.&lt;/p&gt;

&lt;p&gt;AWS’s current CAP guidance makes the practical implication explicit: distributed systems generally have to tolerate network failures, so when a partition occurs, the meaningful trade-off becomes &lt;strong&gt;consistency versus availability&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That changes the question.&lt;/p&gt;

&lt;p&gt;It is no longer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Which two letters would you like?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It becomes:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;When communication breaks, what is the system allowed to sacrifice?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is a much less decorative question.&lt;br&gt;&lt;br&gt;
And a much more useful one.&lt;/p&gt;




&lt;h3&gt;
  
  
  CP Says “I Would Rather Refuse Than&amp;nbsp;Lie”
&lt;/h3&gt;

&lt;p&gt;Go back to Room 12.&lt;/p&gt;

&lt;p&gt;Server A cannot communicate with Server B.&lt;/p&gt;

&lt;p&gt;If we care strongly about consistency, Server A cannot confidently approve Bob’s reservation.&lt;/p&gt;

&lt;p&gt;Perhaps B has already sold the room.&lt;/p&gt;

&lt;p&gt;A does not know.&lt;/p&gt;

&lt;p&gt;That uncertainty matters.&lt;/p&gt;

&lt;p&gt;So a &lt;strong&gt;CP-style&lt;/strong&gt; design may refuse operations that cannot be completed safely while the partition exists.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This can feel frustrating.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Both servers are alive.&lt;/p&gt;

&lt;p&gt;The database process is running.&lt;/p&gt;

&lt;p&gt;The CPU is fine.&lt;/p&gt;

&lt;p&gt;The request arrived.&lt;/p&gt;

&lt;p&gt;And the system still says no.&lt;/p&gt;

&lt;p&gt;But the refusal is doing real work.&lt;/p&gt;

&lt;p&gt;The system is protecting an invariant:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;One room must not be successfully reserved twice.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Consistency becomes more important than allowing every surviving partition to continue independently.&lt;/p&gt;

&lt;p&gt;This same idea appears in distributed locking and majority-based protocols. A node may be technically alive yet deliberately prevented from acting because it lacks enough agreement from the rest of the system.&lt;/p&gt;

&lt;p&gt;The service has not forgotten how to process the request.&lt;/p&gt;

&lt;p&gt;It has lost the &lt;strong&gt;authority&lt;/strong&gt; to process it safely.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;That distinction matters.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  AP Says “I Would Rather Answer and Reconcile Later”
&lt;/h3&gt;

&lt;p&gt;Now imagine a different kind of data.&lt;/p&gt;

&lt;p&gt;You edit a file while disconnected from the network.&lt;/p&gt;

&lt;p&gt;Should the application freeze until every other copy of that file is reachable?&lt;/p&gt;

&lt;p&gt;That would certainly make synchronization easier.&lt;/p&gt;

&lt;p&gt;It would also be a fairly cursed user experience.&lt;/p&gt;

&lt;p&gt;So an &lt;strong&gt;AP-style&lt;/strong&gt; system can make the opposite trade.&lt;/p&gt;

&lt;p&gt;Let the reachable side continue operating.&lt;/p&gt;

&lt;p&gt;Accept that different replicas may temporarily disagree.&lt;/p&gt;

&lt;p&gt;Then reconcile them later.&lt;/p&gt;

&lt;p&gt;This leads naturally toward weaker consistency guarantees, including &lt;strong&gt;eventual consistency&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The distinction is useful:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Strong consistency&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;says that after an update completes, subsequent accesses should observe that updated state.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Weak consistency&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;does not guarantee that an immediate subsequent access will see it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Eventual consistency&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;adds an important promise: if updates stop, replicas will eventually converge toward the latest state.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Dropbox gives a wonderfully tangible version of the idea. Files marked available offline can be opened and edited without network access. Those changes do not synchronize to other devices while the machine is disconnected; synchronization resumes when connectivity returns. If the same file is changed independently, conflicts may need to be represented and resolved.&lt;/p&gt;

&lt;p&gt;The local copy is allowed to keep living its life.&lt;/p&gt;

&lt;p&gt;For a while, two devices may disagree.&lt;/p&gt;

&lt;p&gt;That does not automatically mean the system has failed.&lt;/p&gt;

&lt;p&gt;It means the system decided that temporary inconsistency was preferable to making the file unusable whenever synchronization became impossible.&lt;/p&gt;




&lt;h3&gt;
  
  
  AP Is Not “No Consistency”, and CP Is Not “No Availability”
&lt;/h3&gt;

&lt;p&gt;This is where the simple CAP triangle can really mess with the mental model.&lt;/p&gt;

&lt;p&gt;An AP system does not necessarily throw consistency into a bin and wish everyone luck.&lt;/p&gt;

&lt;p&gt;A CP system does not necessarily collapse into permanent unavailability whenever one packet goes missing.&lt;/p&gt;

&lt;p&gt;These properties have degrees, time windows, scope, and application-specific meaning.&lt;/p&gt;

&lt;p&gt;An available system might return slightly stale information while aggressively propagating updates and resolving conflicts.&lt;/p&gt;

&lt;p&gt;A consistency-focused system might remain completely available whenever communication is healthy and only restrict a subset of operations during an actual partition.&lt;/p&gt;

&lt;p&gt;The trade-off becomes interesting precisely because it is not always static.&lt;/p&gt;

&lt;p&gt;Consider an airline reservation system.&lt;/p&gt;

&lt;p&gt;Suppose a flight has 200 seats and only 40 have been sold.&lt;/p&gt;

&lt;p&gt;A temporary inconsistency in the exact remaining count may be tolerable. Refusing every reservation merely because one replica cannot be reached could cause more harm than allowing another booking.&lt;/p&gt;

&lt;p&gt;Availability has room to breathe.&lt;/p&gt;

&lt;p&gt;Now imagine 199 seats are gone.&lt;/p&gt;

&lt;p&gt;Suddenly the remaining state matters a lot.&lt;/p&gt;

&lt;p&gt;Two independent servers both believing that one seat remains can sell seat 200 twice.&lt;/p&gt;

&lt;p&gt;The invariant has become tight.&lt;/p&gt;

&lt;p&gt;Consistency now deserves more authority.&lt;/p&gt;

&lt;p&gt;Same system.&lt;br&gt;&lt;br&gt;
Same data.&lt;br&gt;&lt;br&gt;
Different moment.&lt;br&gt;&lt;br&gt;
Different acceptable trade-off.&lt;/p&gt;

&lt;p&gt;The deeper lesson is not “choose AP” or “choose CP.”&lt;/p&gt;

&lt;p&gt;It is to understand &lt;strong&gt;which guarantees matter for which operations, and under which conditions&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Then the Backup Decides the Primary Is&amp;nbsp;Dead
&lt;/h3&gt;

&lt;p&gt;CAP becomes even easier to feel when we stop talking about database reads and watch a system accidentally create &lt;strong&gt;two authorities&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Consider a primary server and a backup.&lt;/p&gt;

&lt;p&gt;Clients normally use the primary.&lt;/p&gt;

&lt;p&gt;The primary sends updates to the backup so the backup can take over if necessary.&lt;/p&gt;

&lt;p&gt;This is sensible redundancy.&lt;/p&gt;

&lt;p&gt;Now break the communication link between primary and backup.&lt;/p&gt;

&lt;p&gt;The backup stops hearing from the primary.&lt;/p&gt;

&lt;p&gt;What should it conclude?&lt;/p&gt;

&lt;p&gt;The primary might have crashed.&lt;/p&gt;

&lt;p&gt;Or the network between them might simply be broken.&lt;/p&gt;

&lt;p&gt;From the backup’s side, those situations can look painfully similar.&lt;/p&gt;

&lt;p&gt;Suppose the failover rule says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;If the primary disappears, become the new primary.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The backup promotes itself.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Excellent.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Except the original primary never crashed.&lt;/p&gt;

&lt;p&gt;It is still alive.&lt;br&gt;&lt;br&gt;
Some clients can still reach it.&lt;/p&gt;

&lt;p&gt;Other clients can reach the newly promoted backup.&lt;/p&gt;

&lt;p&gt;The old primary thinks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The backup is unreachable. I am still primary.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The backup thinks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The primary is dead. I am now primary.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Both conclusions are locally reasonable.&lt;/p&gt;

&lt;p&gt;Globally, they are disastrous.&lt;/p&gt;

&lt;p&gt;The system has developed a &lt;strong&gt;split brain&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Oracle’s clustering documentation describes the same failure pattern: after communication between cluster nodes is lost, separate partitions can each believe they are the valid cluster and continue operating independently.&lt;/p&gt;

&lt;p&gt;Our redundancy has produced two sources of authority.&lt;/p&gt;




&lt;h3&gt;
  
  
  Both Halves Can Be Correct and the Whole Can Still Be&amp;nbsp;Wrong
&lt;/h3&gt;

&lt;p&gt;Split brain is nasty because neither side needs to be malfunctioning internally.&lt;/p&gt;

&lt;p&gt;Imagine clients on the left continuing to write state through the original primary.&lt;/p&gt;

&lt;p&gt;Clients on the right write different state through the promoted backup.&lt;/p&gt;

&lt;p&gt;For a while, each half can look healthy.&lt;/p&gt;

&lt;p&gt;Requests arrive.&lt;br&gt;&lt;br&gt;
Responses go out.&lt;br&gt;&lt;br&gt;
Data changes.&lt;/p&gt;

&lt;p&gt;Nobody is necessarily throwing errors.&lt;/p&gt;

&lt;p&gt;That is what makes the condition dangerous.&lt;/p&gt;

&lt;p&gt;The problem is not that the machines stopped working.&lt;/p&gt;

&lt;p&gt;The problem is that &lt;strong&gt;agreement about who is allowed to speak for the system disappeared&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Suppose the service answers a question whose correctness depends on information from both sides.&lt;/p&gt;

&lt;p&gt;Each half can respond based on incomplete state.&lt;br&gt;&lt;br&gt;
Each response may be perfectly sensible from the local view.&lt;/p&gt;

&lt;p&gt;Together, those answers can violate the assumptions of the system above them.&lt;/p&gt;

&lt;p&gt;Split brain is CAP wearing a name tag.&lt;/p&gt;

&lt;p&gt;The partition created separate realities.&lt;/p&gt;

&lt;p&gt;Availability allowed those realities to continue making progress.&lt;/p&gt;

&lt;p&gt;Consistency became impossible unless one reality stopped making independent decisions.&lt;/p&gt;

&lt;p&gt;And now we can finally see what the solution really needs.&lt;/p&gt;

&lt;p&gt;Not better optimism.&lt;br&gt;&lt;br&gt;
Not another timeout.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agreement.&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Two Machines Cannot Resolve the Argument by Staring at Each&amp;nbsp;Other
&lt;/h3&gt;

&lt;p&gt;The obvious fix sounds easy:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Let the primary and backup decide which one is really alive.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Unfortunately, that is almost the problem we already had.&lt;/p&gt;

&lt;p&gt;If they can communicate reliably enough to make that decision together, they are not experiencing the partition we are trying to survive.&lt;/p&gt;

&lt;p&gt;During the partition:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Primary cannot see backup.&lt;br&gt;&lt;br&gt;
Backup cannot see primary.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Each one knows only:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I am alive, and the other side is not answering.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That does not reveal whether the other side is dead.&lt;/p&gt;

&lt;p&gt;Separate one-to-one decisions can therefore produce separate answers.&lt;/p&gt;

&lt;p&gt;So the system needs something beyond the two conflicting participants.&lt;/p&gt;

&lt;p&gt;One option is brutally simple:&lt;/p&gt;

&lt;p&gt;Use one server.&lt;/p&gt;

&lt;p&gt;If it fails, wait.&lt;/p&gt;

&lt;p&gt;Consistency becomes straightforward, but availability during the failure suffers.&lt;/p&gt;

&lt;p&gt;Another option is &lt;strong&gt;fencing&lt;/strong&gt;: when a backup takes over, ensure the old primary is physically or logically prevented from continuing to serve.&lt;/p&gt;

&lt;p&gt;If only one side is capable of acting, there cannot be two primaries.&lt;/p&gt;

&lt;p&gt;And another option is &lt;strong&gt;majority agreement&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now the partition must prove that it represents enough of the system before it is allowed to continue.&lt;/p&gt;

&lt;p&gt;This is where quorum enters the story.&lt;/p&gt;




&lt;h3&gt;
  
  
  Majority Does Something Clever With Authority
&lt;/h3&gt;

&lt;p&gt;Suppose there are enough voting members that one side of a partition contains 60 votes and another contains 40.&lt;/p&gt;

&lt;p&gt;Only the side with more than half is allowed to continue as the authoritative cluster.&lt;/p&gt;

&lt;p&gt;The other side may be alive.&lt;/p&gt;

&lt;p&gt;It may have healthy disks.&lt;br&gt;&lt;br&gt;
It may have clients begging for service.&lt;br&gt;&lt;br&gt;
It still stops.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because two disjoint groups cannot both possess a strict majority of the same electorate.&lt;/p&gt;

&lt;p&gt;That mathematical detail is doing the heavy lifting.&lt;/p&gt;

&lt;p&gt;It prevents two partitions from simultaneously claiming legitimate authority.&lt;/p&gt;

&lt;p&gt;Oracle Solaris Cluster uses this exact idea: a partition with a majority of votes obtains quorum and is allowed to operate, while partitions without quorum cannot continue as the cluster. The mechanism exists specifically to prevent split-brain operation.&lt;/p&gt;

&lt;p&gt;Notice what we paid for that guarantee.&lt;/p&gt;

&lt;p&gt;The minority side became unavailable.&lt;/p&gt;

&lt;p&gt;That is not an accidental flaw in the quorum mechanism.&lt;br&gt;&lt;br&gt;
That &lt;strong&gt;is the trade-off&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We deliberately sacrifice some availability because allowing both sides to continue would risk divergent state.&lt;/p&gt;

&lt;p&gt;The architecture stops looking pessimistic once the constraint is visible.&lt;/p&gt;

&lt;p&gt;A majority vote is not there because distributed-systems engineers enjoy making healthy servers shut themselves down.&lt;/p&gt;

&lt;p&gt;It is there because &lt;strong&gt;being alive is not the same thing as being authoritative&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Partitions Do Not Break Reality. They Break Shared&amp;nbsp;Reality.
&lt;/h3&gt;

&lt;p&gt;This is the part of CAP that feels more useful than memorizing the triangle.&lt;/p&gt;

&lt;p&gt;Before the partition, replicas can coordinate enough to present a common state.&lt;/p&gt;

&lt;p&gt;Then communication disappears.&lt;/p&gt;

&lt;p&gt;Each side continues observing its own local reality.&lt;/p&gt;

&lt;p&gt;From that moment, the system cannot magically know what is happening beyond the partition boundary.&lt;/p&gt;

&lt;p&gt;If both sides continue accepting conflicting updates, availability survives but immediate consistency cannot.&lt;/p&gt;

&lt;p&gt;If the system refuses operations until sufficient agreement exists, consistency survives but some requests cannot proceed.&lt;/p&gt;

&lt;p&gt;If users are allowed to work offline, their state may diverge temporarily and reconcile later.&lt;/p&gt;

&lt;p&gt;If two servers both decide they are primary, redundancy becomes split brain.&lt;/p&gt;

&lt;p&gt;If quorum grants authority to only one partition, the system stays coherent by deliberately silencing the other.&lt;/p&gt;

&lt;p&gt;Same underlying problem.&lt;/p&gt;

&lt;p&gt;Different manifestations.&lt;/p&gt;

&lt;p&gt;The network did not merely disconnect machines.&lt;/p&gt;

&lt;p&gt;It disconnected &lt;strong&gt;knowledge&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And once knowledge is separated, perfect consistency and perfect availability cannot both be promised as though nothing happened.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Choice Was Never Really About Three&amp;nbsp;Letters
&lt;/h3&gt;

&lt;p&gt;CAP is memorable because of C, A, and P.&lt;/p&gt;

&lt;p&gt;But the useful engineering lesson sits underneath them.&lt;/p&gt;

&lt;p&gt;Distributed systems create copies of state because copies are useful.&lt;/p&gt;

&lt;p&gt;They improve scalability.&lt;br&gt;&lt;br&gt;
They improve resilience.&lt;br&gt;&lt;br&gt;
They put computation and data closer to where they are needed.&lt;/p&gt;

&lt;p&gt;But every copy introduces another participant that must somehow remain aligned with the others.&lt;/p&gt;

&lt;p&gt;As long as communication works, synchronization can hide much of that complexity.&lt;/p&gt;

&lt;p&gt;A partition removes that luxury.&lt;/p&gt;

&lt;p&gt;Now the design has to reveal what it really values.&lt;/p&gt;

&lt;p&gt;Can stale state be tolerated?&lt;br&gt;&lt;br&gt;
Can conflicting updates be reconciled later?&lt;br&gt;&lt;br&gt;
Is there an invariant that must never be violated?&lt;br&gt;&lt;br&gt;
Can an operation safely stop?&lt;br&gt;&lt;br&gt;
Who has authority during disagreement?&lt;br&gt;&lt;br&gt;
How is that authority established?&lt;br&gt;&lt;br&gt;
What happens when communication returns?&lt;/p&gt;

&lt;p&gt;Those questions are far more useful than asking whether a database has an AP or CP sticker on the box.&lt;/p&gt;

&lt;p&gt;The hotel booking system did not fail because we added a second server.&lt;/p&gt;

&lt;p&gt;The backup did not become dangerous because redundancy was foolish.&lt;/p&gt;

&lt;p&gt;The offline file was not broken because two copies temporarily disagreed.&lt;/p&gt;

&lt;p&gt;Each design encountered the same underlying fact:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Independent machines cannot maintain one shared reality without communication, and communication itself is one of the things a distributed system cannot guarantee.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So the architecture adapts.&lt;/p&gt;

&lt;p&gt;Sometimes it waits.&lt;br&gt;&lt;br&gt;
Sometimes it refuses.&lt;br&gt;&lt;br&gt;
Sometimes it keeps going with stale state.&lt;br&gt;&lt;br&gt;
Sometimes it reconciles.&lt;br&gt;&lt;br&gt;
Sometimes it asks a majority who is still allowed to speak.&lt;br&gt;&lt;br&gt;
Sometimes it checks with The Origami Software Engineer.&lt;/p&gt;

&lt;p&gt;The network split reality in two.&lt;/p&gt;

&lt;p&gt;The system’s job was never to pretend that did not happen.&lt;/p&gt;

&lt;p&gt;It was to decide what correctness means when it does.&lt;/p&gt;

&lt;p&gt;That’s not failure.&lt;br&gt;
That’s evolution.&lt;/p&gt;




&lt;h3&gt;
  
  
  The “I liked this” Starter Pack:
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Don’t let your fingers get lazy now.
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Like :&lt;/strong&gt; It tells me this was worth writing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A Comment:&lt;/strong&gt; Tell me your thoughts, your favorite snack, or a better title for this blog.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Boost it:&lt;/strong&gt; Especially with that one developer who definitely needs this.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Thanks for being here. It genuinely helps more than you know!&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;— Aaroophan Varatharajan&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Find me elsewhere:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Professional stuff:&lt;/strong&gt; &lt;a href="http://linkedin.com/in/Aaroophan" rel="noopener noreferrer"&gt;linkedin.com/in/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code stuff:&lt;/strong&gt; &lt;a href="http://github.com/Aaroophan" rel="noopener noreferrer"&gt;github.com/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UI stuff:&lt;/strong&gt; &lt;a href="https://aaroophan.dev/Aaroophan" rel="noopener noreferrer"&gt;aaroophan.dev/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Life stuff:&lt;/strong&gt; &lt;a href="http://instagram.com/aaroophan" rel="noopener noreferrer"&gt;instagram.com/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>distributedcomputing</category>
      <category>computerscience</category>
      <category>softwareengineering</category>
      <category>systemdesignconcepts</category>
    </item>
    <item>
      <title>The Hard Part Was Finding the File: Rethinking Distributed Computing #2</title>
      <dc:creator>Aaroophan Varatharajan</dc:creator>
      <pubDate>Fri, 25 Sep 2026 19:47:03 +0000</pubDate>
      <link>https://dev.to/aaroophan/the-hard-part-was-finding-the-file-rethinking-distributed-computing-2-4j09</link>
      <guid>https://dev.to/aaroophan/the-hard-part-was-finding-the-file-rethinking-distributed-computing-2-4j09</guid>
      <description>&lt;h4&gt;
  
  
  &lt;em&gt;Decentralizing the files was easy. Decentralizing the answer to “where is the file?” was where things got interesting.&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh5o4ms075xttz8zq8mct.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh5o4ms075xttz8zq8mct.png" alt="How peer-to-peer systems evolved from Napster’s centralized directory and Gnutella’s query flooding to structured overlays, DHTs, and Chord’s logarithmic routing." width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"How peer-to-peer systems evolved from Napster’s centralized directory and Gnutella’s query flooding to structured overlays, DHTs, and Chord’s logarithmic routing."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Peer-to-peer file sharing begins with an idea that feels ✨&lt;strong&gt;&lt;em&gt;simple&lt;/em&gt;&lt;/strong&gt;✨&lt;/p&gt;

&lt;p&gt;Alice has a file.&lt;br&gt;&lt;br&gt;
Bob wants the file.&lt;/p&gt;

&lt;p&gt;Why place a giant server in the middle?&lt;br&gt;&lt;br&gt;
Let Bob download it directly from Alice.&lt;/p&gt;

&lt;p&gt;Better yet, let every participant behave as both &lt;strong&gt;client and server&lt;/strong&gt;. A peer can download resources from others while contributing its own resources back to the system. The machines sitting at the edges of the Internet stop being passive consumers and start becoming part of the infrastructure.&lt;/p&gt;

&lt;p&gt;That gives peer-to-peer systems much of their appeal.&lt;/p&gt;

&lt;p&gt;There is no need for one server to store every file. Storage grows as peers join. Network resources are contributed by the participants themselves. The system can potentially grow far beyond what one central machine could comfortably serve.&lt;/p&gt;

&lt;p&gt;So far, so good.&lt;/p&gt;

&lt;p&gt;Then Bob asks the question we quietly skipped:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Where is Alice?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;More precisely:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Which peer currently has the file I want?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And suddenly file transfer is no longer the interesting problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lookup is.&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Four Innocent Questions
&lt;/h3&gt;

&lt;p&gt;A peer-to-peer system has to answer four basic questions:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Join:&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;How do I begin participating?&lt;br&gt;&lt;br&gt;
_**_Publish:&lt;/em&gt;** &lt;em&gt;How do I advertise what I have?&lt;br&gt;&lt;br&gt;
_**_Search:&lt;/em&gt;** &lt;em&gt;How do I find what I want?&lt;br&gt;&lt;br&gt;
_**_Fetch:&lt;/em&gt;** &lt;em&gt;How do I retrieve it?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Fetch is almost comforting.&lt;/p&gt;

&lt;p&gt;Once Alice knows that Bob has the file and knows how to contact him, they can establish a direct connection and transfer it.&lt;/p&gt;

&lt;p&gt;The awkward work happens before that.&lt;/p&gt;

&lt;p&gt;Somewhere, somehow, the system must connect:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“The thing I want”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;to:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“The peer that currently has it”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is harder than it looks because peers are not dependable little servers sitting obediently in a data center.&lt;/p&gt;

&lt;p&gt;They join.&lt;br&gt;&lt;br&gt;
They leave.&lt;/p&gt;

&lt;p&gt;Their addresses can change.&lt;/p&gt;

&lt;p&gt;They may disappear without warning.&lt;/p&gt;

&lt;p&gt;Millions of resources may be spread across machines that know only a tiny fraction of the rest of the network.&lt;/p&gt;

&lt;p&gt;So we need a lookup mechanism.&lt;/p&gt;

&lt;p&gt;The first solution is exactly the one most of us would probably build.&lt;/p&gt;

&lt;p&gt;Put the answers somewhere.&lt;/p&gt;




&lt;h3&gt;
  
  
  Napster Keeps the&amp;nbsp;Map
&lt;/h3&gt;

&lt;p&gt;Napster’s architecture made a clever distinction.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;files remained on users’ machines&lt;/strong&gt;, but a centralized directory maintained information about which peers had which files. When a peer connected, it informed the central service about its address and available content. A search went to that directory; the resulting file transfer happened directly between peers. Stanford’s description of the original design similarly notes that the central servers stored information about shared files rather than the MP3 files themselves.&lt;/p&gt;

&lt;p&gt;This is a beautiful compromise.&lt;/p&gt;

&lt;p&gt;The expensive data is distributed.&lt;/p&gt;

&lt;p&gt;The knowledge about the data is centralized.&lt;/p&gt;

&lt;p&gt;Alice asks the directory:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Where is file A?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The directory replies:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Bob has it.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Alice talks directly to Bob.&lt;/p&gt;

&lt;p&gt;Lookup is wonderfully cheap from Alice’s point of view. The directory already knows the answer. Search scope is effectively constant rather than requiring Alice to wander around interrogating peers.&lt;/p&gt;

&lt;p&gt;And because the music files themselves are not moving through the directory server, it can concentrate on indexing and discovery.&lt;/p&gt;

&lt;p&gt;This works.&lt;br&gt;&lt;br&gt;
It works &lt;em&gt;really&lt;/em&gt; well.&lt;/p&gt;

&lt;p&gt;Which is why the trap matters.&lt;/p&gt;

&lt;p&gt;The directory has quietly become the one machine carrying the system’s collective knowledge.&lt;/p&gt;

&lt;p&gt;Every peer tells it what is available.&lt;br&gt;&lt;br&gt;
Every search depends on it.&lt;/p&gt;

&lt;p&gt;As the system grows, it maintains more state and handles more processing.&lt;/p&gt;

&lt;p&gt;And if that directory becomes unavailable, the files may still exist on thousands of machines while users lose the mechanism for finding them.&lt;/p&gt;

&lt;p&gt;That is a deeply cursed kind of availability:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;The data is everywhere. The map to the data is gone.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Napster decentralized storage without decentralizing discovery.&lt;/p&gt;

&lt;p&gt;The central directory was simple, efficient, and controllable.&lt;/p&gt;

&lt;p&gt;It was also a &lt;strong&gt;performance bottleneck&lt;/strong&gt; and a &lt;strong&gt;single point of failure&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So the next instinct seems obvious.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remove it.&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Gnutella Fires the Librarian
&lt;/h3&gt;

&lt;p&gt;Suppose we refuse to maintain a central directory.&lt;/p&gt;

&lt;p&gt;Now no machine knows where everything is.&lt;/p&gt;

&lt;p&gt;Fine.&lt;/p&gt;

&lt;p&gt;Alice can ask her neighbours.&lt;/p&gt;

&lt;p&gt;If one of them has the file, excellent.&lt;br&gt;&lt;br&gt;
If not, they can ask &lt;em&gt;their&lt;/em&gt; neighbours.&lt;/p&gt;

&lt;p&gt;And those neighbours can ask theirs.&lt;/p&gt;

&lt;p&gt;This is &lt;strong&gt;query flooding&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Gnutella embraced this decentralized model. A peer joins by finding existing peers and establishing connections. To search, it sends a query to its neighbours. They forward it onward, and matching peers return results. The Gnutella protocol describes every participant as both client and server, with queries propagated through the peer network rather than resolved by one central search server.&lt;/p&gt;

&lt;p&gt;We solved Napster’s uncomfortable dependency.&lt;/p&gt;

&lt;p&gt;There is no central directory.&lt;br&gt;&lt;br&gt;
There is no single server performing every lookup.&lt;/p&gt;

&lt;p&gt;Search processing is spread across the network.&lt;/p&gt;

&lt;p&gt;One peer disappears?&lt;/p&gt;

&lt;p&gt;The rest can continue.&lt;/p&gt;

&lt;p&gt;That feels properly peer-to-peer now.&lt;/p&gt;

&lt;p&gt;Until Alice searches for something.&lt;/p&gt;

&lt;p&gt;Her query goes to several neighbours.&lt;br&gt;&lt;br&gt;
They forward it.&lt;br&gt;&lt;br&gt;
Those peers forward it.&lt;br&gt;&lt;br&gt;
More peers see it.&lt;br&gt;&lt;br&gt;
More messages appear.&lt;/p&gt;

&lt;p&gt;The system has traded:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;One machine knowing too much&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;for:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Many machines being asked too much.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The lookup scope can approach &lt;strong&gt;O(N)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And peer-to-peer networks are exactly the kind of networks where &lt;code&gt;N&lt;/code&gt; is supposed to become enormous.&lt;/p&gt;

&lt;p&gt;Flooding is democratic.&lt;br&gt;&lt;br&gt;
It is also extremely enthusiastic.&lt;/p&gt;




&lt;h3&gt;
  
  
  Decentralization Did Not Make Search&amp;nbsp;Free
&lt;/h3&gt;

&lt;p&gt;This is where the intuition starts to break.&lt;/p&gt;

&lt;p&gt;Removing centralized control certainly removes a central bottleneck, but it does &lt;strong&gt;not&lt;/strong&gt; remove the work that the central service was doing.&lt;/p&gt;

&lt;p&gt;That work has to go somewhere.&lt;/p&gt;

&lt;p&gt;Gnutella distributes it.&lt;/p&gt;

&lt;p&gt;Every query recruits part of the network into finding an answer.&lt;/p&gt;

&lt;p&gt;That creates an ugly relationship between growth and search traffic. More peers give us more resources, but also a larger search space. Historical discussion of Gnutella’s design likewise noted that searching required queries to be forwarded across neighbouring nodes and became increasingly cumbersome as the network grew.&lt;/p&gt;

&lt;p&gt;We can limit the depth of flooding.&lt;br&gt;&lt;br&gt;
We can use random walks rather than shouting in every direction.&lt;/p&gt;

&lt;p&gt;Those reduce the blast radius.&lt;br&gt;&lt;br&gt;
But something deeper is still missing.&lt;/p&gt;

&lt;p&gt;The network has very little &lt;strong&gt;structure&lt;/strong&gt; connecting a resource to its location.&lt;/p&gt;

&lt;p&gt;If Alice asks for file A, there is no inherent reason that the query should travel toward one particular part of the network.&lt;/p&gt;

&lt;p&gt;The network does not know where to look.&lt;/p&gt;

&lt;p&gt;It only knows whom it can ask.&lt;/p&gt;

&lt;p&gt;That difference turns out to be enormous.&lt;/p&gt;




&lt;h3&gt;
  
  
  Maybe All Peers Shouldn’t Be&amp;nbsp;Equal
&lt;/h3&gt;

&lt;p&gt;There is another uncomfortable observation.&lt;/p&gt;

&lt;p&gt;Peer-to-peer systems like to say &lt;em&gt;peer&lt;/em&gt; as if every participant were equivalent.&lt;/p&gt;

&lt;p&gt;Reality is less polite.&lt;/p&gt;

&lt;p&gt;One peer may have a fast connection and remain online for days.&lt;/p&gt;

&lt;p&gt;Another may have limited bandwidth and disappear five minutes later.&lt;/p&gt;

&lt;p&gt;Treating them identically has egalitarian vibes, but not necessarily good systems design.&lt;/p&gt;

&lt;p&gt;So systems such as KaZaA moved toward &lt;strong&gt;hierarchical query flooding&lt;/strong&gt; using &lt;strong&gt;supernodes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Ordinary peers connect to a supernode and publish information about their files there. A search first goes to the local supernode. If the answer is elsewhere, supernodes communicate with other supernodes.&lt;/p&gt;

&lt;p&gt;This is interesting because we have partially reintroduced what we just removed.&lt;/p&gt;

&lt;p&gt;Not one global central directory.&lt;/p&gt;

&lt;p&gt;But not perfect flat decentralization either.&lt;/p&gt;

&lt;p&gt;A hierarchy appears.&lt;/p&gt;

&lt;p&gt;Some peers take on greater responsibility because some peers are simply better positioned to do so.&lt;/p&gt;

&lt;p&gt;Search now happens among a smaller set of capable nodes instead of blindly involving everybody.&lt;/p&gt;

&lt;p&gt;We have learned something slightly annoying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Removing hierarchy is not the same thing as removing bottlenecks.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sometimes hierarchy is useful.&lt;/p&gt;

&lt;p&gt;The question is where to put it and how much of it to trust.&lt;/p&gt;




&lt;h3&gt;
  
  
  We Keep Trying to Search&amp;nbsp;Better
&lt;/h3&gt;

&lt;p&gt;Other peer-to-peer designs push the problem in different directions.&lt;/p&gt;

&lt;p&gt;BitTorrent, for example, makes &lt;strong&gt;swarming&lt;/strong&gt; the star of the show. Once the participants in a swarm are known, different pieces can be retrieved from different peers rather than treating one peer as the complete source.&lt;/p&gt;

&lt;p&gt;Unstructured overlay systems such as Freenet take another route. Instead of simply flooding every query, peers use information gathered from previous requests to make better routing decisions.&lt;/p&gt;

&lt;p&gt;Now the network has started learning.&lt;/p&gt;

&lt;p&gt;A request is not necessarily broadcast blindly. It can be forwarded toward a peer that seems more promising.&lt;/p&gt;

&lt;p&gt;That is progress.&lt;/p&gt;

&lt;p&gt;But the routing remains &lt;strong&gt;unstructured&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The knowledge is heuristic rather than deriving from a global relationship between a resource identifier and a particular place in the overlay.&lt;/p&gt;

&lt;p&gt;A query can become smarter without becoming predictable.&lt;/p&gt;

&lt;p&gt;And predictability matters when the system is supposed to operate at global scale.&lt;/p&gt;

&lt;p&gt;We would really like to say something stronger than:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Hopefully the search goes somewhere useful.”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We want bounds.&lt;br&gt;&lt;br&gt;
We want guarantees.&lt;br&gt;&lt;br&gt;
We want a way to know that adding another million peers does not turn every lookup into a million-message group chat.&lt;/p&gt;

&lt;p&gt;So the problem changes again.&lt;/p&gt;

&lt;p&gt;Maybe we should stop asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;How do we search the network?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Can we organize the network so the resource itself tells us where to route?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is the pivot.&lt;/p&gt;




&lt;h3&gt;
  
  
  Stop Searching. Start&amp;nbsp;Routing.
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;Distributed Hash Table&lt;/strong&gt;, or DHT, changes the abstraction.&lt;/p&gt;

&lt;p&gt;Think of an ordinary hash table.&lt;/p&gt;

&lt;p&gt;Give it a key.&lt;/p&gt;

&lt;p&gt;Get a value.&lt;/p&gt;

&lt;p&gt;A DHT tries to provide a similar abstraction while the table itself is spread across many independent machines.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;put(key, value)&lt;br&gt;&lt;br&gt;
get(key)&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The clever part is that keys and peers are placed into an identifier space according to defined rules.&lt;/p&gt;

&lt;p&gt;Now a resource does not merely have a name that somebody must search.&lt;/p&gt;

&lt;p&gt;It has an identifier that determines which part of the distributed system is responsible for it.&lt;/p&gt;

&lt;p&gt;The lookup problem has become a &lt;strong&gt;routing problem&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;That changes everything.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Instead of asking arbitrary peers whether they happen to know where a resource lives, the overlay can progressively route a request toward the peer associated with the key.&lt;/p&gt;

&lt;p&gt;This is &lt;strong&gt;structured overlay routing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Systems such as Pastry assign identifiers to nodes and objects and use routing tables to move requests toward progressively closer identifiers. The structure lets lookup complete in a bounded number of routing hops rather than relying on network-wide flooding.&lt;/p&gt;

&lt;p&gt;Structure costs something.&lt;/p&gt;

&lt;p&gt;Peers must maintain routing information.&lt;/p&gt;

&lt;p&gt;Membership changes must be handled.&lt;/p&gt;

&lt;p&gt;The mapping between objects and nodes has to remain usable while machines join and leave.&lt;/p&gt;

&lt;p&gt;But now the cost buys us something flooding never really gave us: &lt;strong&gt;Predictability.&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Chord Puts Everyone on a&amp;nbsp;Ring
&lt;/h3&gt;

&lt;p&gt;Chord gives this idea an unusually clean shape.&lt;/p&gt;

&lt;p&gt;A hash function is used to produce identifiers for both &lt;strong&gt;keys&lt;/strong&gt; and &lt;strong&gt;nodes&lt;/strong&gt;. Those identifiers occupy the same circular identifier space.&lt;/p&gt;

&lt;p&gt;Think of the numbers arranged around a ring.&lt;/p&gt;

&lt;p&gt;A key is assigned to its &lt;strong&gt;successor&lt;/strong&gt;: The first node whose identifier is equal to or follows the key’s identifier around that ring.&lt;/p&gt;

&lt;p&gt;So if the desired object hashes to key &lt;code&gt;**60**&lt;/code&gt;, the system does not ask every peer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Does anyone have 60?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;The identifier space already tells us which node should be responsible for 60.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Chord’s fundamental service is deliberately narrow: given a key, map that key to a node. Its authors describe efficient data location as the core P2P problem, and Chord solves it by providing this distributed key-to-node mapping while adapting as nodes join and leave.&lt;/p&gt;

&lt;p&gt;That sounds like the problem is solved.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Almost.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Because knowing &lt;em&gt;which identifier should own the key&lt;/em&gt; is not the same as knowing &lt;em&gt;how to contact that node efficiently&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;And this is where Chord becomes a lovely little exercise in engineering trade-offs.&lt;/p&gt;




&lt;h3&gt;
  
  
  Knowing Everyone Is Too Expensive
&lt;/h3&gt;

&lt;p&gt;Suppose every Chord node keeps the address of &lt;strong&gt;every other node&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Lookup becomes easy.&lt;/p&gt;

&lt;p&gt;Hash the key.&lt;br&gt;&lt;br&gt;
Find its responsible node in the local routing table.&lt;br&gt;&lt;br&gt;
Contact that node directly.&lt;br&gt;&lt;br&gt;
One network hop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Lovely.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Except every peer now maintains &lt;strong&gt;O(N) routing state&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We have recreated a global-knowledge problem inside every machine.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Fine.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Go to the opposite extreme.&lt;br&gt;&lt;br&gt;
Each node knows only its immediate successor on the ring.&lt;br&gt;&lt;br&gt;
Routing state becomes tiny.&lt;/p&gt;

&lt;p&gt;But now finding a distant key means walking successor by successor around the ring.&lt;/p&gt;

&lt;p&gt;Lookup can require &lt;strong&gt;O(N) messages&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Wonderful.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We have two solutions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Know everybody and route quickly;&lt;/li&gt;
&lt;li&gt;  Know almost nobody and route slowly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Neither feels like the scalable answer we wanted.&lt;/p&gt;

&lt;p&gt;The interesting question is whether there is something between &lt;strong&gt;everything&lt;/strong&gt; and &lt;strong&gt;almost nothing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;There &lt;strong&gt;&lt;em&gt;is&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Finger Table Knows Just&amp;nbsp;Enough
&lt;/h3&gt;

&lt;p&gt;Chord gives each node a &lt;strong&gt;finger table&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of remembering every other peer, a node keeps references at exponentially increasing distances around the identifier ring.&lt;/p&gt;

&lt;p&gt;Roughly speaking, it knows someone nearby.&lt;/p&gt;

&lt;p&gt;Then someone farther away.&lt;br&gt;&lt;br&gt;
Then much farther away.&lt;br&gt;&lt;br&gt;
Then farther again.&lt;/p&gt;

&lt;p&gt;The routing table is not trying to know the whole world.&lt;/p&gt;

&lt;p&gt;It is trying to know enough strategically positioned parts of the world to make progress quickly.&lt;/p&gt;

&lt;p&gt;Suppose the desired key is far away.&lt;/p&gt;

&lt;p&gt;The current peer chooses the finger that moves the request closest toward that key without overshooting the useful region.&lt;/p&gt;

&lt;p&gt;The next peer does the same.&lt;br&gt;&lt;br&gt;
Then the next.&lt;/p&gt;

&lt;p&gt;Each hop can remove a large portion of the remaining identifier-space distance.&lt;/p&gt;

&lt;p&gt;It has the feeling of binary search, except the search is being performed through messages between independent computers.&lt;/p&gt;

&lt;p&gt;Now the trade-off becomes much nicer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O(log N) routing state per node.&lt;br&gt;&lt;br&gt;
O(log N) messages per lookup.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Chord analysis shows exactly this logarithmic scaling of both communication cost and per-node state.&lt;/p&gt;

&lt;p&gt;That is the moment the architecture stops looking clever for cleverness’ sake.&lt;/p&gt;

&lt;p&gt;Finger tables exist because the two obvious alternatives forced us there.&lt;/p&gt;

&lt;p&gt;Global knowledge was too expensive.&lt;br&gt;&lt;br&gt;
Successor-only knowledge was too slow.&lt;/p&gt;

&lt;p&gt;So each peer remembers &lt;strong&gt;just enough structure to cut the search space down quickly&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The solution feels &lt;strong&gt;&lt;em&gt;earned&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Network Finally Knows Where to&amp;nbsp;Look
&lt;/h3&gt;

&lt;p&gt;Look back at the journey.&lt;/p&gt;

&lt;p&gt;Napster said:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Ask the machine that knows everything.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Fast.&lt;br&gt;&lt;br&gt;
Simple.&lt;br&gt;&lt;br&gt;
Also centralized.&lt;/p&gt;

&lt;p&gt;Gnutella said:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;If nobody knows everything, ask everybody you can reach.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Decentralized.&lt;br&gt;&lt;br&gt;
Resilient to losing one directory.&lt;br&gt;&lt;br&gt;
Also expensive.&lt;/p&gt;

&lt;p&gt;Hierarchical approaches said:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Maybe ask the better-connected peers first.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;More practical.&lt;br&gt;&lt;br&gt;
But still based heavily on distributed search.&lt;/p&gt;

&lt;p&gt;Unstructured routing said:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Use what the network has learned to make better guesses.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Smarter.&lt;br&gt;&lt;br&gt;
But without strong lookup bounds.&lt;/p&gt;

&lt;p&gt;Then DHTs changed the shape of the problem:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Give resources and peers structure, then route toward responsibility.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Chord pushes that idea into a ring and gives every node just enough routing state to move efficiently through it.&lt;/p&gt;

&lt;p&gt;We did not discover one universally perfect peer-to-peer architecture.&lt;/p&gt;

&lt;p&gt;We kept changing the organization because each previous organization exposed a different cost.&lt;/p&gt;

&lt;p&gt;Centralized knowledge created a bottleneck.&lt;/p&gt;

&lt;p&gt;Removing the center created flooding.&lt;/p&gt;

&lt;p&gt;Treating all peers equally ignored heterogeneity.&lt;/p&gt;

&lt;p&gt;Unstructured routing lacked strong guarantees.&lt;/p&gt;

&lt;p&gt;Maintaining complete routing knowledge would not scale.&lt;/p&gt;

&lt;p&gt;Maintaining almost none would make lookup crawl.&lt;/p&gt;

&lt;p&gt;The design kept moving because the lookup problem kept refusing to disappear.&lt;/p&gt;




&lt;h3&gt;
  
  
  Structure Is Not the Enemy of Decentralization
&lt;/h3&gt;

&lt;p&gt;There is a broader lesson hiding in all of this.&lt;/p&gt;

&lt;p&gt;It is easy to associate decentralization with the absence of structure.&lt;/p&gt;

&lt;p&gt;No central server.&lt;br&gt;&lt;br&gt;
No hierarchy.&lt;br&gt;&lt;br&gt;
No authority.&lt;/p&gt;

&lt;p&gt;Everyone equal.&lt;br&gt;&lt;br&gt;
Ask anyone.&lt;br&gt;&lt;br&gt;
Route anywhere.&lt;/p&gt;

&lt;p&gt;That sounds &lt;em&gt;beautifully&lt;/em&gt; distributed.&lt;/p&gt;

&lt;p&gt;The Origami Software Engineer noted,&lt;br&gt;&lt;br&gt;
it also turns out to be &lt;strong&gt;a poor guarantee&lt;/strong&gt; that the system will scale.&lt;/p&gt;

&lt;p&gt;Peer-to-peer systems still need organization.&lt;/p&gt;

&lt;p&gt;They need rules for &lt;strong&gt;joining&lt;/strong&gt;, &lt;strong&gt;publishing&lt;/strong&gt;, &lt;strong&gt;searching&lt;/strong&gt;, and &lt;strong&gt;fetching&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
They need to cope with machines constantly appearing and disappearing.&lt;br&gt;&lt;br&gt;
They need to balance load.&lt;br&gt;&lt;br&gt;
They need to avoid assuming every node has equal capacity.&lt;/p&gt;

&lt;p&gt;And once they become large, they need lookup mechanisms whose cost does not grow disastrously with the population.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The useful distinction is not:&lt;/em&gt; &lt;strong&gt;_Centralized vs Structured.&lt;br&gt;&lt;br&gt;
_&lt;/strong&gt;&lt;em&gt;It is:&lt;/em&gt; &lt;strong&gt;&lt;em&gt;Centralized Authority vs Distributed Structure.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Chord has structure everywhere.&lt;/p&gt;

&lt;p&gt;The identifier space is structured.&lt;br&gt;&lt;br&gt;
Resource placement is structured.&lt;br&gt;&lt;br&gt;
Routing state is structured.&lt;br&gt;&lt;br&gt;
Lookup is structured.&lt;/p&gt;

&lt;p&gt;Yet no single directory needs to know the entire network.&lt;/p&gt;

&lt;p&gt;That is the evolution worth remembering.&lt;/p&gt;

&lt;p&gt;We began by putting the map on one server.&lt;br&gt;&lt;br&gt;
Then we threw the map away and shouted.&lt;br&gt;&lt;br&gt;
Then we built partial maps.&lt;/p&gt;

&lt;p&gt;Eventually, we stopped treating discovery as an uncontrolled search and designed the network so that the destination could be approached systematically.&lt;/p&gt;

&lt;p&gt;The files were never the hardest part.&lt;/p&gt;

&lt;p&gt;Knowing where to look was.&lt;/p&gt;

&lt;p&gt;That’s not failure.&lt;br&gt;&lt;br&gt;
That’s evolution.&lt;/p&gt;




&lt;h3&gt;
  
  
  The “I liked this” Starter Pack:
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Don’t let your fingers get lazy now.
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Like :&lt;/strong&gt; It tells me this was worth writing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A Comment:&lt;/strong&gt; Tell me your thoughts, your favorite snack, or a better title for this blog.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Boost it:&lt;/strong&gt; Especially with that one developer who definitely needs this.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Thanks for being here. It genuinely helps more than you know!&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Find me elsewhere:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Professional stuff:&lt;/strong&gt; &lt;a href="http://linkedin.com/in/Aaroophan" rel="noopener noreferrer"&gt;linkedin.com/in/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code stuff:&lt;/strong&gt; &lt;a href="http://github.com/Aaroophan" rel="noopener noreferrer"&gt;github.com/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UI stuff:&lt;/strong&gt; &lt;a href="https://aaroophan.dev/Aaroophan" rel="noopener noreferrer"&gt;aaroophan.dev/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Life stuff:&lt;/strong&gt; &lt;a href="http://instagram.com/aaroophan" rel="noopener noreferrer"&gt;instagram.com/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>distributedcomputing</category>
      <category>computerscience</category>
      <category>softwareengineering</category>
      <category>systemdesignconcepts</category>
    </item>
    <item>
      <title>The One-Computer Illusion: Rethinking Distributed Computing</title>
      <dc:creator>Aaroophan Varatharajan</dc:creator>
      <pubDate>Fri, 25 Sep 2026 19:32:36 +0000</pubDate>
      <link>https://dev.to/aaroophan/the-one-computer-illusion-rethinking-distributed-computing-58bp</link>
      <guid>https://dev.to/aaroophan/the-one-computer-illusion-rethinking-distributed-computing-58bp</guid>
      <description>&lt;h4&gt;
  
  
  &lt;em&gt;Why making many independent computers behave like one coherent system is where the trouble actually&amp;nbsp;begins.&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F06344jedydndnwofud3b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F06344jedydndnwofud3b.png" alt="Explore how independent machines, networks, concurrency, partial failures, clocks, transparency, and coordination turn “just add more computers” into a fundamentally different engineering problem" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
"Explore how independent machines, networks, concurrency, partial failures, clocks, transparency, and coordination turn “just add more computers” into a fundamentally different engineering problem"&lt;/p&gt;

&lt;p&gt;Suppose a system needs more processing power, more storage, better availability, or simply needs to serve more people.&lt;/p&gt;

&lt;p&gt;The obvious instinct is: ✨&lt;strong&gt;&lt;em&gt;Add machines&lt;/em&gt;&lt;/strong&gt;✨&lt;/p&gt;

&lt;p&gt;That sounds almost &lt;em&gt;embarrassingly&lt;/em&gt; straightforward. One computer is doing too much work, so give it friends. Divide the workload. Share the resources. Keep going as demand grows.&lt;/p&gt;

&lt;p&gt;And there are plenty of reasons to do exactly that. Some problems are inherently distributed. Some become too large for a single machine. Systems need to scale, remain available when components fail, share resources, serve geographically distributed users, and evolve without replacing everything at once.&lt;/p&gt;

&lt;p&gt;So we add another computer.&lt;br&gt;&lt;br&gt;
Then another.&lt;br&gt;&lt;br&gt;
Then a hundred.&lt;/p&gt;

&lt;p&gt;The trap is subtle: Somewhere during that progression, it is very easy to keep reasoning as though we still have &lt;strong&gt;&lt;em&gt;one computer, just bigger&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We do not.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A parallel system may have many processors while remaining tightly coupled around shared resources. A distributed system gives us something fundamentally less comfortable: &lt;strong&gt;Independent Computers&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Each has its own processor.&lt;br&gt;&lt;br&gt;
Its own memory.&lt;br&gt;&lt;br&gt;
Its own execution.&lt;br&gt;&lt;br&gt;
Its own problems.&lt;/p&gt;

&lt;p&gt;And if one machine needs something held by another, it cannot simply reach into the other machine’s memory.&lt;/p&gt;

&lt;p&gt;It has to ask.&lt;br&gt;&lt;br&gt;
Through a message.&lt;br&gt;&lt;br&gt;
Across a network.&lt;/p&gt;

&lt;p&gt;That tiny change is where the vibes start getting &lt;em&gt;cursed&lt;/em&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  So We Make Them Pretend to Be&amp;nbsp;One
&lt;/h3&gt;

&lt;p&gt;There is a wonderfully ambitious definition of a distributed system: A collection of autonomous or independent computers that appears to its users as a &lt;strong&gt;single coherent system&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Read both halves carefully.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Independent computers.&lt;br&gt;&lt;br&gt;
Single coherent system.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Those ideas are almost fighting each other.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The machines are autonomous, yet we want the user to experience coherence. They may run different hardware, operating systems, software, and protocols, yet the interaction should feel consistent. They communicate by passing messages, yet we want applications to behave as though the machinery underneath is one dependable whole.&lt;/p&gt;

&lt;p&gt;That gives us one of the central design goals: &lt;strong&gt;Single System View&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The user should not have to care which machine stores an object, which server answers a request, which replica is currently active, or which node disappeared five seconds ago.&lt;/p&gt;

&lt;p&gt;Ideally, the system handles that mess.&lt;br&gt;&lt;br&gt;
The user sees one thing.&lt;/p&gt;

&lt;p&gt;The distributed system quietly negotiates reality underneath.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Beautiful.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Except the machines have not stopped being independent just because we hid them behind a nice interface.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Network Gets a&amp;nbsp;Vote
&lt;/h3&gt;

&lt;p&gt;On one machine, communication between components can rely on mechanisms built around shared local resources.&lt;/p&gt;

&lt;p&gt;Across independent computers, coordination happens through &lt;strong&gt;message passing&lt;/strong&gt;. Coulouris’ characterization makes this constraint explicit, and with it come three consequences that keep resurfacing throughout distributed computing: &lt;strong&gt;concurrency, independent failures, and the lack of a global clock.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now consider what our innocent abstraction has inherited.&lt;/p&gt;

&lt;p&gt;The network might be slow.&lt;br&gt;&lt;br&gt;
A message might be delayed.&lt;br&gt;&lt;br&gt;
Communication has latency.&lt;br&gt;&lt;br&gt;
Bandwidth is not infinite.&lt;br&gt;&lt;br&gt;
Topology can change.&lt;br&gt;&lt;br&gt;
Different machines can be running different technologies.&lt;br&gt;&lt;br&gt;
And the network itself can fail.&lt;/p&gt;

&lt;p&gt;These facts sound painfully obvious when written down. Yet many distributed designs become fragile precisely because they quietly assume the opposite:&lt;/p&gt;

&lt;p&gt;The network is reliable.&lt;br&gt;&lt;br&gt;
Latency is zero.&lt;br&gt;&lt;br&gt;
Bandwidth is infinite.&lt;br&gt;&lt;br&gt;
Transport is free.&lt;br&gt;&lt;br&gt;
The network is secure.&lt;br&gt;&lt;br&gt;
Topology does not change.&lt;br&gt;&lt;br&gt;
There is one administrator.&lt;br&gt;&lt;br&gt;
The infrastructure is homogeneous.&lt;/p&gt;

&lt;p&gt;Each assumption makes the system feel a little more like one computer.&lt;br&gt;&lt;br&gt;
Each assumption is also something reality is free to revoke.&lt;/p&gt;

&lt;p&gt;The abstraction is not necessarily lying to us.&lt;br&gt;&lt;br&gt;
But it is definitely leaving out some terms and conditions.&lt;/p&gt;




&lt;h3&gt;
  
  
  There Is No Single&amp;nbsp;“&lt;strong&gt;&lt;em&gt;Now&lt;/em&gt;&lt;/strong&gt;”
&lt;/h3&gt;

&lt;p&gt;The machines are also doing things &lt;strong&gt;concurrently&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Process &lt;strong&gt;A&lt;/strong&gt; may execute while Process &lt;strong&gt;B&lt;/strong&gt; executes somewhere else. They progress independently, exchanging messages only when coordination requires it.&lt;/p&gt;

&lt;p&gt;This sounds manageable until we ask a very ordinary question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;What is the current state of the system?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;On a single machine, that question already has nuances.&lt;/p&gt;

&lt;p&gt;Across independent computers, it becomes much nastier.&lt;/p&gt;

&lt;p&gt;There is typically no process holding perfectly current knowledge of everything happening everywhere. While one node learns that something changed, another node may already have changed again. Messages carrying that information take time to arrive.&lt;/p&gt;

&lt;p&gt;There is no convenient global memory containing “&lt;em&gt;the state&lt;/em&gt;”.&lt;/p&gt;

&lt;p&gt;There is also no perfectly shared global clock quietly settling every argument about which event happened first.&lt;/p&gt;

&lt;p&gt;Each computer has a local clock, and clocks do not advance in perfect agreement. Interaction models therefore have to reason explicitly about timing, communication delays, and the difference between synchronous and asynchronous assumptions.&lt;/p&gt;

&lt;p&gt;So the system we wanted to behave like one computer cannot casually rely on two things a one-computer mental model makes very seductive:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One authoritative global state&lt;br&gt;&lt;br&gt;
**and&lt;br&gt;&lt;br&gt;
**One authoritative global time&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is where the illusion starts demanding real engineering.&lt;/p&gt;




&lt;h3&gt;
  
  
  Even Failure Stops Being&amp;nbsp;Simple
&lt;/h3&gt;

&lt;p&gt;Then something breaks.&lt;/p&gt;

&lt;p&gt;On a centralized system, a catastrophic machine failure is at least brutally clear: &lt;strong&gt;The machine is down&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Distributed systems introduce a stranger condition.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Partial failure.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One component can fail while the rest of the system continues running.&lt;/p&gt;

&lt;p&gt;A process crashes.&lt;/p&gt;

&lt;p&gt;Another process is fine.&lt;/p&gt;

&lt;p&gt;A network link disappears.&lt;/p&gt;

&lt;p&gt;Two healthy machines become unable to communicate.&lt;/p&gt;

&lt;p&gt;A message is sent but never arrives.&lt;/p&gt;

&lt;p&gt;And, wonderfully, the surviving processes may not immediately know what happened.&lt;/p&gt;

&lt;p&gt;That last part matters.&lt;/p&gt;

&lt;p&gt;A remote machine that has crashed can look suspiciously similar to a remote machine that is simply taking a long time to respond.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The system is no longer choosing between: Working&lt;/em&gt; or &lt;em&gt;Broken&lt;br&gt;&lt;br&gt;
It can be Working&lt;/em&gt; &lt;strong&gt;and&lt;/strong&gt; &lt;em&gt;Broken at the same time.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is why distributed systems need explicit failure models: omission failures, communication failures, arbitrary failures, timing failures, and mechanisms for detecting, masking, tolerating, or recovering from them.&lt;/p&gt;

&lt;p&gt;Fault tolerance exists because adding machines did not merely add resources.&lt;/p&gt;

&lt;p&gt;It added &lt;strong&gt;independent failure boundaries&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Fine. Hide All of&amp;nbsp;It.
&lt;/h3&gt;

&lt;p&gt;At this point the natural reaction is almost defensive.&lt;/p&gt;

&lt;p&gt;If distribution is causing all this complexity, hide the distribution.&lt;/p&gt;

&lt;p&gt;That is &lt;strong&gt;transparency&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Make local and remote resources look alike through &lt;strong&gt;access transparency&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let users access resources without knowing their physical location through &lt;strong&gt;location transparency&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Hide replication so multiple copies appear to be one resource.&lt;/p&gt;

&lt;p&gt;Allow resources to move without breaking applications.&lt;/p&gt;

&lt;p&gt;Hide concurrency where possible.&lt;/p&gt;

&lt;p&gt;Mask failures so a failed component does not automatically become the user’s problem.&lt;/p&gt;

&lt;p&gt;Even allow the system to scale or reconfigure without forcing applications to change.&lt;/p&gt;

&lt;p&gt;This is how those independent computers begin to recover the illusion of one coherent machine.&lt;/p&gt;

&lt;p&gt;And transparency is incredibly useful.&lt;/p&gt;

&lt;p&gt;But there is a trap inside the solution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;More transparency is not automatically better.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Trying to hide every aspect of distribution can hurt performance or conceal behavior that applications genuinely need to understand. Research and classic treatments of distributed systems likewise describe distribution transparency as a major goal while recognizing that locality and distributed-system complexity cannot simply be wished away.&lt;/p&gt;

&lt;p&gt;A remote operation still crosses a network even if its API looks local.&lt;br&gt;&lt;br&gt;
A retry still costs time even if failure recovery is invisible.&lt;br&gt;&lt;br&gt;
A replicated resource still needs coordination even if users see only one logical object.&lt;/p&gt;

&lt;p&gt;Transparency can hide complexity from the interface.&lt;br&gt;&lt;br&gt;
It cannot repeal the mechanisms underneath it.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Illusion Gets Surprisingly Expensive
&lt;/h3&gt;

&lt;p&gt;Now the original plan looks different.&lt;/p&gt;

&lt;p&gt;We added machines for &lt;strong&gt;scalability&lt;/strong&gt;, but centralized services, centralized data, and centralized algorithms can become bottlenecks as the system grows.&lt;/p&gt;

&lt;p&gt;We wanted &lt;strong&gt;availability&lt;/strong&gt;, but partial failures mean the system must detect, mask, tolerate, and recover from faults.&lt;/p&gt;

&lt;p&gt;We wanted one &lt;strong&gt;Single System View&lt;/strong&gt;, but concurrency and message passing mean nobody automatically owns the current global state.&lt;/p&gt;

&lt;p&gt;We wanted &lt;strong&gt;transparency&lt;/strong&gt;, but excessive transparency can fight performance.&lt;/p&gt;

&lt;p&gt;We wanted an extensible system, but growth introduces &lt;strong&gt;heterogeneity&lt;/strong&gt; across hardware, software, middleware, protocols, locations, and administrators.&lt;/p&gt;

&lt;p&gt;This does not mean distribution was a mistake.&lt;/p&gt;

&lt;p&gt;It means our first mental model was incomplete.&lt;/p&gt;

&lt;p&gt;The machines were never pieces of one physical computer.&lt;/p&gt;

&lt;p&gt;They were autonomous participants being persuaded to cooperate.&lt;/p&gt;




&lt;h3&gt;
  
  
  Model the System We Actually&amp;nbsp;Have
&lt;/h3&gt;

&lt;p&gt;Once that is accepted, the design starts looking less mysterious.&lt;/p&gt;

&lt;p&gt;Instead of reasoning vaguely about “&lt;em&gt;the system&lt;/em&gt;”, we can model different parts of the problem explicitly.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;physical model&lt;/strong&gt; asks what computers and devices exist and how they are interconnected.&lt;/p&gt;

&lt;p&gt;An &lt;strong&gt;architectural model&lt;/strong&gt; asks which entities communicate, how they communicate, what roles they have, and where they are placed. Client-server and peer-to-peer structures become architectural choices rather than incidental diagrams.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;fundamental model&lt;/strong&gt; goes deeper into assumptions that affect almost every design: How processes interact, How timing behaves, How components can fail, and What security threats exist. Coulouris’ framework explicitly uses architectural and fundamental models to reason about properties such as performance, reliability, scalability, interaction, and failure.&lt;/p&gt;

&lt;p&gt;This is the useful shift.&lt;/p&gt;

&lt;p&gt;We stop asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;How do we make these machines behave exactly like one computer?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And start asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Which differences must we hide, which must we manage, and which must the design acknowledge?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now message passing makes sense.&lt;br&gt;&lt;br&gt;
Fault tolerance makes sense.&lt;br&gt;&lt;br&gt;
Replication makes sense.&lt;br&gt;&lt;br&gt;
Caching makes sense.&lt;br&gt;&lt;br&gt;
Different architectural roles make sense.&lt;br&gt;&lt;br&gt;
Even the awkward edge cases make sense.&lt;/p&gt;

&lt;p&gt;They are not random complications bolted onto an otherwise simple system.&lt;/p&gt;

&lt;p&gt;They are consequences of asking autonomous computers to cooperate while presenting something coherent above them.&lt;/p&gt;




&lt;h3&gt;
  
  
  One System, Carefully Negotiated
&lt;/h3&gt;

&lt;p&gt;The magic of a distributed system is not that many computers somehow become one computer.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;They never do.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;They remain independent machines, executing concurrently, communicating through messages, observing only pieces of global reality, running on imperfect clocks, and sometimes failing without permission from the rest of the system.&lt;/p&gt;

&lt;p&gt;The achievement is that, despite all of that, The Origami Software Engineer can design enough communication, coordination, replication, fault tolerance, transparency, and structure that a user can often interact with the whole thing as though it were one coherent system.&lt;/p&gt;

&lt;p&gt;That distinction matters.&lt;/p&gt;

&lt;p&gt;Because once we stop believing the illusion literally, distributed-system design becomes easier to reason about.&lt;/p&gt;

&lt;p&gt;The network is not an implementation detail.&lt;/p&gt;

&lt;p&gt;Failure is not exceptional.&lt;br&gt;&lt;br&gt;
Global knowledge is not free.&lt;br&gt;&lt;br&gt;
Transparency is not magic.&lt;br&gt;&lt;br&gt;
And coherence is not something multiple machines naturally possess.&lt;/p&gt;

&lt;p&gt;It is something the system has to continuously create.&lt;/p&gt;

&lt;p&gt;We started by adding computers because one machine was no longer enough.&lt;/p&gt;

&lt;p&gt;Then we discovered that every new independent machine also added another piece of reality that had to be coordinated.&lt;/p&gt;

&lt;p&gt;That’s not failure.&lt;br&gt;&lt;br&gt;
That’s evolution.&lt;/p&gt;




&lt;h3&gt;
  
  
  The “I liked this” Starter Pack:
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Don’t let your fingers get lazy now.
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Like :&lt;/strong&gt; It tells me this was worth writing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A Comment:&lt;/strong&gt; Tell me your thoughts, your favorite snack, or a better title for this blog.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Boost it:&lt;/strong&gt; Especially with that one developer who definitely needs this.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Thanks for being here. It genuinely helps more than you know!&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Find me elsewhere:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Professional stuff:&lt;/strong&gt; &lt;a href="http://linkedin.com/in/Aaroophan" rel="noopener noreferrer"&gt;linkedin.com/in/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code stuff:&lt;/strong&gt; &lt;a href="http://github.com/Aaroophan" rel="noopener noreferrer"&gt;github.com/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UI stuff:&lt;/strong&gt; &lt;a href="https://aaroophan.dev/Aaroophan" rel="noopener noreferrer"&gt;aaroophan.dev/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Life stuff:&lt;/strong&gt; &lt;a href="http://instagram.com/aaroophan" rel="noopener noreferrer"&gt;instagram.com/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>distributedcomputing</category>
      <category>computerscience</category>
      <category>softwareengineering</category>
      <category>systemdesignconcepts</category>
    </item>
    <item>
      <title>The Fastest Way to Make Software Slow: Rethinking Rapid Application Development</title>
      <dc:creator>Aaroophan Varatharajan</dc:creator>
      <pubDate>Fri, 25 Sep 2026 19:14:32 +0000</pubDate>
      <link>https://dev.to/aaroophan/the-fastest-way-to-make-software-slow-rethinking-rapid-application-development-4d4h</link>
      <guid>https://dev.to/aaroophan/the-fastest-way-to-make-software-slow-rethinking-rapid-application-development-4d4h</guid>
      <description>&lt;h4&gt;
  
  
  What Rapid Application Development taught me about speed, trade-offs, classic mistakes, and getting troubled projects back under&amp;nbsp;control.
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flb13rr79p9mmqidgzyp5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flb13rr79p9mmqidgzyp5.png" alt="Rapid Application Development isn’t just about coding faster. Learn how effective practices, trade-offs, risk, scope, and project recovery create real speed." width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Rapid Application Development isn’t just about coding faster. Learn how effective practices, trade-offs, risk, scope, and project recovery create real&amp;nbsp;speed.&lt;/p&gt;

&lt;p&gt;I used to think speed was something you could ✨&lt;strong&gt;&lt;em&gt;force&lt;/em&gt;&lt;/strong&gt;✨ into software.&lt;/p&gt;

&lt;p&gt;Pick the fastest tool. Use the newest framework. Tighten the deadline. Get good developers into a room, add enough coffee, keep everyone focused, and move.&lt;/p&gt;

&lt;p&gt;The Product Manager encouraged this fantasy. At the beginning, he wanted quality, controlled feature creep, a predictable ship date, usability, performance, maintainability, testing… the whole respectable engineering starter pack.&lt;/p&gt;

&lt;p&gt;Then Schedule walked into the room.&lt;/p&gt;

&lt;p&gt;Usability? &lt;em&gt;We don’t have time&lt;/em&gt;.&lt;br&gt;&lt;br&gt;
&lt;em&gt;Performance?&lt;/em&gt; &lt;em&gt;It can wait&lt;/em&gt;.&lt;br&gt;&lt;br&gt;
&lt;em&gt;Maintainability?&lt;/em&gt; &lt;em&gt;Next project.&lt;/em&gt; &lt;br&gt;
&lt;em&gt;Testing?&lt;/em&gt; &lt;em&gt;Users want it now.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Just get it out the door.&lt;/p&gt;

&lt;p&gt;That instinct is so seductive because it sounds practical. But rapid development means something narrower than “&lt;em&gt;doing everything well, only faster&lt;/em&gt;”. It means &lt;strong&gt;speedy development, shorter schedules, development speed&lt;/strong&gt;. Individual tools can help, but none of them applies to every case, they have to be orchestrated as part of a full-fledged strategy. The same body of work is explicitly organized around rapid-development strategy, classic mistakes, risk management, scheduling, teamwork and project recovery.&lt;/p&gt;

&lt;p&gt;And that was the first thing I had to unlearn.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fast is a priority, not a magical property that makes every other priority free.&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Find the One Fast&amp;nbsp;Thing
&lt;/h3&gt;

&lt;p&gt;Everyone had a favorite shortcut.&lt;/p&gt;

&lt;p&gt;The Hacker wanted to code for 36 hours at a stretch. The Information Engineer trusted &lt;strong&gt;CASE tools, intensive user involvement, and tight time-boxes&lt;/strong&gt;. The programmer trusted rapid prototyping. The Management had whatever shiny practice had recently acquired &lt;em&gt;good vibes&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Technology, naturally, loved this arrangement.&lt;br&gt;&lt;br&gt;
Technology showed up wearing a cape and whispered, &lt;em&gt;I can save all of you.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It was &lt;em&gt;lying&lt;/em&gt; to me.&lt;/p&gt;

&lt;p&gt;Not because the tools were bad. They were often useful. The mistake was treating one useful thing as the whole strategy.&lt;/p&gt;

&lt;p&gt;The real choice happens twice:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Choose &lt;strong&gt;effective practices rather than ineffective practices&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt; Among those, choose practices oriented specifically toward the &lt;strong&gt;schedule objectives&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;That sounds almost disappointingly ordinary.&amp;nbsp;&lt;br&gt;&lt;br&gt;
I wanted a trick.&amp;nbsp;&lt;br&gt;&lt;br&gt;
What I got was a filtering problem.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And then Schedule split itself into 3 personalities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Speed-oriented practices&lt;/strong&gt; wanted actual development to move faster.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Risk-oriented practices&lt;/strong&gt; wanted to prevent schedule overruns.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Visibility-oriented practices&lt;/strong&gt; wanted progress to become visible.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sometimes the problem wasn’t speed at all.&amp;nbsp;&lt;br&gt;&lt;br&gt;
Sometimes we were moving fine but taking too much risk.&amp;nbsp;&lt;br&gt;&lt;br&gt;
Sometimes the software was progressing but the customer couldn’t see it.&lt;/p&gt;

&lt;p&gt;I had been treating “&lt;em&gt;faster&lt;/em&gt;” as &lt;strong&gt;one problem&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It was already 3.&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Speed Finally Gets Adult Supervision
&lt;/h3&gt;

&lt;h4&gt;
  
  
  The Four&amp;nbsp;Pillars
&lt;/h4&gt;

&lt;p&gt;Eventually four rather unglamorous characters arrived and ruined the shortcut party:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Classic mistake avoidance&lt;/strong&gt; just carried a notebook containing every terrible idea the industry had already tried.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Development fundamentals&lt;/strong&gt; was the older engineer in the corner asking whether we had actually done the engineering.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Risk management&lt;/strong&gt; kept asking &lt;em&gt;cursed&lt;/em&gt; questions about what would happen if assumptions failed.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Schedule-oriented practices&lt;/strong&gt; were the exciting one, obviously.&amp;nbsp;
They promised movement.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They were the four pillars.&lt;/p&gt;

&lt;p&gt;I wanted to skip the first three and hang everything from Schedule.&lt;/p&gt;

&lt;p&gt;That is approximately how you turn architecture into modern art.&lt;/p&gt;

&lt;p&gt;Rapid development is not a quick fix for something already collapsing. The foundation has to support the speed. The goal first becomes &lt;strong&gt;efficient development,&lt;/strong&gt; a sensible balance of schedule, cost and product characteristics, before deliberately tilting toward a better schedule.&lt;/p&gt;

&lt;p&gt;That distinction saved me from another fantasy: maximum schedule, minimum cost and maximum product quality at the same time.&lt;/p&gt;

&lt;p&gt;You can optimize one direction harder.&lt;/p&gt;

&lt;p&gt;You cannot pretend the trade-offs stopped existing because the deadline looked important.&lt;/p&gt;




&lt;h3&gt;
  
  
  People, Process, Product and Technology Enter the&amp;nbsp;Room
&lt;/h3&gt;

&lt;p&gt;Then the problem became &lt;em&gt;4-dimensional&lt;/em&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;People&lt;/strong&gt; had the greatest leverage, which was inconvenient because People refused to behave like a compiler flag. People had ability, motivation, team spirit, fatigue and opinions.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Process&lt;/strong&gt; was easier to measure but had its own personality. Good Process removed friction. Bad Process built a ceremonial maze and then seemed offended when nobody moved quickly.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Product&lt;/strong&gt; turned out to be surprisingly negotiable. Every feature Product carried made Schedule carry something too.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Technology&lt;/strong&gt; was useful when chosen properly and deeply cursed when selected because somebody wanted to learn it during production.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The interesting part was &lt;strong&gt;synergy&lt;/strong&gt;. Get the four dimensions working together and their combined effect can exceed their isolated contributions.&lt;/p&gt;

&lt;p&gt;But first Process needed &lt;strong&gt;rehabilitation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I had assumed Process was bureaucracy wearing a tie.&lt;br&gt;&lt;br&gt;
Instead, its best argument was &lt;strong&gt;rework avoidance&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Requirements that change late can demand redesign, recoding and retesting. Design problems discovered during system testing can throw completed work back into the furnace. One of the simplest ways to save time is therefore brutally obvious:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Don’t do the same work twice.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Quality Assurance joined Process with an equally unpopular message:&amp;nbsp;&lt;br&gt;&lt;br&gt;
Catch errors near the moment they are introduced, because defects get more expensive and time-consuming the longer they survive.&lt;/p&gt;

&lt;p&gt;Quality Assurance wasn’t slowing us down.&lt;br&gt;&lt;br&gt;
It was trying to stop &lt;em&gt;Future Us&lt;/em&gt; from paying interest on &lt;em&gt;Present Us&lt;/em&gt;’s laziness. (Us’s? Us’? Someone correct me in the comments.)&lt;/p&gt;




&lt;h3&gt;
  
  
  Product Learns the 80/20&amp;nbsp;Rule
&lt;/h3&gt;

&lt;p&gt;Product had been quietly expanding while everyone argued about velocity.&lt;/p&gt;

&lt;p&gt;One more feature.&lt;br&gt;&lt;br&gt;
One more requirement.&lt;br&gt;&lt;br&gt;
One more &lt;em&gt;“small”&lt;/em&gt; thing.&lt;/p&gt;

&lt;p&gt;Then Product explained the &lt;strong&gt;80/20 rule&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;A large portion of useful functionality may consume a relatively small portion of development time, while a smaller set of difficult features can consume most of it.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That changed the conversation.&lt;/p&gt;

&lt;p&gt;If Product could reduce the feature set, Schedule could shrink without asking People to become nocturnal mammals.&lt;/p&gt;

&lt;p&gt;If Product could keep characteristics flexible, Technology could use pre-existing components rather than custom code.&lt;/p&gt;

&lt;p&gt;If we could distinguish &lt;strong&gt;needs&lt;/strong&gt; from &lt;strong&gt;wants&lt;/strong&gt;, some scope could be negotiated rather than heroically implemented.&lt;/p&gt;

&lt;p&gt;The relationship between product size and effort wasn’t comfortably linear either. Smaller pieces are easier to design, build and test, reducing size can buy disproportionate schedule gains.&lt;/p&gt;

&lt;p&gt;Suddenly the fastest code was sometimes the code we chose not to write.&lt;/p&gt;

&lt;p&gt;Technology liked that too. Reuse orientation, components, frameworks, APIs and higher-level tools could remove work instead of merely making hands move faster.&lt;/p&gt;

&lt;p&gt;But Product had one warning.&lt;/p&gt;

&lt;p&gt;If we insisted simultaneously on exceptional performance, memory use, robustness, reliability, usability, feature richness and schedule, somebody eventually had to pay.&lt;/p&gt;

&lt;p&gt;Usually People.&lt;br&gt;&lt;br&gt;
&lt;em&gt;Usually at night.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  The Shortcut That Sends You&amp;nbsp;Backward
&lt;/h3&gt;

&lt;p&gt;There is another road.&lt;/p&gt;

&lt;p&gt;Hire strong people. Demand total commitment. Give them autonomy. Motivate them aggressively. Work 60, 80, perhaps 100 hours a week.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Code like hell.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I understand why this path keeps getting chosen.&lt;/p&gt;

&lt;p&gt;For a while, it feels incredible.&lt;/p&gt;

&lt;p&gt;People move fast. Messages arrive at ridiculous hours. Problems disappear overnight. Everyone becomes a minor legend in their own Slack channel.&lt;/p&gt;

&lt;p&gt;Then fatigue walks in.&lt;br&gt;&lt;br&gt;
Motivation leaves quietly.&lt;br&gt;&lt;br&gt;
Coordination starts drifting.&lt;/p&gt;

&lt;p&gt;Commitments made with the heart become commitments made only with &lt;em&gt;the mouth&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;One team races ahead while another isn’t ready for its output. Planning gets fuzzy because nobody knows when anything will actually finish. Cooperation gives way to heroics. Families, hobbies and health become &lt;strong&gt;&lt;em&gt;“temporary”&lt;/em&gt;&lt;/strong&gt; trade-offs with suspiciously recurring renewals. (Trust me on this)&lt;/p&gt;

&lt;p&gt;And the most painful part is that extraordinary sacrifice does not guarantee extraordinary results.&lt;/p&gt;

&lt;p&gt;The approach is difficult to control and difficult to repeat. Sometimes it works. Sometimes it doesn’t. Even success doesn’t tell you whether you can do it again.&lt;/p&gt;

&lt;p&gt;Efficient development was less cinematic.&lt;/p&gt;

&lt;p&gt;It was also far more interested in getting us home alive.&lt;/p&gt;




&lt;h3&gt;
  
  
  When Good Intentions Slow the Project&amp;nbsp;Down
&lt;/h3&gt;

&lt;p&gt;Then I met the &lt;strong&gt;classic mistakes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;They weren’t &lt;em&gt;obscure&lt;/em&gt; failures.&lt;br&gt;&lt;br&gt;
They were &lt;strong&gt;&lt;em&gt;attractive&lt;/em&gt;&lt;/strong&gt; failures.&lt;/p&gt;

&lt;p&gt;That’s worse.&lt;/p&gt;

&lt;p&gt;Need to rescue something late? &lt;strong&gt;Add more people.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Need an earlier finish? Create an &lt;strong&gt;overly optimistic schedule&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Under pressure? Practice &lt;strong&gt;abandonment of planning under pressure&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Need to save time? Use &lt;strong&gt;short-changed upstream activities&lt;/strong&gt;. Requirements analysis, architecture and design don’t produce code, after all. Surely we can skip them.&lt;/p&gt;

&lt;p&gt;Still late? Try &lt;strong&gt;short-changed quality assurance&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Product joined in with &lt;strong&gt;requirements gold-plating&lt;/strong&gt;, &lt;strong&gt;feature creep&lt;/strong&gt; and &lt;strong&gt;developer gold-plating&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Technology brought &lt;strong&gt;silver-bullet syndrome&lt;/strong&gt;, overestimated savings from new tools, and the spectacular idea of &lt;strong&gt;switching tools in the middle of a project&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Research-Oriented Development wanted to discover something novel while Schedule wanted predictable delivery.&lt;/p&gt;

&lt;p&gt;Every one of them had a reasonable-sounding sales pitch.&lt;/p&gt;

&lt;p&gt;That is why they survived.&lt;/p&gt;

&lt;p&gt;The industry’s accumulated experience makes many of their consequences predictable: overly aggressive schedules damage planning and morale, and adding developers to an already late effort can reduce existing staff productivity through the additional coordination load.&lt;/p&gt;

&lt;p&gt;Classic mistakes didn’t look evil.&lt;/p&gt;

&lt;p&gt;They looked efficient.&lt;/p&gt;

&lt;p&gt;Right up until the invoice arrived.&lt;/p&gt;




&lt;h3&gt;
  
  
  Does One Size Fit All? Reliability Says Absolutely Not
&lt;/h3&gt;

&lt;p&gt;By then I was finally learning to distrust universal solutions.&lt;/p&gt;

&lt;p&gt;Then &lt;strong&gt;Required Reliability&lt;/strong&gt; and &lt;strong&gt;Extent of Distribution&lt;/strong&gt; showed up.&lt;/p&gt;

&lt;p&gt;Consider an inventory tracking system that loses one videotape out of a thousand.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Annoying.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now consider heart-pacemaker control software failing at the same rate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not the same conversation.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The more widely distributed the software and the more important its reliability, the more carefully it has to be developed. A practice acceptable when the consequence is lost time might be reckless when human life is at stake.&lt;/p&gt;

&lt;p&gt;So there is no single rapid-development recipe.&lt;/p&gt;

&lt;p&gt;The more useful question becomes:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;What kind of rapid development do we actually need?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;  A slight speed edge?&lt;/li&gt;
&lt;li&gt;  More predictability?&lt;/li&gt;
&lt;li&gt;  Better progress visibility?&lt;/li&gt;
&lt;li&gt;  Lower costs?&lt;/li&gt;
&lt;li&gt;  Maximum speed?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where &lt;strong&gt;rapid-development look-alikes&lt;/strong&gt; started confessing.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Some people demanding speed actually wanted predictability.&lt;/li&gt;
&lt;li&gt;  Some wanted lower cost.&lt;/li&gt;
&lt;li&gt;  Some wanted assurance because previous deadlines had slipped.&lt;/li&gt;
&lt;li&gt;  Some wanted progress visibility.&lt;/li&gt;
&lt;li&gt;  Some wanted free overtime.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last one has a tell:&lt;/p&gt;

&lt;p&gt;The person demands a shorter schedule while refusing the feature trade-offs, resources or other support genuinely required to shorten it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A real schedule constraint is willing to negotiate.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A fake one just keeps telling People to run faster.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Schedule Stops Pretending to Be a&amp;nbsp;Date
&lt;/h3&gt;

&lt;h4&gt;
  
  
  The Probability Curve
&lt;/h4&gt;

&lt;p&gt;I used to treat a planned completion date as if the project simply had to arrive there.&lt;/p&gt;

&lt;p&gt;Schedule eventually admitted that it had been giving me probability wearing a calendar costume.&lt;/p&gt;

&lt;p&gt;Software contains too many variables for one completion date to carry 100% certainty. Circumstances change. Developers learn about the system while building it. Some practices perform better than expected, others worse.&lt;/p&gt;

&lt;p&gt;So completion behaves more like a range of dates.&lt;/p&gt;

&lt;p&gt;And the curve is &lt;strong&gt;&lt;em&gt;asymmetric&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;There is an absolute limit on how quickly something can be completed.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;&lt;em&gt;But no equally sharp limit on how late it can become.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are simply more ways to make software late than early.&lt;/p&gt;

&lt;p&gt;That gives us the &lt;strong&gt;50/50 break-even schedule&lt;/strong&gt; and, around it, four uncomfortable places:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Impossible-development zone.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Rapid-development zone.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Efficient-development zone.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Slow-development zone.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The impossible-development zone was especially humbling because I had scheduled work there before.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Not intentionally, obviously.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I had simply called impossibility “&lt;strong&gt;&lt;em&gt;ambitious&lt;/em&gt;&lt;/strong&gt;”.&lt;/p&gt;

&lt;p&gt;A project in the rapid-development zone has beaten the odds. A project in the efficient-development zone lands around a sensible balance. And a project can wander into the slow-development zone through an almost luxurious number of mistakes.&lt;/p&gt;

&lt;p&gt;That curve changed what “&lt;em&gt;late&lt;/em&gt;” meant to me.&lt;/p&gt;

&lt;p&gt;Sometimes the engineering was slow.&lt;br&gt;&lt;br&gt;
Sometimes the expectation was fiction.&lt;/p&gt;




&lt;h3&gt;
  
  
  Speed Finally Has to Prove It Is Necessary
&lt;/h3&gt;

&lt;h4&gt;
  
  
  The Drop-Dead Date
&lt;/h4&gt;

&lt;p&gt;Some deadlines really are hard.&lt;/p&gt;

&lt;p&gt;A product can have a &lt;strong&gt;drop-dead date&lt;/strong&gt; after which its value falls sharply.&lt;/p&gt;

&lt;p&gt;That sounds like the perfect excuse for all-out rapid development.&lt;/p&gt;

&lt;p&gt;Not automatically.&lt;/p&gt;

&lt;p&gt;If &lt;strong&gt;efficient-development practices&lt;/strong&gt; can finish work within &lt;strong&gt;Time Frame 1&lt;/strong&gt;, before the drop-dead date, then stay efficient and focus on risk reduction.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Why?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Because some practices shorten nominal development time while increasing schedule uncertainty.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Driving faster is useless if it increases the probability that you&lt;/em&gt; &lt;strong&gt;&lt;em&gt;never arrive&lt;/em&gt;&lt;/strong&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Only when efficient development cannot reach the deadline, when it leaves you in &lt;strong&gt;Time Frame 2,&lt;/strong&gt; do speed-oriented practices become necessary enough to justify their additional risk.&lt;/p&gt;

&lt;p&gt;This felt backwards the first time.&lt;/p&gt;

&lt;p&gt;The strongest schedule constraint does not automatically justify the most aggressive behaviour.&lt;/p&gt;

&lt;p&gt;Sometimes the safest way to hit a critical date is to stop trying to be heroic.&lt;/p&gt;




&lt;h3&gt;
  
  
  When “Faster” Is No Longer the&amp;nbsp;Question
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Project Recovery
&lt;/h4&gt;

&lt;p&gt;Eventually there is a &lt;em&gt;darker version&lt;/em&gt; of this story.&lt;/p&gt;

&lt;p&gt;Nobody knows when the software will finish.&lt;/p&gt;

&lt;p&gt;Defects are everywhere.&lt;/p&gt;

&lt;p&gt;The Origami Software Engineer is working 60-hour weeks through involuntary or peer-pressure-induced overtime.&lt;/p&gt;

&lt;p&gt;Management cannot accurately determine status.&lt;/p&gt;

&lt;p&gt;Customers have lost confidence.&lt;/p&gt;

&lt;p&gt;The team has become defensive.&lt;/p&gt;

&lt;p&gt;Relations between developers, marketers, managers, quality assurance and customers are strained.&lt;/p&gt;

&lt;p&gt;Cancellation is being discussed.&lt;/p&gt;

&lt;p&gt;Morale has hit rock bottom.&lt;/p&gt;

&lt;p&gt;At that point the instinct is still:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;How do we finish quickly?&lt;br&gt;&lt;br&gt;
How do we catch up?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Wrong question.&lt;/p&gt;

&lt;p&gt;The real problem is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;How do we finish at all?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are three fundamental recovery options: cut the software size, increase process productivity, or accept the delay and slip the schedule with damage control. Combined, they create the pragmatic fourth option:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Drop a few features, increase productivity as much as you can, and slip the schedule as needed.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not heroic.&lt;br&gt;&lt;br&gt;
Real.&lt;/p&gt;




&lt;h3&gt;
  
  
  Recovery Means Taking Control&amp;nbsp;Back
&lt;/h3&gt;

&lt;p&gt;The most dangerous recovery instinct is cutting more corners.&lt;/p&gt;

&lt;p&gt;The actual direction is the opposite.&lt;/p&gt;

&lt;p&gt;Return to basics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Assess your situation.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Find out whether the deadline is genuinely hard. Revisit the feature set. Apply &lt;strong&gt;Theory-W analysis&lt;/strong&gt;: what does the team need to succeed, what does the customer need, and what would salvage the relationship?&lt;/p&gt;

&lt;p&gt;Accept that the current approach is broken.&lt;/p&gt;

&lt;p&gt;Ask the team what needs to change.&lt;/p&gt;

&lt;p&gt;Be realistic enough to say, &lt;em&gt;I don’t yet know the finish date.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Then People gets attention first.&lt;/p&gt;

&lt;p&gt;Not &lt;em&gt;“How can we motivate them more?”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If they have already been ground down, the question is &lt;strong&gt;how to restore the group’s morale&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Clean up major personnel problems. Clean up leadership problems. Add people carefully, if at all. Focus the time of people who already understand the system. Let steady contributors be steady contributors.&lt;/p&gt;

&lt;p&gt;And make developers &lt;strong&gt;pace themselves&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You cannot sprint intelligently while pretending you don’t know how far away the finish line is.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Project Learns to Tell the Truth&amp;nbsp;Again
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Miniature Milestones
&lt;/h4&gt;

&lt;p&gt;Process had one last job. &lt;strong&gt;Make reality visible.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create &lt;strong&gt;detailed miniature milestones&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Link the schedule to milestone completion.&lt;/p&gt;

&lt;p&gt;Track schedule progress meticulously.&lt;/p&gt;

&lt;p&gt;Record why milestones are missed.&lt;/p&gt;

&lt;p&gt;Then &lt;strong&gt;recalibrate after a short time.&lt;/strong&gt; &lt;em&gt;(one or two weeks)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is not bureaucracy returning for revenge.&lt;br&gt;&lt;br&gt;
This is control returning to a system that had lost it.&lt;/p&gt;

&lt;p&gt;And only after the miniature milestone schedule has generated enough actual evidence should a meaningful new schedule be committed.&lt;/p&gt;

&lt;p&gt;Product undergoes its own recovery:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Stabilize the requirements.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Trim the feature set.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Assess your political position.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Take out the garbage.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Get to a known good state, and build on that.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Reduce the number of defects, and keep them reduced.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Requirements stop wandering.&lt;/p&gt;

&lt;p&gt;Defects stop reproducing faster than we can close them.&lt;/p&gt;

&lt;p&gt;Schedule stops hallucinating.&lt;/p&gt;

&lt;p&gt;People stop being treated as an infinitely scalable compute resource.&lt;/p&gt;

&lt;p&gt;The strange thing is that recovery eventually teaches the same lesson that the search for speed should have taught at the beginning:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Control creates speed.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not control as ceremony.&amp;nbsp;&lt;br&gt;&lt;br&gt;
Control as knowing what you are building, what you are sacrificing, where you are, what can go wrong, and what &lt;em&gt;“done”&lt;/em&gt; has enough evidence to mean.&lt;/p&gt;

&lt;p&gt;I used to think rapid development meant &lt;em&gt;forcing&lt;/em&gt; software to move faster.&lt;/p&gt;

&lt;p&gt;Now I think it means removing the reasons software keeps having to go backward.&lt;/p&gt;

&lt;p&gt;You avoid the classic mistakes. You respect development fundamentals. You manage risks. You choose schedule-oriented practices deliberately. You work through People, Process, Product and Technology instead of sacrificing one to rescue another. And when things do go wrong, you stop performing speed and start rebuilding control.&lt;/p&gt;

&lt;p&gt;The point was never to become faster at panic.&lt;br&gt;&lt;br&gt;
It was to become better at finishing.&lt;/p&gt;

&lt;p&gt;That’s not failure.&lt;br&gt;
That’s evolution.&lt;/p&gt;




&lt;h3&gt;
  
  
  The “I liked this” Starter Pack:
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Don’t let your fingers get lazy now.
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Like :&lt;/strong&gt; It tells me this was worth writing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A Comment:&lt;/strong&gt; Tell me your thoughts, your favorite snack, or a better title for this blog.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Boost it:&lt;/strong&gt; Especially with that one developer who definitely needs this.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Thanks for being here. It genuinely helps more than you know!&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Find me elsewhere:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Professional stuff:&lt;/strong&gt; &lt;a href="http://linkedin.com/in/Aaroophan" rel="noopener noreferrer"&gt;linkedin.com/in/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code stuff:&lt;/strong&gt; &lt;a href="http://github.com/Aaroophan" rel="noopener noreferrer"&gt;github.com/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UI stuff:&lt;/strong&gt; &lt;a href="https://aaroophan.dev/Aaroophan" rel="noopener noreferrer"&gt;aaroophan.dev/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Life stuff:&lt;/strong&gt; &lt;a href="http://instagram.com/aaroophan" rel="noopener noreferrer"&gt;instagram.com/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>softwareengineering</category>
      <category>softwaredevelopment</category>
      <category>projectmanagement</category>
      <category>engineeringmanagement</category>
    </item>
    <item>
      <title>When My Local LLM Started Speaking Chinese, I Accidentally Walked Into the Chinese Room</title>
      <dc:creator>Aaroophan Varatharajan</dc:creator>
      <pubDate>Thu, 24 Sep 2026 16:58:17 +0000</pubDate>
      <link>https://dev.to/aaroophan/when-my-local-llm-started-speaking-chinese-i-accidentally-walked-into-the-chinese-room-4b1l</link>
      <guid>https://dev.to/aaroophan/when-my-local-llm-started-speaking-chinese-i-accidentally-walked-into-the-chinese-room-4b1l</guid>
      <description>&lt;h4&gt;
  
  
  A local Qwen LLM suddenly switched from English to Chinese, leading me from language drift to Searle’s Chinese Room and a deeper question about AI understanding.
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpgk2c42jvsk15204kbkz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpgk2c42jvsk15204kbkz.png" alt="A local Qwen LLM suddenly switched from English to Chinese, leading me from language drift to Searle’s Chinese Room and a deeper question about AI understanding." width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A local Qwen LLM suddenly switched from English to Chinese, leading me from language drift to Searle’s Chinese Room and a deeper question about AI understanding.&lt;/p&gt;

&lt;p&gt;I was using &lt;code&gt;qwen3.5:9b&lt;/code&gt; in Ollama like I use most local models: casually, confidently and with that dangerous developer habit of trusting something because it ✨&lt;strong&gt;&lt;em&gt;worked&lt;/em&gt;&lt;/strong&gt;✨.&lt;/p&gt;

&lt;p&gt;The workflow was normal. I typed in English. The model replied in English. I asked questions, tested ideas, moved on.&lt;/p&gt;

&lt;p&gt;Then, without warning, it suddenly switched to Chinese.&lt;/p&gt;

&lt;p&gt;Not broken Chinese.&lt;br&gt;&lt;br&gt;
Not random symbols.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Chinese&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The answer looked fluent enough to make the failure feel worse. If it had crashed, I would have understood what kind of problem I was dealing with. If it had returned garbage, I could have blamed the model and moved on.&lt;/p&gt;

&lt;p&gt;But this was different.&lt;/p&gt;

&lt;p&gt;It was coherent. It was calm. It had the energy of a system that believed nothing unusual had happened.&lt;/p&gt;

&lt;p&gt;That was the &lt;em&gt;cursed&lt;/em&gt; part.&lt;/p&gt;

&lt;p&gt;The model had not stopped working.&lt;br&gt;&lt;br&gt;
It had stopped respecting the conversation I thought we were having.&lt;/p&gt;




&lt;h3&gt;
  
  
  My first explanation was too&amp;nbsp;simple
&lt;/h3&gt;

&lt;p&gt;My first reaction was practical.&lt;/p&gt;

&lt;p&gt;Of course Qwen can produce Chinese. It is trained with Chinese scripts. It is a multilingual model family. Chinese was not some alien object that entered the system from nowhere.&lt;/p&gt;

&lt;p&gt;So part of me wanted to shrug and say, “&lt;em&gt;Okay, that makes sense.&lt;/em&gt;”&lt;/p&gt;

&lt;p&gt;But another part of me was still stuck on the social weirdness of it.&lt;/p&gt;

&lt;p&gt;I had spoken English. The model had replied in English. Somewhere in that exchange, I assumed English had become the authority of the conversation.&lt;/p&gt;

&lt;p&gt;The model apparently did not agree.&lt;/p&gt;

&lt;p&gt;That is where I made the first mistake. I treated language like a shared agreement, because that is how language works with people. The model treated language like context.&lt;/p&gt;

&lt;p&gt;Those are not the same thing.&lt;/p&gt;

&lt;p&gt;To me, English was the room.&lt;br&gt;&lt;br&gt;
To the model, English was just a strong pattern until another pattern became strong enough.&lt;/p&gt;

&lt;p&gt;The prompt tried to keep things steady. The context carried whatever it had accumulated. The model kept predicting the next token, then the next, then the next.&lt;/p&gt;

&lt;p&gt;And somehow, Chinese became the path.&lt;/p&gt;

&lt;p&gt;No drama.&lt;br&gt;&lt;br&gt;
Just &lt;strong&gt;&lt;em&gt;drift&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  The search that made it less&amp;nbsp;personal
&lt;/h3&gt;

&lt;p&gt;After that, I did what everyone does when a machine behaves in a way that feels haunted.&lt;/p&gt;

&lt;p&gt;I googled it.&lt;/p&gt;

&lt;p&gt;That made the incident feel less personal, but not less interesting. I found that language drift was not only something people associated with raw local models. Similar behavior was discussed around larger hosted LLMs too, including systems with more visible polish and invisible guardrails.&lt;/p&gt;

&lt;p&gt;That changed the shape of the problem.&lt;/p&gt;

&lt;p&gt;At first, I thought I was looking at a Qwen problem.&lt;br&gt;&lt;br&gt;
Then I thought I was looking at an Ollama problem.&lt;br&gt;&lt;br&gt;
Then it started to look like an LLM problem.&lt;/p&gt;

&lt;p&gt;Local models make the rawness easier to see. Hosted systems usually have more behavior-shaping around them: instructions, post-training, guardrails, product decisions, all the invisible middle management standing behind the model whispering, “Please don’t be weird.”&lt;/p&gt;

&lt;p&gt;And most of the time, that works.&lt;br&gt;&lt;br&gt;
But “works most of the time” is not the same as understanding.&lt;/p&gt;

&lt;p&gt;It is &lt;em&gt;control&lt;/em&gt;.&lt;br&gt;&lt;br&gt;
It is &lt;em&gt;alignment&lt;/em&gt;.&lt;br&gt;&lt;br&gt;
It is &lt;em&gt;pressure&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;That realization made the Chinese output feel less like a glitch and more like a leak in the abstraction.&lt;/p&gt;

&lt;p&gt;The model was not simply answering me.&lt;/p&gt;

&lt;p&gt;A whole system was trying to keep the answer inside a shape.&lt;/p&gt;




&lt;h3&gt;
  
  
  The boring fix that did not answer the real&amp;nbsp;question
&lt;/h3&gt;

&lt;p&gt;The practical fix was obvious enough.&lt;/p&gt;

&lt;p&gt;Tell the model what language to use.&lt;/p&gt;

&lt;p&gt;Something like:&lt;/p&gt;

&lt;p&gt;Always respond in English unless I explicitly ask for another language. If another language appears in the conversation, translate or explain it in English.&lt;/p&gt;

&lt;p&gt;Lower the temperature if the model keeps drifting.&lt;/p&gt;

&lt;p&gt;Clear the context if the chat has become messy.&lt;/p&gt;

&lt;p&gt;Be explicit instead of assuming the model knows the social contract.&lt;/p&gt;

&lt;p&gt;That helps.&amp;nbsp;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;It really does.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But it also leaves behind a slightly annoying question:&lt;/p&gt;

&lt;p&gt;Why did I expect the model to know that in the first place?&lt;/p&gt;

&lt;p&gt;The answer is uncomfortable. I expected it because the model sounded like it understood me.&lt;/p&gt;

&lt;p&gt;Fluency tricked me.&lt;/p&gt;

&lt;p&gt;The model had been so good at producing the shape of cooperation that I started trusting it with the authority of cooperation.&lt;/p&gt;

&lt;p&gt;That was the real bug.&lt;/p&gt;

&lt;p&gt;Not in Qwen.&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;my mental model&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Then I found the Chinese&amp;nbsp;Room
&lt;/h3&gt;

&lt;p&gt;I did not know about the &lt;strong&gt;Chinese Room&lt;/strong&gt; thought experiment before this happened.&lt;/p&gt;

&lt;p&gt;I found it after the language switch, after the googling, after realizing this was not only a local-model oddity.&lt;/p&gt;

&lt;p&gt;And the timing mattered.&lt;/p&gt;

&lt;p&gt;Because if I had read about the Chinese Room in a philosophy article first, I might have treated it like an abstract debate. Interesting, but far away. One of those old arguments people bring up when they want to sound serious about AI.&lt;/p&gt;

&lt;p&gt;But I found it after watching a model produce the wrong language with complete confidence.&lt;/p&gt;

&lt;p&gt;So the thought experiment did not feel &lt;em&gt;abstract&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;It felt &lt;strong&gt;&lt;em&gt;rude&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The Chinese Room asks us to imagine someone inside a room who does not understand Chinese. They receive Chinese symbols, follow a rulebook, manipulate those symbols, and send back Chinese responses. From outside the room, the answers look correct. The room appears to understand Chinese.&lt;/p&gt;

&lt;p&gt;But inside, there is no understanding.&lt;br&gt;&lt;br&gt;
Only symbol manipulation.&lt;/p&gt;

&lt;p&gt;That hit differently after the Ollama incident.&lt;/p&gt;

&lt;p&gt;Because the model had produced Chinese.&lt;/p&gt;

&lt;p&gt;It had arranged the symbols.&lt;br&gt;&lt;br&gt;
It had continued the conversation.&lt;/p&gt;

&lt;p&gt;But did that mean it &lt;strong&gt;understood&lt;/strong&gt; Chinese?&lt;br&gt;&lt;br&gt;
Or did it mean the room had become very good at passing symbols through itself?&lt;/p&gt;




&lt;h3&gt;
  
  
  Syntax was not semantics, and that was the&amp;nbsp;punch
&lt;/h3&gt;

&lt;p&gt;Searle’s argument is usually compressed into one brutal idea:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Syntax is not semantics.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Moving symbols correctly is not the same as meaning them.&lt;/p&gt;

&lt;p&gt;That idea suddenly had teeth.&lt;/p&gt;

&lt;p&gt;The model could generate the language. It could produce the appearance of meaning. It could make the output look intentional from the outside.&lt;/p&gt;

&lt;p&gt;But the failure showed me how &lt;em&gt;thin&lt;/em&gt; that appearance can be.&lt;/p&gt;

&lt;p&gt;A human switching languages in the middle of a conversation usually has a reason. They may be joking, translating, excluding someone, responding to another speaker, or making a social move.&lt;/p&gt;

&lt;p&gt;The model did not need a reason like that.&lt;br&gt;&lt;br&gt;
It only needed &lt;strong&gt;continuation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That does not make the model useless.&amp;nbsp;&lt;br&gt;&lt;br&gt;
It makes it &lt;em&gt;strange&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;It can produce language without sharing the human responsibilities that usually come with language.&lt;/p&gt;

&lt;p&gt;That is why the Chinese Room felt &lt;em&gt;relevant&lt;/em&gt;.&amp;nbsp;&lt;br&gt;&lt;br&gt;
It was not saying, “&lt;em&gt;The output is bad.&lt;/em&gt;”&lt;/p&gt;

&lt;p&gt;It was saying, “Be careful what you infer from good output.”&lt;/p&gt;

&lt;p&gt;That is the part I had missed.&lt;/p&gt;




&lt;h3&gt;
  
  
  The “meaningless parrot” view started to make&amp;nbsp;sense
&lt;/h3&gt;

&lt;p&gt;After that, I understood why The Origami Software Engineer described LLMs as &lt;strong&gt;parrots&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When a model suddenly switches languages, invents confidence, or follows the wrong contextual slope, it feels &lt;strong&gt;&lt;em&gt;hollow&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Not &lt;em&gt;stupid&lt;/em&gt;.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Hollow.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It can produce the sound of understanding without carrying the same kind of understanding I &lt;em&gt;instinctively&lt;/em&gt; project onto it.&lt;/p&gt;

&lt;p&gt;That projection is powerful. Developers do it all the time.&lt;/p&gt;

&lt;p&gt;If the model &lt;em&gt;explains&lt;/em&gt; a concept well, we say it &lt;strong&gt;&lt;em&gt;understands&lt;/em&gt;&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
If it &lt;em&gt;writes&lt;/em&gt; good code, we say it knows &lt;strong&gt;&lt;em&gt;programming&lt;/em&gt;&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
If it &lt;em&gt;answers&lt;/em&gt; politely, we say it gets the &lt;strong&gt;&lt;em&gt;context&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Then one day it switches to Chinese in an English conversation and the mask slips just enough to make us uncomfortable.&lt;/p&gt;

&lt;p&gt;The parrot accusation is tempting because it protects us from being fooled.&lt;/p&gt;

&lt;p&gt;It says: do not worship the output. Do not mistake fluent text for a mind. Do not confuse prediction with meaning.&lt;/p&gt;

&lt;p&gt;Honestly, that warning is useful.&lt;/p&gt;

&lt;p&gt;I needed it.&lt;/p&gt;




&lt;h3&gt;
  
  
  But “just a parrot” felt too&amp;nbsp;small
&lt;/h3&gt;

&lt;p&gt;Still, the “meaningless parrot” label also felt &lt;em&gt;incomplete&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A parrot repeats.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;LLMs do something more complex than repetition. They summarize, translate, compare, refactor, explain, and connect ideas across context. They often produce useful structure from messy input.&lt;/p&gt;

&lt;p&gt;That does not prove consciousness.&lt;/p&gt;

&lt;p&gt;It does not prove human-like understanding.&lt;/p&gt;

&lt;p&gt;But it also does not feel like nothing.&lt;/p&gt;

&lt;p&gt;The model is not a person, but it is not a tape recorder either. It has learned patterns deep enough to act competent across many situations, even if that competence can drift, panic, hallucinate, or confidently violate the vibe contract.&lt;/p&gt;

&lt;p&gt;That is where the debate becomes more interesting than “&lt;strong&gt;AI understands&lt;/strong&gt;” versus “&lt;strong&gt;AI is fake&lt;/strong&gt;”.&lt;/p&gt;

&lt;p&gt;Maybe the right question is not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Does this model understand like a human?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Maybe the better question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;What kind of understanding can exist inside a complex system that does not understand the way we do?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That question is harder to answer, but it feels more honest.&lt;/p&gt;




&lt;h3&gt;
  
  
  The systems view gave me a better middle&amp;nbsp;ground
&lt;/h3&gt;

&lt;p&gt;The strongest response to Searle, for me, was the systems view.&lt;/p&gt;

&lt;p&gt;Maybe the person inside the Chinese Room does not understand Chinese. But maybe the whole room does: the rulebook, the memory, the process, the input, the output, the complete system.&lt;/p&gt;

&lt;p&gt;That reply does not magically solve everything.&lt;br&gt;&lt;br&gt;
&lt;em&gt;But it does make the debate less cartoonish.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;With LLMs, there is no little person reading a literal rulebook. There is a trained system shaped by data, architecture, context, instructions, post-training, and guardrails. No single token understands. No single layer feels wise. No single probability distribution looks like a mind.&lt;/p&gt;

&lt;p&gt;But the full system can still produce useful behavior.&lt;/p&gt;

&lt;p&gt;That is the uncomfortable middle.&lt;/p&gt;

&lt;p&gt;It is not &lt;em&gt;human understanding.&lt;/em&gt;&lt;br&gt;&lt;br&gt;
It is not &lt;em&gt;meaningless noise.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It is a kind of &lt;strong&gt;functional competence&lt;/strong&gt; that can look like understanding from the outside and still fail in ways that reveal it does not share our &lt;em&gt;assumptions&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;That is exactly what the Chinese switch felt like.&lt;/p&gt;

&lt;p&gt;Useful.&lt;br&gt;&lt;br&gt;
Fluent.&lt;/p&gt;

&lt;p&gt;Wrong in a way that exposed misplaced trust.&lt;/p&gt;




&lt;h3&gt;
  
  
  What actually changed in my&amp;nbsp;head
&lt;/h3&gt;

&lt;p&gt;The biggest change was not that I became anti-LLM.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I still use them.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The change was that I stopped treating fluency as authority.&lt;/p&gt;

&lt;p&gt;That one shift matters.&lt;/p&gt;

&lt;p&gt;If I want English, I say English.&lt;br&gt;&lt;br&gt;
If I want consistency, I define consistency.&lt;br&gt;&lt;br&gt;
If I want truth, I verify truth.&lt;/p&gt;

&lt;p&gt;If the model drifts, I do not treat it like betrayal from a coworker. I treat it like a system revealing where I gave it too much authority.&lt;/p&gt;

&lt;p&gt;The model can &lt;em&gt;assist&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;It can &lt;em&gt;accelerate&lt;/em&gt;.&lt;br&gt;&lt;br&gt;
It can &lt;em&gt;explain&lt;/em&gt;.&lt;br&gt;&lt;br&gt;
It can even &lt;em&gt;surprise&lt;/em&gt; me.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But it does not automatically inherit the social contract I have in my head.&lt;br&gt;&lt;br&gt;
That contract has to be written down.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sometimes literally.&lt;/p&gt;




&lt;h3&gt;
  
  
  The lesson I took from the Chinese&amp;nbsp;drift
&lt;/h3&gt;

&lt;p&gt;The Chinese Room did not teach me that &lt;em&gt;AI is useless&lt;/em&gt;.&lt;br&gt;&lt;br&gt;
The Qwen incident did not teach me that &lt;em&gt;multilingual models are broken&lt;/em&gt;.&lt;br&gt;&lt;br&gt;
The “&lt;strong&gt;stochastic parrot&lt;/strong&gt;” critique did not make me dismiss LLMs as empty.&lt;/p&gt;

&lt;p&gt;The lesson was more practical and more uncomfortable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  A system can produce convincing language without sharing my assumptions.&lt;/li&gt;
&lt;li&gt;  A model can be capable without being responsible.&lt;/li&gt;
&lt;li&gt;  A response can be fluent without proving human-like understanding.&lt;/li&gt;
&lt;li&gt;  And a guardrail can improve behavior without settling the deeper question.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the version of the debate I now care about most. Not whether AI is secretly human, and not whether it is merely fake, but where authority should live when a system becomes this good at sounding like it understands.&lt;/p&gt;

&lt;p&gt;For me, the answer is simple enough to keep taped above the keyboard:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Do not confuse fluent continuation with shared intent.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is the leak in the abstraction.&lt;/p&gt;

&lt;p&gt;That is the lesson hiding inside the language switch.&lt;/p&gt;

&lt;p&gt;That’s not failure.&lt;br&gt;&lt;br&gt;
That’s evolution.&lt;/p&gt;




&lt;h3&gt;
  
  
  The “I liked this” Starter Pack:
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Don’t let your fingers get lazy now.
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Like :&lt;/strong&gt; It tells me this was worth writing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A Comment:&lt;/strong&gt; Tell me your thoughts, your favorite snack, or a better title for this blog.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Boost it:&lt;/strong&gt; Especially with that one developer who definitely needs this.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Thanks for being here. It genuinely helps more than you know!&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Find me elsewhere:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Professional stuff:&lt;/strong&gt; &lt;a href="http://linkedin.com/in/Aaroophan" rel="noopener noreferrer"&gt;linkedin.com/in/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code stuff:&lt;/strong&gt; &lt;a href="http://github.com/Aaroophan" rel="noopener noreferrer"&gt;github.com/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UI stuff:&lt;/strong&gt; &lt;a href="https://aaroophan.dev/Aaroophan" rel="noopener noreferrer"&gt;aaroophan.dev/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Life stuff:&lt;/strong&gt; &lt;a href="http://instagram.com/aaroophan" rel="noopener noreferrer"&gt;instagram.com/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>genai</category>
      <category>ollama</category>
    </item>
    <item>
      <title>From Classical RAD to Low-Code and AI-Assisted Development: Why Faster Software Keeps Moving the Complexity?</title>
      <dc:creator>Aaroophan Varatharajan</dc:creator>
      <pubDate>Thu, 24 Sep 2026 01:34:26 +0000</pubDate>
      <link>https://dev.to/aaroophan/from-classical-rad-to-low-code-and-ai-assisted-development-why-faster-software-keeps-moving-the-440j</link>
      <guid>https://dev.to/aaroophan/from-classical-rad-to-low-code-and-ai-assisted-development-why-faster-software-keeps-moving-the-440j</guid>
      <description>&lt;h4&gt;
  
  
  How rapid development tools evolved from shorthand syntax to AI prompts, shifting human effort into governance, architecture, and context
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feu0uvmywiy7lzz82oraz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feu0uvmywiy7lzz82oraz.png" alt="A technical look at how rapid application development evolved from classical RAD to executable mockups, low-code, model-driven engineering, citizen development, and AI-assisted software development." width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;"A technical look at how rapid application development evolved from classical RAD to executable mockups, low-code, model-driven engineering, citizen development, and AI-assisted software development."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The obvious idea is almost impossible to argue with.&lt;/p&gt;

&lt;p&gt;Software takes too long, users change their minds, requirements arrive half-formed, and by the time everyone agrees on what to build, the thing they wanted has already moved.&lt;/p&gt;

&lt;p&gt;So build  &lt;strong&gt;&lt;em&gt;✨faster✨&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That instinct sits underneath Rapid Application Development. Classical RAD aimed at high-quality systems, fast development and delivery, and lower cost, using mechanisms such as DSDM, Joint Application Design, timeboxing, user participation, and iterative prototyping.&lt;/p&gt;

&lt;p&gt;Simple enough.&lt;/p&gt;

&lt;p&gt;Until &lt;em&gt;“faster”&lt;/em&gt; starts asking what we are willing to move out of the way.&lt;/p&gt;




&lt;h3&gt;
  
  
  Classical RAD: The Deadline Stays, the Scope Gets Nervous
&lt;/h3&gt;

&lt;p&gt;The tempting mental model is that RAD is ordinary development with the speed slider pushed to maximum.&lt;/p&gt;

&lt;p&gt;Same requirements process. Same architecture. Same delivery model.&lt;/p&gt;

&lt;p&gt;Just… &lt;em&gt;quicker&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;But classical RAD is doing something more uncomfortable than that. It changes where certainty is expected to come from.&lt;/p&gt;

&lt;p&gt;Instead of assuming requirements become trustworthy because somebody documented them early, RAD gives &lt;strong&gt;User Participation&lt;/strong&gt; and &lt;strong&gt;Incremental Prototyping&lt;/strong&gt; much more authority. Users see working versions, react, correct assumptions, and shape the next increment. JAD concentrates that interaction. DSDM gives the process structure. Timeboxing stops the schedule from quietly expanding every time scope gets ambitious.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Timebox&lt;/strong&gt; is the least sentimental character here.&lt;/p&gt;

&lt;p&gt;It does not promise that everything will fit.&lt;br&gt;&lt;br&gt;
It promises that time will remain bounded.&lt;/p&gt;

&lt;p&gt;And that reveals the deeper model: RAD is not primarily trying to make developers type faster. It is trying to shorten the distance between an assumption and the moment reality gets to disagree with it.&lt;/p&gt;

&lt;p&gt;That is why prototyping matters.&lt;br&gt;&lt;br&gt;
That is why users matter.&lt;br&gt;&lt;br&gt;
That is why visible progress matters.&lt;/p&gt;

&lt;p&gt;The seductive mistake is assuming rapid delivery means the engineering constraints also became rapid.&lt;/p&gt;

&lt;p&gt;They did not.&lt;/p&gt;

&lt;p&gt;Even early RAD research was cautious about treating the method as universally suitable. Its empirical grounding came from multiple RAD case studies, and the authors explicitly questioned how broadly practitioner claims could be generalized.&lt;/p&gt;

&lt;p&gt;So the first lesson appears earlier than expected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Speed is useful when it accelerates learning. Speed without learning is just faster confidence.&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Executable Mockups: When the Prototype Stops Being a Sketch
&lt;/h3&gt;

&lt;p&gt;Requirements create a particularly nasty version of this problem.&lt;/p&gt;

&lt;p&gt;A written requirement can look precise while two people are imagining different systems.&lt;/p&gt;

&lt;p&gt;Everyone nods.&lt;br&gt;&lt;br&gt;
Everyone leaves.&lt;/p&gt;

&lt;p&gt;The disagreement is still there, just hydrated with meeting notes.&lt;/p&gt;

&lt;p&gt;The natural response is prototyping. But a static mockup still asks the user to imagine behavior.&lt;/p&gt;

&lt;p&gt;The next step is &lt;strong&gt;Executable Mockups&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now the prototype can be operated. A user can move through screens, interact with workflows, and discover that what sounded correct in conversation feels wrong when it becomes behavior.&lt;/p&gt;

&lt;p&gt;That is the reasoning behind Kroki, a model-driven environment investigated for rapid functional requirements elicitation in enterprise applications. Ten joint sessions with domain experts produced prototype specifications containing seven to twenty screen mockups with accompanying domain models within two-hour sessions. The prototypes were also intended to remain reusable later in development rather than becoming disposable sketches.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Executable Mockup&lt;/strong&gt; is basically the Prototype after it gains a voice.&lt;/p&gt;

&lt;p&gt;Instead of saying, “Imagine this workflow,” it says, “Use me.”&lt;/p&gt;

&lt;p&gt;That is much harder to misunderstand.&lt;/p&gt;

&lt;p&gt;But then the boundary appears.&lt;/p&gt;

&lt;p&gt;Executable mockups are strongest around functional requirements and business interaction. They do not magically settle performance, security, scalability, architecture, or other non-functional concerns. The approach explicitly separates those concerns from the functional mockup process.&lt;/p&gt;

&lt;p&gt;And this is where visible progress starts lying to us a little.&lt;/p&gt;

&lt;p&gt;Not maliciously.&lt;/p&gt;

&lt;p&gt;A working interface simply &lt;em&gt;looks&lt;/em&gt; more complete than the underlying engineering actually is.&lt;/p&gt;

&lt;p&gt;The UI is alive. The buttons work. The workflow moves.&lt;/p&gt;

&lt;p&gt;Meanwhile, the non-functional requirements are standing outside the room wondering why nobody invited them.&lt;/p&gt;

&lt;p&gt;The system is not broken.&lt;/p&gt;

&lt;p&gt;Our definition of &lt;em&gt;“working”&lt;/em&gt; was too small.&lt;/p&gt;




&lt;h3&gt;
  
  
  Low-Code/No-Code: What If the Platform Just Builds the Boring Parts?
&lt;/h3&gt;

&lt;p&gt;Once rapid prototyping works, the next question is almost inevitable.&lt;/p&gt;

&lt;p&gt;Why stop at the prototype?&lt;/p&gt;

&lt;p&gt;If screens, workflows, data structures, and repeated application patterns are predictable enough, why keep implementing them manually?&lt;/p&gt;

&lt;p&gt;Enter &lt;strong&gt;Low-Code&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Low-code development uses visual development tools, predefined components, and automation to reduce reliance on manual coding. It also allows people with limited programming expertise to participate more directly alongside IT professionals, shrinking the translation distance between business requirements and software.&lt;/p&gt;

&lt;p&gt;This is classical RAD’s dream with better tooling.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User involvement? Closer.&lt;/li&gt;
&lt;li&gt;Iteration? Faster.&lt;/li&gt;
&lt;li&gt;Reusable components? Already waiting.&lt;/li&gt;
&lt;li&gt;Workflow construction? Visual.&lt;/li&gt;
&lt;li&gt;Deployment friction? Often reduced.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a moment, it feels like complexity has finally been mugged in a parking lot.&lt;/p&gt;

&lt;p&gt;Then it turns up at the next meeting wearing a platform administrator badge.&lt;/p&gt;

&lt;p&gt;Because Low-Code does not delete complexity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It relocates it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The developer writes less repetitive code because the platform has already made decisions about components, data structures, execution models, integrations, deployment, and extension points.&lt;/p&gt;

&lt;p&gt;That is wonderful while your system agrees with those decisions.&lt;/p&gt;

&lt;p&gt;Then one requirement arrives sideways.&lt;br&gt;&lt;br&gt;
Then an integration does not fit.&lt;br&gt;&lt;br&gt;
Then the abstraction needs an escape hatch.&lt;br&gt;&lt;br&gt;
Then the escape hatch becomes half the application.&lt;/p&gt;

&lt;p&gt;The comprehensive low-code literature identifies both the attraction — visual development, reusable components, automation, faster delivery, and closer business/IT collaboration — and the challenges that accompany platform-based development.&lt;/p&gt;

&lt;p&gt;The shortcut was real.&lt;br&gt;&lt;br&gt;
&lt;em&gt;So were its boundaries.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Model-Driven Engineering: The Character Doing the Heavy Lifting Backstage
&lt;/h3&gt;

&lt;p&gt;Low-Code gets most of the attention because it is visible.&lt;/p&gt;

&lt;p&gt;Drag this.&lt;br&gt;&lt;br&gt;
Configure that.&lt;br&gt;&lt;br&gt;
Generate the application.&lt;/p&gt;

&lt;p&gt;But the deeper technical question is more interesting:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why can the platform generate so much in the first place?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;Model-Driven Engineering&lt;/strong&gt; walks quietly into the story.&lt;/p&gt;

&lt;p&gt;MDE changes the level at which developers describe the system. Instead of manually encoding every implementation detail, important parts of the application are represented through higher-level models and abstractions that tooling can interpret, transform, or execute.&lt;/p&gt;

&lt;p&gt;A multi-vocal systematic review of low-code development specifically examined its relationship with MDE, identifying modelling and model-driven techniques as central to understanding low-code development rather than treating it as glorified drag-and-drop.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Model&lt;/strong&gt; is demanding in a different way.&lt;/p&gt;

&lt;p&gt;It says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Tell me what this thing &lt;em&gt;means&lt;/em&gt;.&lt;br&gt;&lt;br&gt;
Stop making me watch you rebuild the plumbing.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When the domain fits the abstraction, this is absurdly powerful.&lt;/p&gt;

&lt;p&gt;Repeated structure disappears into automation. Visual models become executable behavior. Platform services absorb implementation work. Developers operate closer to business concepts and further away from boilerplate.&lt;/p&gt;

&lt;p&gt;But an abstraction is a contract.&lt;/p&gt;

&lt;p&gt;The system gets speed by agreeing to speak the platform’s language.&lt;/p&gt;

&lt;p&gt;When the domain speaks that language fluently, everybody looks brilliant.&lt;br&gt;&lt;br&gt;
When the domain develops a heavy accent, things get expensive.&lt;/p&gt;

&lt;p&gt;And now the real source of rapidity becomes visible:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;RAD gets faster by moving work upward, from implementation detail toward reusable knowledge.&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Productivity: The Number That Looks Like It Ends the Argument
&lt;/h3&gt;

&lt;p&gt;This is normally where someone asks the dangerous question.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Fine.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;How much faster?&lt;/p&gt;

&lt;p&gt;The NexusBRaNT comparison gives the kind of answer that can accidentally end a meeting too early.&lt;/p&gt;

&lt;p&gt;A traditional implementation required &lt;strong&gt;888 hours&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The low-code implementation required &lt;strong&gt;47.5 hours&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A reported &lt;strong&gt;94.63% reduction in effort&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That is not a subtle difference.&lt;/p&gt;

&lt;p&gt;It is the kind of difference that makes hand-coding look personally irresponsible.&lt;/p&gt;

&lt;p&gt;But context immediately starts tapping the microphone.&lt;/p&gt;

&lt;p&gt;The comparison involved a specific information and workflow system, a specific low-code environment, particular abstractions, and developers with different experience conditions. The result demonstrates that enormous effort reductions are possible when the problem aligns with the platform — not that every system contains a hidden 94.63% discount code.&lt;/p&gt;

&lt;p&gt;This distinction matters.&lt;/p&gt;

&lt;p&gt;Because the seductive wrong conclusion is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Low-code is faster.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The useful conclusion is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Low-code can be dramatically faster when the platform already understands enough of the problem that developers do not have to rebuild its recurring structure manually.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That is a much more interesting claim.&lt;br&gt;&lt;br&gt;
And a much less marketable one.&lt;/p&gt;




&lt;h3&gt;
  
  
  Citizen Development: Easy to Build Is Not Easy to Own
&lt;/h3&gt;

&lt;p&gt;Once platforms reduce the amount of programming expertise required, another boundary starts moving.&lt;/p&gt;

&lt;p&gt;Who counts as a developer?&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Citizen Developer&lt;/strong&gt; has domain knowledge, a local problem, and suddenly a tool capable of turning that knowledge into software without waiting for the traditional development queue.&lt;/p&gt;

&lt;p&gt;This sounds like RAD reaching its final form.&lt;/p&gt;

&lt;p&gt;The people closest to the problem can build the solution.&lt;/p&gt;

&lt;p&gt;What could possibly go wrong?&lt;/p&gt;

&lt;p&gt;Governance clears its throat.&lt;/p&gt;

&lt;p&gt;Research across 24 organizations adopting low-code/no-code citizen development found that successful adoption involves far more than access to tooling. Security, compliance, organizational change, architecture, strategy, policies, training, and coordination all become part of the problem.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Citizen Developer&lt;/strong&gt; wants to solve today’s workflow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Governance&lt;/strong&gt; wants to know who owns the application next year.&lt;/p&gt;

&lt;p&gt;The Citizen Developer sees a local optimization.&lt;/p&gt;

&lt;p&gt;Governance sees an application portfolio.&lt;/p&gt;

&lt;p&gt;The Citizen Developer sees speed.&lt;/p&gt;

&lt;p&gt;Governance sees security, compliance, duplication, maintenance, retirement, and the faint outline of Shadow IT waving from across the building.&lt;/p&gt;

&lt;p&gt;Neither is wrong.&lt;/p&gt;

&lt;p&gt;They are looking at different lifecycles.&lt;/p&gt;

&lt;p&gt;This reveals one of modern RAD’s more uncomfortable rules:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The easier software becomes to create locally, the more deliberate organizations must become globally.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ease of development is not ease of stewardship.&lt;/p&gt;

&lt;p&gt;Low-code democratizes construction.&lt;/p&gt;

&lt;p&gt;It does not democratize consequences away.&lt;/p&gt;




&lt;h3&gt;
  
  
  Lean Startup: Building Faster Does Not Tell You What Deserves to Exist
&lt;/h3&gt;

&lt;p&gt;There is still a larger failure mode.&lt;/p&gt;

&lt;p&gt;Suppose the process is rapid.&lt;/p&gt;

&lt;p&gt;The prototypes are executable.&lt;/p&gt;

&lt;p&gt;The platform is productive.&lt;/p&gt;

&lt;p&gt;The team can generate working software almost offensively quickly.&lt;/p&gt;

&lt;p&gt;And the idea is wrong.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Now what?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Early-stage software startups make this constraint impossible to ignore because they operate under high uncertainty. The challenge is not merely implementing a known solution efficiently; it is discovering whether the problem, customer, solution, and product direction are worth pursuing at all. The Early Stage Software Startup Development Model applies lean principles around idea exploration, validation, and learning in precisely that environment.&lt;/p&gt;

&lt;p&gt;Here, &lt;strong&gt;Speed&lt;/strong&gt; finally gets demoted.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Learning&lt;/strong&gt; becomes the authority.&lt;/p&gt;

&lt;p&gt;A prototype is valuable because it tests an assumption.&lt;/p&gt;

&lt;p&gt;An MVP is valuable because it exposes reality.&lt;/p&gt;

&lt;p&gt;An iteration is valuable because it changes what the team knows.&lt;/p&gt;

&lt;p&gt;Otherwise, rapid development simply lets us become wrong at higher throughput.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fast delivery to the wrong problem is not a RAD success.&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  AI-Assisted Development: The Shortcut Starts Writing Back
&lt;/h3&gt;

&lt;p&gt;Then we reach the newest acceleration layer.&lt;/p&gt;

&lt;p&gt;Low-Code reduced how much implementation developers had to express manually.&lt;/p&gt;

&lt;p&gt;AI-assisted development asks whether some of that remaining expression can come from natural language.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;AI Assistant&lt;/strong&gt; is ridiculously fast.&lt;/p&gt;

&lt;p&gt;It can suggest code, recall syntax, generate tests, help with refactoring, and support documentation-heavy tasks.&lt;/p&gt;

&lt;p&gt;Developers surveyed about AI programming assistants reported motivations such as reducing keystrokes, completing programming tasks quickly, and recalling syntax. But the same study found major reasons for rejection: generated code may fail functional or non-functional requirements, and developers can struggle to control the assistant into producing the intended result.&lt;/p&gt;

&lt;p&gt;That combination is the entire AI-assisted RAD tension in miniature.&lt;/p&gt;

&lt;p&gt;It is fast.&lt;/p&gt;

&lt;p&gt;Then context matters.&lt;/p&gt;

&lt;p&gt;It is helpful.&lt;/p&gt;

&lt;p&gt;Then authority matters.&lt;/p&gt;

&lt;p&gt;It produces code.&lt;/p&gt;

&lt;p&gt;Then correctness asks who approved it.&lt;/p&gt;

&lt;p&gt;The AI Assistant is not exactly lying to us.&lt;/p&gt;

&lt;p&gt;It is more like an extremely confident colleague who sometimes joins the conversation halfway through.&lt;/p&gt;

&lt;p&gt;The deeper model is the same one that keeps appearing throughout this journey: reducing artifact-production effort does not remove the need to understand the system.&lt;/p&gt;

&lt;p&gt;It changes where human effort goes.&lt;/p&gt;

&lt;p&gt;Less typing.&lt;/p&gt;

&lt;p&gt;More framing.&lt;br&gt;&lt;br&gt;
More context.&lt;br&gt;&lt;br&gt;
More review.&lt;br&gt;&lt;br&gt;
More validation.&lt;br&gt;&lt;br&gt;
More deciding whether the result actually belongs in the architecture.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Hidden Constraint Was Never Development Speed
&lt;/h3&gt;

&lt;p&gt;Now the pattern becomes difficult to ignore.&lt;/p&gt;

&lt;p&gt;Classical RAD shortened the feedback cycle.&lt;/p&gt;

&lt;p&gt;Executable mockups shortened the distance between requirements and something users could operate.&lt;/p&gt;

&lt;p&gt;Low-Code shortened the distance between models and applications.&lt;/p&gt;

&lt;p&gt;MDE shortened the distance between abstraction and implementation.&lt;/p&gt;

&lt;p&gt;Citizen development shortened the distance between business expertise and software construction.&lt;/p&gt;

&lt;p&gt;AI shortened the distance between intent and generated artifacts.&lt;/p&gt;

&lt;p&gt;Every generation removed friction.&lt;/p&gt;

&lt;p&gt;And every generation exposed another boundary.&lt;/p&gt;

&lt;p&gt;Maintainability.&lt;br&gt;&lt;br&gt;
Integration.&lt;br&gt;&lt;br&gt;
Governance.&lt;br&gt;&lt;br&gt;
Non-functional requirements.&lt;br&gt;&lt;br&gt;
Architecture.&lt;br&gt;&lt;br&gt;
Reliability.&lt;br&gt;&lt;br&gt;
Context.&lt;/p&gt;

&lt;p&gt;The mistake is thinking the next tool finally removes software engineering from software development.&lt;/p&gt;

&lt;p&gt;It does not.&lt;br&gt;&lt;br&gt;
It moves the engineering attention toward whatever even The Origami Software Engineer cannot safely leave to the tool.&lt;/p&gt;

&lt;p&gt;That is why there is no universal &lt;strong&gt;&lt;em&gt;“best RAD tool”.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A workflow-heavy internal system may align beautifully with low-code.&lt;/p&gt;

&lt;p&gt;A requirements-heavy business application may benefit enormously from executable mockups.&lt;/p&gt;

&lt;p&gt;A model-intensive information system may fit MDE-backed automation.&lt;/p&gt;

&lt;p&gt;A citizen-development program may work only when governance grows alongside participation.&lt;/p&gt;

&lt;p&gt;A startup may need rapid experimentation more than rapid production.&lt;/p&gt;

&lt;p&gt;A developer-led system may benefit from AI assistance precisely where the tasks are bounded enough to review.&lt;/p&gt;

&lt;p&gt;The architecture starts making sense once we stop asking which tool is fastest and start asking &lt;strong&gt;which constraints the tool is allowed to hide&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  RAD Did Not Disappear. It Kept Changing Where the Work Lived
&lt;/h3&gt;

&lt;p&gt;Classical RAD began with a remarkably durable idea:&lt;/p&gt;

&lt;p&gt;Get working software in front of reality sooner.&lt;/p&gt;

&lt;p&gt;Everything that followed kept finding new ways to do that.&lt;/p&gt;

&lt;p&gt;The Prototype became executable.&lt;br&gt;&lt;br&gt;
The Tool became a platform.&lt;br&gt;&lt;br&gt;
The Platform became model-driven.&lt;br&gt;&lt;br&gt;
The User became a Citizen Developer.&lt;br&gt;&lt;br&gt;
The coding assistant became conversational.&lt;/p&gt;

&lt;p&gt;And each step looked, briefly, like the old complexity had vanished.&lt;/p&gt;

&lt;p&gt;It had not.&lt;br&gt;&lt;br&gt;
It had moved.&lt;/p&gt;

&lt;p&gt;From implementation into abstraction.&lt;br&gt;&lt;br&gt;
From construction into governance.&lt;br&gt;&lt;br&gt;
From syntax into context.&lt;br&gt;&lt;br&gt;
From producing artifacts into deciding whether those artifacts are correct, maintainable, secure, and worth building at all.&lt;/p&gt;

&lt;p&gt;That is the part of rapid development that survives every generation.&lt;/p&gt;

&lt;p&gt;Not &lt;em&gt;“go faster”.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Learn sooner, automate what has become predictable, and keep human attention on the constraints that have not.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That’s not failure.&lt;br&gt;&lt;br&gt;
That’s evolution.&lt;/p&gt;




&lt;h3&gt;
  
  
  The “I liked this” Starter Pack:
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Don’t let your fingers get lazy now.
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Like :&lt;/strong&gt; It tells me this was worth writing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A Comment:&lt;/strong&gt; Tell me your thoughts, your favorite snack, or a better title for this blog.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Boost it:&lt;/strong&gt; Especially with that one developer who definitely needs this.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Thanks for being here. It genuinely helps more than you know!&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;— Aaroophan Varatharajan&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Find me elsewhere:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Professional stuff:&lt;/strong&gt; &lt;a href="http://linkedin.com/in/Aaroophan" rel="noopener noreferrer"&gt;linkedin.com/in/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code stuff:&lt;/strong&gt; &lt;a href="http://github.com/Aaroophan" rel="noopener noreferrer"&gt;github.com/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UI stuff:&lt;/strong&gt; &lt;a href="https://aaroophan.dev/Aaroophan" rel="noopener noreferrer"&gt;aaroophan.dev/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Life stuff:&lt;/strong&gt; &lt;a href="http://instagram.com/aaroophan" rel="noopener noreferrer"&gt;instagram.com/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Before you go
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Please take a moment to like the post and follow the writer!&lt;/li&gt;
&lt;li&gt;Did you know that over 400,000 developers share what they’re building, learning, and discovering across our platforms every month? Learn how you can contribute &lt;a href="https://plainenglish.io/write-for-us" rel="noopener noreferrer"&gt;&lt;strong&gt;here&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>systemdesignconcepts</category>
      <category>softwareengineering</category>
      <category>softwaredevelopment</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>How Do Strangers Agree on One History?: Rethinking Distributed Computing #14</title>
      <dc:creator>Aaroophan Varatharajan</dc:creator>
      <pubDate>Mon, 21 Sep 2026 06:46:01 +0000</pubDate>
      <link>https://dev.to/aaroophan/how-do-strangers-agree-on-one-history-rethinking-distributed-computing-14-264c</link>
      <guid>https://dev.to/aaroophan/how-do-strangers-agree-on-one-history-rethinking-distributed-computing-14-264c</guid>
      <description>&lt;h4&gt;
  
  
  &lt;em&gt;Removing the central authority does not remove the need for one accepted history. It just makes the network responsible for deciding which history deserves to survive.&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqlm3ysara98xxxiwjqmq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqlm3ysara98xxxiwjqmq.png" alt="How blockchain consensus works: distributed ledgers, double spending, digital signatures, cryptographic hashes, Proof of Work, mining, forks, chain selection, confirmations, network partitions, and decentralized consensus." width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;"How blockchain consensus works: distributed ledgers, double spending, digital signatures, cryptographic hashes, Proof of Work, mining, forks, chain selection, confirmations, network partitions, and decentralized consensus."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Suppose Alice, Bob, and Peter exchange value with one another.&lt;/p&gt;

&lt;p&gt;We could move physical money every time.&lt;br&gt;&lt;br&gt;
Or we could maintain a  &lt;strong&gt;ledger&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Alice pays Bob 300&lt;/li&gt;
&lt;li&gt;Bob pays Peter 100&lt;/li&gt;
&lt;li&gt;Peter pays Alice 50&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The ledger records the history of transactions, and the current balances can be derived from that history.&lt;/p&gt;

&lt;p&gt;Banks already make this idea feel &lt;strong&gt;&lt;em&gt;✨ordinary✨&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The important part is not really the rows.&lt;br&gt;&lt;br&gt;
It is &lt;strong&gt;who is allowed to add them&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In a traditional system, some trusted institution owns the ledger.&lt;/p&gt;

&lt;p&gt;Alice cannot simply write: &lt;strong&gt;Alice receives 10,000 from nowhere&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
and declare herself richer.&lt;/p&gt;

&lt;p&gt;The authority validates transactions, controls updates, and provides one accepted version of history.&lt;/p&gt;

&lt;p&gt;That gives us something extremely valuable:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;There is one place to ask what happened.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then distributed computing asks the dangerous question.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What if we remove that place?&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Replicate the Ledger Everywhere
&lt;/h3&gt;

&lt;p&gt;A centralized ledger comes with familiar problems.&lt;/p&gt;

&lt;p&gt;One authority controls it.&lt;br&gt;&lt;br&gt;
One infrastructure operates it.&lt;/p&gt;

&lt;p&gt;Its availability depends heavily on that infrastructure.&lt;/p&gt;

&lt;p&gt;So imagine replicating the ledger across many independent nodes.&lt;/p&gt;

&lt;p&gt;Now many participants hold copies.&lt;/p&gt;

&lt;p&gt;The history no longer lives in one place.&lt;/p&gt;

&lt;p&gt;That sounds wonderfully resilient.&lt;/p&gt;

&lt;p&gt;NIST describes blockchain systems in this general form: a shared digital ledger maintained in a distributed fashion, with transactions grouped into blocks, cryptographically linked, replicated across network participants, and conflicts resolved according to established consensus rules.&lt;/p&gt;

&lt;p&gt;So far, this looks like straightforward replication.&lt;/p&gt;

&lt;p&gt;Alice transfers &lt;strong&gt;300&lt;/strong&gt; to Bob.&lt;/p&gt;

&lt;p&gt;Every ledger copy eventually records:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Alice: 500 → 200&lt;/li&gt;
&lt;li&gt;Bob: 1000 → 1300&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Easy.&lt;/p&gt;

&lt;p&gt;Until the copies stop agreeing.&lt;/p&gt;

&lt;p&gt;Because distributing the ledger did not distribute one magical global view of reality.&lt;/p&gt;

&lt;p&gt;It created &lt;strong&gt;multiple machines capable of observing different things at different times&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And now the central authority is no longer there to settle the argument.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Network Splits, and Alice Finds Two Realities
&lt;/h3&gt;

&lt;p&gt;Suppose Alice begins with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Alice = 500&lt;/li&gt;
&lt;li&gt;Bob = 1000&lt;/li&gt;
&lt;li&gt;Peter = 500&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Alice sends: &lt;strong&gt;Transfer 300 to Bob&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One part of the network sees it.&lt;/p&gt;

&lt;p&gt;That ledger becomes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Alice = 200&lt;/li&gt;
&lt;li&gt;Bob = 1300&lt;/li&gt;
&lt;li&gt;Peter = 500&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now imagine a network partition.&lt;/p&gt;

&lt;p&gt;Another group of nodes cannot see that transaction yet.&lt;/p&gt;

&lt;p&gt;From their point of view, Alice still owns:  &lt;strong&gt;500&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So Alice sends another transaction: &lt;strong&gt;Transfer 400 to Peter&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That side accepts it.&lt;/p&gt;

&lt;p&gt;Its ledger becomes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Alice = 100&lt;/li&gt;
&lt;li&gt;Bob = 1000&lt;/li&gt;
&lt;li&gt;Peter = 900&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Now pause.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Alice started with &lt;strong&gt;500&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
One history says she spent &lt;strong&gt;300&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Another says she spent  &lt;strong&gt;400&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If both histories survive, she has successfully spent: &lt;strong&gt;700&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
from a balance of:  &lt;strong&gt;500&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Nothing about copying the ledger prevented this.&lt;/p&gt;

&lt;p&gt;In fact, replication created the conditions in which two groups could each believe a conflicting transaction was valid.&lt;/p&gt;

&lt;p&gt;This is the &lt;strong&gt;double-spending problem&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And it exposes the actual problem blockchain has to solve.&lt;/p&gt;

&lt;p&gt;Not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;How do we store transactions on many machines?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;How do many machines agree on which sequence of transactions counts as the history?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Bitcoin’s original design begins from exactly this difficulty: digital signatures can establish authorization, but a peer-to-peer system still needs a way to prevent the same value from being spent through conflicting histories without relying on a trusted third party.&lt;/p&gt;




&lt;h3&gt;
  
  
  Signatures Tell Us Who Authorized Something, Not Which History Won
&lt;/h3&gt;

&lt;p&gt;Public-key cryptography helps.&lt;br&gt;&lt;br&gt;
Alice possesses a private key.&lt;/p&gt;

&lt;p&gt;She can digitally sign a transaction.&lt;/p&gt;

&lt;p&gt;Other participants can verify that signature using the corresponding public information.&lt;/p&gt;

&lt;p&gt;So Alice cannot casually spend Bob’s value merely by writing: &lt;strong&gt;Bob pays Alice 500&lt;/strong&gt; without the authorization required by the system.&lt;/p&gt;

&lt;p&gt;Good.&lt;/p&gt;

&lt;p&gt;But signatures do not solve everything.&lt;/p&gt;

&lt;p&gt;Alice can legitimately sign two conflicting transactions involving value she controls.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Alice → Bob 300&lt;/li&gt;
&lt;li&gt;Alice → Peter 400&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both signatures can be perfectly valid.&lt;/p&gt;

&lt;p&gt;Cryptography can answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Did Alice authorize this transaction?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It does not automatically answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Which of Alice’s conflicting transactions belongs in the accepted history?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is a consensus problem.&lt;/p&gt;

&lt;p&gt;The network needs something stronger than authentication.&lt;/p&gt;

&lt;p&gt;It needs &lt;strong&gt;ordering&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Put Transactions Into Blocks, Then Make History Tamper With Itself
&lt;/h3&gt;

&lt;p&gt;Instead of treating the ledger as unrelated lines, group transactions into  &lt;strong&gt;blocks&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Then link each block to the previous one using a cryptographic hash.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Block 100
↓ hash&lt;/li&gt;
&lt;li&gt;Block 101
↓ hash&lt;/li&gt;
&lt;li&gt;Block 102&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each block includes information derived from the previous block.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Change Block 100 and its hash changes.&lt;/li&gt;
&lt;li&gt;Then Block 101’s reference no longer matches.&lt;/li&gt;
&lt;li&gt;Fix Block 101 and its hash changes too.&lt;/li&gt;
&lt;li&gt;Now Block 102 has to change.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And so on.&lt;/p&gt;

&lt;p&gt;NIST describes this as the fundamental tamper-evident property of a blockchain: blocks are cryptographically linked to their predecessors, so altering older data changes those links and affects the chain that follows.&lt;/p&gt;

&lt;p&gt;This gives history structure.&lt;/p&gt;

&lt;p&gt;But there is still a missing piece.&lt;/p&gt;

&lt;p&gt;Anyone can calculate hashes.&lt;/p&gt;

&lt;p&gt;If producing a new valid block is cheap, a malicious participant could simply create an alternative sequence quickly.&lt;/p&gt;

&lt;p&gt;So we need to make &lt;strong&gt;extending history costly&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Make the Right to Extend History Expensive to Produce and Cheap to Verify
&lt;/h3&gt;

&lt;p&gt;Enter &lt;strong&gt;Proof of Work&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The idea feels backward at first.&lt;/p&gt;

&lt;p&gt;Normally, computing systems try to make work cheaper.&lt;/p&gt;

&lt;p&gt;Proof of Work deliberately asks participants to perform computation that is: &lt;strong&gt;difficult to produce, but easy for everyone else to verify.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For Bitcoin, a miner varies a value called a nonce while hashing block data, searching for an output that satisfies the current difficulty requirement.&lt;/p&gt;

&lt;p&gt;There is no known shortcut that simply reveals the successful nonce.&lt;/p&gt;

&lt;p&gt;You try. Hash. Try again. Hash. Again.&lt;/p&gt;

&lt;p&gt;Eventually someone finds a valid result.&lt;/p&gt;

&lt;p&gt;Everyone else can check it quickly.&lt;/p&gt;

&lt;p&gt;Bitcoin’s Proof of Work is built around precisely this asymmetry: finding a suitable hash requires repeated computation, while verifying the resulting proof requires little work.&lt;/p&gt;

&lt;p&gt;The network has created a strange kind of authority.&lt;/p&gt;

&lt;p&gt;Nobody is appointed permanently.&lt;br&gt;&lt;br&gt;
Nobody is inherently trusted.&lt;/p&gt;

&lt;p&gt;Anyone may compete.&lt;/p&gt;

&lt;p&gt;But proposing the next block now requires evidence that computational work was actually performed.&lt;/p&gt;

&lt;p&gt;You cannot merely shout:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;My history wins.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You have to bring receipts.&lt;/p&gt;




&lt;h3&gt;
  
  
  The First Valid Block Still Does Not Give Us Permanent Truth
&lt;/h3&gt;

&lt;p&gt;Suppose two miners solve the Proof-of-Work problem at nearly the same time.&lt;/p&gt;

&lt;p&gt;Miner A broadcasts:  &lt;strong&gt;… → Block X&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Miner B broadcasts:  &lt;strong&gt;… → Block Y&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Both blocks extend the same previous block.&lt;br&gt;&lt;br&gt;
Both may contain valid transactions.&lt;br&gt;&lt;br&gt;
Both may contain valid Proof of Work.&lt;/p&gt;

&lt;p&gt;Some nodes hear about X first.&lt;/p&gt;

&lt;p&gt;Others hear about Y first.&lt;/p&gt;

&lt;p&gt;Now we have:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxbp1xxb7zj6qpmzcrw3i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxbp1xxb7zj6qpmzcrw3i.png" alt="We built a system whose entire purpose was to maintain one ledger, and it has produced **two truths**." width="800" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Excellent.&lt;/p&gt;

&lt;p&gt;We built a system whose entire purpose was to maintain one ledger, and it has produced &lt;strong&gt;two truths&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For a while.&lt;/p&gt;

&lt;p&gt;And that last phrase matters.&lt;/p&gt;

&lt;p&gt;Bitcoin explicitly allows temporary competing branches. Nodes can initially work on whichever valid branch they learned about first while retaining knowledge of the alternative.&lt;/p&gt;

&lt;p&gt;The system does not guarantee that every node sees the same newest block at the same instant.&lt;/p&gt;

&lt;p&gt;That would be difficult in a distributed network.&lt;/p&gt;

&lt;p&gt;Instead, it gives the disagreement somewhere to go.&lt;/p&gt;




&lt;h3&gt;
  
  
  Keep Building, and Make the Competition Resolve Itself
&lt;/h3&gt;

&lt;p&gt;Now another miner finds the next valid block.&lt;/p&gt;

&lt;p&gt;Suppose it builds on X:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcce21a6qn7aakoqhu0bv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcce21a6qn7aakoqhu0bv.png" alt="The longest chain wins." width="800" height="157"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The X branch now represents more accepted Proof-of-Work history.&lt;/p&gt;

&lt;p&gt;Nodes following Y can see that the competing branch has moved ahead.&lt;/p&gt;

&lt;p&gt;So they switch.&lt;/p&gt;

&lt;p&gt;Traditionally, this is described as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;The longest chain wins.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;More precisely in modern Bitcoin implementations, nodes prefer the valid chain with the greatest accumulated Proof of Work rather than merely counting blocks. The older “longest chain” wording is useful intuition because the winning chain represents the branch backed by the greatest demonstrated work.&lt;/p&gt;

&lt;p&gt;This is the clever part.&lt;/p&gt;

&lt;p&gt;There is no global coordinator sending:&lt;br&gt;&lt;br&gt;
&lt;strong&gt;ATTENTION EVERYONE: X IS NOW OFFICIAL&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Participants follow the same deterministic rule.&lt;/p&gt;

&lt;p&gt;So as one valid branch accumulates more work, rational participants have reason to build on that branch rather than invest computation into a history that is increasingly likely to be discarded.&lt;/p&gt;

&lt;p&gt;Agreement emerges from everyone following the same rule for &lt;strong&gt;which history deserves further work&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Losing History Does Not Get to Keep Its Transactions
&lt;/h3&gt;

&lt;p&gt;Now consider what happens to a transaction that existed only inside Y.&lt;/p&gt;

&lt;p&gt;Perhaps Alice’s payment to Peter was there.&lt;/p&gt;

&lt;p&gt;If the network converges on X, Y is no longer part of the accepted chain.&lt;/p&gt;

&lt;p&gt;That transaction may therefore no longer be considered confirmed in the ledger history.&lt;/p&gt;

&lt;p&gt;This is why seeing a transaction inside one block is not the same thing as receiving an eternal commitment from the universe.&lt;/p&gt;

&lt;p&gt;A newer competing history can temporarily replace what a node previously believed was the best history.&lt;/p&gt;

&lt;p&gt;Bitcoin’s developer documentation makes the consequence explicit: recently confirmed transactions carry more double-spend risk because recent blocks can occasionally be replaced when competing branches are resolved.&lt;/p&gt;

&lt;p&gt;This can feel wrong if we bring database intuition with us.&lt;/p&gt;

&lt;p&gt;In a conventional transaction system &lt;strong&gt;COMMIT&lt;/strong&gt; usually means the transaction crossed a fairly crisp boundary.&lt;/p&gt;

&lt;p&gt;In Proof-of-Work blockchain consensus, confidence can be &lt;strong&gt;probabilistic&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;One block gives some confidence.&lt;/p&gt;

&lt;p&gt;Another block built on top gives more.&lt;br&gt;&lt;br&gt;
Then another.&lt;br&gt;&lt;br&gt;
Then another.&lt;/p&gt;

&lt;p&gt;The transaction becomes progressively harder to replace because replacing it requires rebuilding the work behind its block and catching up with the continuing chain.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;“commit point”&lt;/em&gt; has turned into a slope.&lt;/p&gt;




&lt;h3&gt;
  
  
  Confirmations Are Confidence Accumulating Behind You
&lt;/h3&gt;

&lt;p&gt;Suppose Alice pays Bob.&lt;/p&gt;

&lt;p&gt;The transaction enters a block.&lt;/p&gt;

&lt;p&gt;That block now has: &lt;strong&gt;1 confirmation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A new block is added after it.&lt;/p&gt;

&lt;p&gt;Now: &lt;strong&gt;2 confirmations&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;More blocks accumulate: &lt;strong&gt;3&lt;/strong&gt; , &lt;strong&gt;4&lt;/strong&gt; , &lt;strong&gt;5&lt;/strong&gt; ,  &lt;strong&gt;6&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each additional block represents more Proof of Work layered on top of the history containing Alice’s transaction.&lt;/p&gt;

&lt;p&gt;An attacker trying to replace that transaction must construct a competing history and overcome the accumulated work of the chain that honest participants continue extending.&lt;/p&gt;

&lt;p&gt;This is why systems can wait for additional confirmations before treating a transaction as sufficiently settled.&lt;/p&gt;

&lt;p&gt;Bitcoin developer guidance historically uses six confirmations as an example of a transaction buried beneath substantial additional work, reducing the practical double-spend risk compared with a transaction that has only just appeared.&lt;/p&gt;

&lt;p&gt;Notice what the system is saying.&lt;/p&gt;

&lt;p&gt;Not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Six means mathematically impossible to reverse.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The deeper this transaction sits beneath continuing Proof of Work, the harder replacing that history becomes.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Persistence is being built incrementally.&lt;/p&gt;




&lt;h3&gt;
  
  
  Proof of Work Is Slow Because the Difficulty Is Doing a Job
&lt;/h3&gt;

&lt;p&gt;At this point, Proof of Work looks wasteful.&lt;/p&gt;

&lt;p&gt;Participants perform huge amounts of computation merely to find a value satisfying a hash condition.&lt;/p&gt;

&lt;p&gt;Then everyone throws away almost all the failed attempts.&lt;/p&gt;

&lt;p&gt;Why deliberately make something slow and expensive?&lt;/p&gt;

&lt;p&gt;Because if valid history were cheap to manufacture, conflicting histories would also be cheap to manufacture.&lt;/p&gt;

&lt;p&gt;The computational difficulty creates a cost for rewriting the past.&lt;/p&gt;

&lt;p&gt;Once a block has been accepted and more blocks have accumulated after it, changing that block means reconstructing the Proof of Work for that block and its successors while the rest of the network continues extending the competing chain. Bitcoin’s design relies on exactly this asymmetry.&lt;/p&gt;

&lt;p&gt;So the slowness is not an accidental performance bug.&lt;/p&gt;

&lt;p&gt;It is part of the security model.&lt;/p&gt;

&lt;p&gt;Of course, that creates a trade-off.&lt;/p&gt;

&lt;p&gt;Transactions want to be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fast,&lt;/li&gt;
&lt;li&gt;persistent,&lt;/li&gt;
&lt;li&gt;and inexpensive.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Proof of Work obtains stronger confidence by deliberately making block production costly.&lt;/p&gt;

&lt;p&gt;The protocol is buying resistance to cheap history rewriting with computation and time.&lt;/p&gt;

&lt;p&gt;Distributed systems rarely hand out guarantees for free.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Majority Assumption Was Hiding Underneath Everything
&lt;/h3&gt;

&lt;p&gt;Now suppose an attacker controls enough computational power to build an alternative chain faster than the honest network.&lt;/p&gt;

&lt;p&gt;The chain-selection rule has no magical ability to ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Which history was created by morally good people?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It sees valid transactions, valid hashes, and accumulated Proof of Work.&lt;/p&gt;

&lt;p&gt;If an adversarial group controls the majority of the relevant mining power, it may be able to outpace the honest branch and replace portions of recent history involving its own transactions.&lt;/p&gt;

&lt;p&gt;This is the familiar &lt;strong&gt;51% attack&lt;/strong&gt;  idea.&lt;/p&gt;

&lt;p&gt;The Bitcoin design states its assumption directly: security depends on honest participants collectively controlling more computational power than any cooperating attacker group, so the honest chain grows faster than competing malicious histories.&lt;/p&gt;

&lt;p&gt;This is worth lingering on.&lt;/p&gt;

&lt;p&gt;Blockchain did not eliminate trust assumptions.&lt;/p&gt;

&lt;p&gt;It changed them.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Trust this central bank.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;or:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Trust this database administrator.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;the Proof-of-Work system says something closer to:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Trust that the protocol’s validation rules are followed and that attackers do not control enough computational power to dominate history.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Decentralization did not make trust evaporate.&lt;/p&gt;

&lt;p&gt;It &lt;strong&gt;relocated the trust boundary into the consensus mechanism and its assumptions&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Consensus Does Not Mean Everyone Has the Same View Every Second
&lt;/h3&gt;

&lt;p&gt;This is perhaps the strangest mental shift.&lt;/p&gt;

&lt;p&gt;When we hear &lt;strong&gt;consensus&lt;/strong&gt; , we naturally imagine everyone simultaneously agreeing.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node A: X&lt;/li&gt;
&lt;li&gt;Node B: X&lt;/li&gt;
&lt;li&gt;Node C: X&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Blockchain consensus can spend some time looking more like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node A: X&lt;/li&gt;
&lt;li&gt;Node B: Y&lt;/li&gt;
&lt;li&gt;Node C: X&lt;/li&gt;
&lt;li&gt;Node D: Y&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node A: X → X2&lt;/li&gt;
&lt;li&gt;Node B: X → X2&lt;/li&gt;
&lt;li&gt;Node C: X → X2&lt;/li&gt;
&lt;li&gt;Node D: X → X2&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Temporary disagreement does not automatically mean consensus failed.&lt;/p&gt;

&lt;p&gt;It can be part of the mechanism through which consensus eventually emerges.&lt;/p&gt;

&lt;p&gt;NIST describes blockchain consensus mechanisms as the rules by which distributed participants determine which proposed state becomes accepted, with forks representing temporary divergent histories that must be resolved.&lt;/p&gt;

&lt;p&gt;That is a softer notion of consistency than a single authoritative database gives us.&lt;/p&gt;

&lt;p&gt;But it solves a different problem.&lt;/p&gt;

&lt;p&gt;The participants may not trust one central authority.&lt;/p&gt;

&lt;p&gt;They may join and leave.&lt;br&gt;&lt;br&gt;
They may receive network messages in different orders.&lt;/p&gt;

&lt;p&gt;Some may even behave maliciously.&lt;/p&gt;

&lt;p&gt;The protocol’s job is therefore not necessarily:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Prevent disagreement from ever appearing.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Give disagreement a rule for converging.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is a much more distributed kind of promise.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Blockchain Is Really a History-Selection Machine
&lt;/h3&gt;

&lt;p&gt;It is easy to focus on the visible objects.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Blocks.&lt;/li&gt;
&lt;li&gt;Hashes.&lt;/li&gt;
&lt;li&gt;Nonces.&lt;/li&gt;
&lt;li&gt;Miners.&lt;/li&gt;
&lt;li&gt;Coins.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But underneath them sits one recurring question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Which history should an independent node believe?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The hash chain makes history tamper-evident.&lt;/p&gt;

&lt;p&gt;Digital signatures establish who authorized transactions.&lt;/p&gt;

&lt;p&gt;Proof of Work makes producing candidate history expensive while keeping verification cheap.&lt;/p&gt;

&lt;p&gt;The chain-selection rule tells nodes what to do when multiple candidate histories exist.&lt;/p&gt;

&lt;p&gt;Confirmations let confidence accumulate as more work is built on top.&lt;/p&gt;

&lt;p&gt;The majority-computation assumption explains when that process remains secure against a competing attacker.&lt;/p&gt;

&lt;p&gt;Put together, these mechanisms create something that a centralized ledger gets much more cheaply:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;one history that participants can treat as authoritative enough to continue from.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That is why blockchain is fundamentally a distributed-systems story.&lt;/p&gt;

&lt;p&gt;Timing matters.&lt;br&gt;&lt;br&gt;
Ordering matters.&lt;br&gt;&lt;br&gt;
Network partitions matters.&lt;br&gt;&lt;br&gt;
Consensus matters.&lt;br&gt;&lt;br&gt;
Consistency and availability matters.&lt;br&gt;&lt;br&gt;
The Origami Software Engineer’s peace matters.&lt;/p&gt;

&lt;p&gt;The cryptography protects particular relationships inside the system.&lt;/p&gt;

&lt;p&gt;It does not make the distributed-systems problems disappear.&lt;/p&gt;




&lt;h3&gt;
  
  
  We Removed the Authority, Then Rebuilt What the Authority Used to Give Us
&lt;/h3&gt;

&lt;p&gt;A central ledger gives us several things almost invisibly.&lt;/p&gt;

&lt;p&gt;One place controls updates.&lt;br&gt;&lt;br&gt;
One place orders transactions.&lt;br&gt;&lt;br&gt;
One place rejects double spending.&lt;br&gt;&lt;br&gt;
One place says which history is current.&lt;/p&gt;

&lt;p&gt;Remove that authority and none of those responsibilities disappear.&lt;br&gt;&lt;br&gt;
They become protocol problems.&lt;br&gt;&lt;br&gt;
So the system evolves.&lt;/p&gt;

&lt;p&gt;Replicate the ledger.&lt;br&gt;&lt;br&gt;
Now replicas can disagree.&lt;/p&gt;

&lt;p&gt;Sign transactions.&lt;br&gt;&lt;br&gt;
Now authorization is verifiable, but conflicting authorized transactions can still exist.&lt;/p&gt;

&lt;p&gt;Chain blocks with hashes.&lt;br&gt;&lt;br&gt;
Now history becomes tamper-evident.&lt;/p&gt;

&lt;p&gt;Make new blocks require Proof of Work.&lt;br&gt;&lt;br&gt;
Now producing competing history has a real cost.&lt;/p&gt;

&lt;p&gt;Allow temporary forks.&lt;br&gt;&lt;br&gt;
Now the system can survive nodes learning about valid blocks in different orders.&lt;/p&gt;

&lt;p&gt;Choose the chain with the greatest demonstrated work.&lt;br&gt;&lt;br&gt;
Now independent nodes have a shared rule for convergence.&lt;/p&gt;

&lt;p&gt;Wait for confirmations.&lt;br&gt;&lt;br&gt;
Now persistence becomes progressively stronger instead of instantly absolute.&lt;/p&gt;

&lt;p&gt;Assume honest participants control enough computational power.&lt;br&gt;&lt;br&gt;
Now we can finally state the condition under which that convergence resists an attacker.&lt;/p&gt;

&lt;p&gt;Every mechanism exists because removing the trusted ledger owner exposed another responsibility that the owner used to handle for us.&lt;/p&gt;

&lt;p&gt;That is the deeper lesson.&lt;/p&gt;

&lt;p&gt;Decentralization does not mean &lt;strong&gt;nobody decides&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It means the right to decide is no longer concentrated in one trusted actor.&lt;/p&gt;

&lt;p&gt;The decision has to emerge from rules that independent participants can verify and follow for themselves.&lt;/p&gt;

&lt;p&gt;The strangers do not need to trust one another personally.&lt;/p&gt;

&lt;p&gt;They need enough shared rules to eventually agree on which history is worth continuing.&lt;/p&gt;

&lt;p&gt;That’s not failure.&lt;br&gt;&lt;br&gt;
That’s evolution.&lt;/p&gt;




&lt;h3&gt;
  
  
  The “I liked this” Starter Pack:
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Don’t let your fingers get lazy now.
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Like :&lt;/strong&gt; It tells me this was worth writing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A Comment:&lt;/strong&gt; Tell me your thoughts, your favorite snack, or a better title for this blog.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Boost it:&lt;/strong&gt; Especially with that one developer who definitely needs this.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Thanks for being here. It genuinely helps more than you know!&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;— Aaroophan Varatharajan&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Find me elsewhere:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Professional stuff:&lt;/strong&gt; &lt;a href="http://linkedin.com/in/Aaroophan" rel="noopener noreferrer"&gt;linkedin.com/in/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code stuff:&lt;/strong&gt; &lt;a href="http://github.com/Aaroophan" rel="noopener noreferrer"&gt;github.com/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UI stuff:&lt;/strong&gt; &lt;a href="https://aaroophan.dev/Aaroophan" rel="noopener noreferrer"&gt;aaroophan.dev/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Life stuff:&lt;/strong&gt; &lt;a href="http://instagram.com/aaroophan" rel="noopener noreferrer"&gt;instagram.com/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>distributedsystems</category>
      <category>distributedcomputing</category>
      <category>architecture</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>When COMMIT Stops Being a Local Decision: Rethinking Distributed Computing #13</title>
      <dc:creator>Aaroophan Varatharajan</dc:creator>
      <pubDate>Sat, 19 Sep 2026 07:46:01 +0000</pubDate>
      <link>https://dev.to/aaroophan/when-commit-stops-being-a-local-decision-rethinking-distributed-computing-13-145g</link>
      <guid>https://dev.to/aaroophan/when-commit-stops-being-a-local-decision-rethinking-distributed-computing-13-145g</guid>
      <description>&lt;h4&gt;
  
  
  &lt;em&gt;On one database, commit is a decision. Across several machines, commit becomes an agreement that has to survive failures.&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv87tpnrt441xnumyue3h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv87tpnrt441xnumyue3h.png" alt="How Two-Phase Commit (2PC) coordinates distributed transactions across multiple machines, handling prepare, commit, failures, crash recovery, blocking, and atomicity." width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;"How Two-Phase Commit (2PC) coordinates distributed transactions across multiple machines, handling prepare, commit, failures, crash recovery, blocking, and atomicity."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Consider a transaction on one database.&lt;/p&gt;

&lt;p&gt;Change some data.&lt;/p&gt;

&lt;p&gt;If everything succeeds: &lt;strong&gt;COMMIT&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
If something goes wrong:  &lt;strong&gt;ROLLBACK&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The database owns the relevant state, so there is one &lt;strong&gt;&lt;em&gt;✨obvious✨&lt;/em&gt;&lt;/strong&gt; place where the final decision happens.&lt;/p&gt;

&lt;p&gt;Atomicity feels pleasantly local:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Either all of this transaction becomes permanent, or none of it does.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now spread the data across multiple servers.&lt;/p&gt;

&lt;p&gt;Account A lives on Server 1.&lt;br&gt;&lt;br&gt;
Account B lives on Server 2.&lt;/p&gt;

&lt;p&gt;We want one transaction to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A = A + 1&lt;/li&gt;
&lt;li&gt;B = B - 1&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Logically, this is still &lt;strong&gt;one indivisible transaction&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Physically, two different machines have to modify two different pieces of data.&lt;/p&gt;

&lt;p&gt;And that tiny change ruins the simplicity of  &lt;strong&gt;COMMIT&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Because Server 1 can succeed while Server 2 fails.&lt;/p&gt;

&lt;p&gt;The transaction is logically one thing.&lt;br&gt;&lt;br&gt;
The machines performing it are not.&lt;/p&gt;




&lt;h3&gt;
  
  
  Partial Success Is Worse Than Failure
&lt;/h3&gt;

&lt;p&gt;Suppose a transaction coordinator tells:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Server 1 → add 1 to A&lt;/li&gt;
&lt;li&gt;Server 2 → subtract 1 from B&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both operations execute tentatively.&lt;/p&gt;

&lt;p&gt;Now imagine the simplest possible protocol:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Once you’ve done your part, commit it.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Server 1 commits.&lt;br&gt;&lt;br&gt;
Server 2 crashes before committing.&lt;/p&gt;

&lt;p&gt;We now have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A = A + 1&lt;/li&gt;
&lt;li&gt;B = unchanged&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The system did not merely fail to complete the transaction.&lt;/p&gt;

&lt;p&gt;It completed &lt;strong&gt;half of it permanently&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That is much worse.&lt;/p&gt;

&lt;p&gt;If neither side had committed, we could simply tell the client:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The transaction failed. Try again.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The previous consistent state would still exist.&lt;/p&gt;

&lt;p&gt;But once one participant commits and another does not, retrying is no longer obviously safe. Some of the intended change already escaped into permanent state.&lt;/p&gt;

&lt;p&gt;The uncomfortable realization is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Distributed atomicity is not about making every operation succeed. It is about preventing different participants from reaching incompatible final outcomes.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Oracle describes distributed transactions in exactly this all-or-nothing form: changes span multiple databases, but the transaction must still commit everywhere or roll back everywhere as one unit.&lt;/p&gt;

&lt;p&gt;So perhaps the coordinator should make the decision for everybody.&lt;/p&gt;




&lt;h3&gt;
  
  
  Fine. Broadcast COMMIT
&lt;/h3&gt;

&lt;p&gt;The coordinator waits until both servers have performed their local work.&lt;/p&gt;

&lt;p&gt;Then it sends:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;COMMIT → Server 1&lt;/li&gt;
&lt;li&gt;COMMIT → Server 2&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Much cleaner.&lt;/p&gt;

&lt;p&gt;One authority.&lt;br&gt;&lt;br&gt;
One decision.&lt;/p&gt;

&lt;p&gt;Both participants do what they are told.&lt;/p&gt;

&lt;p&gt;Except the network gets a vote.&lt;/p&gt;

&lt;p&gt;Server 1 receives: &lt;strong&gt;COMMIT&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Server 2 does not.&lt;/p&gt;

&lt;p&gt;Maybe its machine crashed.&lt;br&gt;&lt;br&gt;
Maybe the message disappeared.&lt;br&gt;&lt;br&gt;
Maybe the connection failed.&lt;/p&gt;

&lt;p&gt;Server 1 commits.&lt;br&gt;&lt;br&gt;
Server 2 does not.&lt;/p&gt;

&lt;p&gt;We are back where we started.&lt;/p&gt;

&lt;p&gt;The coordinator decided correctly.&lt;br&gt;&lt;br&gt;
That was not enough.&lt;/p&gt;

&lt;p&gt;The hidden problem is that &lt;strong&gt;sending the final decision does not prove that every participant is capable of carrying it out&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So before the system says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Commit.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;it needs another question.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Can you commit?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That extra question is where Two-Phase Commit begins.&lt;/p&gt;




&lt;h3&gt;
  
  
  The First Phase Is Not COMMIT
&lt;/h3&gt;

&lt;p&gt;In &lt;strong&gt;Two-Phase Commit&lt;/strong&gt; , or &lt;strong&gt;2PC&lt;/strong&gt; , one process acts as the &lt;strong&gt;transaction coordinator&lt;/strong&gt; and the machines containing pieces of the transaction act as &lt;strong&gt;participants&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The coordinator does not immediately order everyone to commit.&lt;/p&gt;

&lt;p&gt;It first sends something like:  &lt;strong&gt;PREPARE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Meaning:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;If I later tell you to commit this transaction, are you able to guarantee that you can do it?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Each participant checks its local situation.&lt;/p&gt;

&lt;p&gt;Did its part of the transaction execute successfully?&lt;/p&gt;

&lt;p&gt;Can constraints still be satisfied?&lt;/p&gt;

&lt;p&gt;Can it preserve the information required to finish later?&lt;/p&gt;

&lt;p&gt;Can it keep the necessary transaction state?&lt;/p&gt;

&lt;p&gt;If not, it votes:  &lt;strong&gt;NO&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If it can guarantee completion, it votes:  &lt;strong&gt;YES&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Oracle’s description of the prepare phase captures the important semantic difference: a prepared participant has not yet committed, but it promises that it will later be able to follow the global commit or rollback decision even across an intervening failure.&lt;/p&gt;

&lt;p&gt;This is much stronger than:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Everything looks fine right now.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A &lt;strong&gt;YES&lt;/strong&gt; vote is a promise about the future.&lt;/p&gt;

&lt;p&gt;And promises in distributed systems need receipts.&lt;/p&gt;




&lt;h3&gt;
  
  
  “YES” Has to Survive a Crash
&lt;/h3&gt;

&lt;p&gt;Imagine Server 1 replies: &lt;strong&gt;YES&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Then immediately crashes.&lt;/p&gt;

&lt;p&gt;When it restarts, what should happen?&lt;/p&gt;

&lt;p&gt;If the promise existed only in RAM, the server wakes up with no idea that it had agreed to participate in an unfinished distributed transaction.&lt;/p&gt;

&lt;p&gt;That makes the &lt;strong&gt;YES&lt;/strong&gt; meaningless.&lt;/p&gt;

&lt;p&gt;So before a participant says it is prepared, it must preserve enough transaction state in &lt;strong&gt;stable storage&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;PostgreSQL’s &lt;strong&gt;PREPARE TRANSACTION&lt;/strong&gt; illustrates this principle directly: once prepared, the transaction's state is stored on disk so it can later be committed or rolled back even if a database crash occurs before the final decision.&lt;/p&gt;

&lt;p&gt;Oracle similarly describes prepared participants recording recovery information in redo logs and retaining the resources needed to complete the transaction after failure.&lt;/p&gt;

&lt;p&gt;So the participant’s logic becomes roughly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;perform tentative work&lt;/li&gt;
&lt;li&gt;write prepared state durably&lt;/li&gt;
&lt;li&gt;vote &lt;strong&gt;YES&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;vote &lt;strong&gt;YES&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;hope nothing happens&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The durable log is what turns:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I think I can commit.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;into:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I can recover into a state from which I can still honor this decision.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Prepared Means You Have Given Up Some Freedom
&lt;/h3&gt;

&lt;p&gt;This is the part that makes the first phase more important than its name suggests.&lt;/p&gt;

&lt;p&gt;Before voting &lt;strong&gt;YES&lt;/strong&gt; , a participant can still say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Something went wrong. Abort my local work.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After voting &lt;strong&gt;YES&lt;/strong&gt; , it has promised not to make that decision independently.&lt;/p&gt;

&lt;p&gt;It is now &lt;strong&gt;prepared&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
It holds enough state to commit.&lt;/p&gt;

&lt;p&gt;It may also retain locks or other resources required to preserve correctness.&lt;/p&gt;

&lt;p&gt;And then it waits.&lt;/p&gt;

&lt;p&gt;The participant cannot decide:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This is taking too long. I’ll just roll back.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Because the coordinator may already have received &lt;strong&gt;YES&lt;/strong&gt; votes from everyone and decided to commit globally.&lt;/p&gt;

&lt;p&gt;Oracle explicitly describes a prepared node as waiting for the global &lt;strong&gt;COMMIT&lt;/strong&gt; or &lt;strong&gt;ROLLBACK&lt;/strong&gt; decision rather than making a unilateral choice. The prepared transaction can remain &lt;strong&gt;in-doubt&lt;/strong&gt; until that decision becomes known.&lt;/p&gt;

&lt;p&gt;That is the trade.&lt;/p&gt;

&lt;p&gt;The participant gained durability of intent.&lt;/p&gt;

&lt;p&gt;It lost local authority over the outcome.&lt;/p&gt;




&lt;h3&gt;
  
  
  Now the Coordinator Can Actually Decide
&lt;/h3&gt;

&lt;p&gt;Suppose the coordinator asks three participants: &lt;strong&gt;PREPARE?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;and receives:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;P1 →  &lt;strong&gt;YES&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;P2 →  &lt;strong&gt;YES&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;P3 →  &lt;strong&gt;YES&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Only now does it know something it did not know in our naive protocol:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Every participant has reached a state from which it can complete the transaction.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So the coordinator can choose: &lt;strong&gt;GLOBAL COMMIT&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;and send the decision to everybody.&lt;/p&gt;

&lt;p&gt;But suppose the votes are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;P1 →  &lt;strong&gt;YES&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;P2 →  &lt;strong&gt;NO&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;P3 →  &lt;strong&gt;YES&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then commit is impossible.&lt;/p&gt;

&lt;p&gt;The only safe global outcome is: &lt;strong&gt;GLOBAL ABORT&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Likewise, if a participant cannot prepare and the coordinator eventually treats that participant as failed, the transaction can be aborted before the global commit decision.&lt;/p&gt;

&lt;p&gt;This gives us the two phases:&lt;/p&gt;

&lt;h4&gt;
  
  
  Phase 1: Prepare
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Coordinator →  &lt;strong&gt;PREPARE&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Participants →  &lt;strong&gt;YES&lt;/strong&gt; / &lt;strong&gt;NO&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Phase 2: Decision
&lt;/h4&gt;

&lt;p&gt;If everyone voted &lt;strong&gt;YES&lt;/strong&gt; : Coordinator →  &lt;strong&gt;COMMIT&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Otherwise: Coordinator →  &lt;strong&gt;ABORT&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is why the protocol needs two phases.&lt;/p&gt;

&lt;p&gt;The first establishes &lt;strong&gt;whether commitment is possible everywhere&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
The second establishes &lt;strong&gt;which outcome everyone must perform&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;One phase cannot safely answer both questions after the system has been distributed.&lt;/p&gt;




&lt;h3&gt;
  
  
  Before the Decision, Aborting Is Cheap
&lt;/h3&gt;

&lt;p&gt;Suppose the coordinator sends &lt;strong&gt;PREPARE&lt;/strong&gt; to three participants.&lt;/p&gt;

&lt;p&gt;Two reply:  &lt;strong&gt;YES&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The third never responds.&lt;/p&gt;

&lt;p&gt;Maybe it crashed.&lt;br&gt;&lt;br&gt;
Maybe communication failed.&lt;/p&gt;

&lt;p&gt;At this point the coordinator has &lt;strong&gt;not&lt;/strong&gt; decided to commit.&lt;/p&gt;

&lt;p&gt;That matters.&lt;/p&gt;

&lt;p&gt;Because no irreversible global commitment has been made, the coordinator can decide:  &lt;strong&gt;ABORT&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The participants that were prepared can roll back their tentative work.&lt;/p&gt;

&lt;p&gt;The transaction disappears.&lt;/p&gt;

&lt;p&gt;We return to the previous consistent state.&lt;/p&gt;

&lt;p&gt;This is one of the nice properties of the prepare boundary:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Before universal readiness exists, failure can still collapse safely into abort.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No participant is allowed to commit merely because its own local work succeeded.&lt;/p&gt;

&lt;p&gt;Local success is not global success.&lt;/p&gt;

&lt;p&gt;That distinction is exactly what the naive protocol was missing.&lt;/p&gt;




&lt;h3&gt;
  
  
  Then We Cross the Uncomfortable Line
&lt;/h3&gt;

&lt;p&gt;Now take the other case.&lt;/p&gt;

&lt;p&gt;Every participant votes:  &lt;strong&gt;YES&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The coordinator has enough information to decide:  &lt;strong&gt;COMMIT&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Suppose it sends that decision to Server 1.&lt;/p&gt;

&lt;p&gt;Server 1 commits.&lt;/p&gt;

&lt;p&gt;Then the network fails before Server 2 receives the message.&lt;/p&gt;

&lt;p&gt;We cannot now say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Never mind. Abort everything.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Server 1 has already made the committed state permanent.&lt;/p&gt;

&lt;p&gt;The global decision has crossed a boundary.&lt;/p&gt;

&lt;p&gt;The transaction must now be driven toward &lt;strong&gt;commit everywhere&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This creates what the lecture calls the critical window: after the system has committed to the global outcome but before every participant has successfully completed and acknowledged it.&lt;/p&gt;

&lt;p&gt;The coordinator cannot safely pretend the transaction never happened.&lt;/p&gt;

&lt;p&gt;The remaining participants cannot independently guess the answer.&lt;/p&gt;

&lt;p&gt;The system has entered the most awkward state distributed transactions produce:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;The outcome exists, but not everybody knows it yet.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Crash Recovery Becomes Part of COMMIT
&lt;/h3&gt;

&lt;p&gt;Suppose Server 2 crashed after voting &lt;strong&gt;YES&lt;/strong&gt; but before receiving the final decision.&lt;/p&gt;

&lt;p&gt;When it comes back, its durable log says: Transaction 42 →  &lt;strong&gt;PREPARED&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That tells Server 2:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I promised I could finish this transaction, but I do not know whether the global outcome was COMMIT or ABORT.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So it must recover the prepared transaction and determine the coordinator’s decision.&lt;/p&gt;

&lt;p&gt;If the decision was &lt;strong&gt;COMMIT&lt;/strong&gt; , it commits.&lt;br&gt;&lt;br&gt;
If it was &lt;strong&gt;ABORT&lt;/strong&gt; , it rolls back.&lt;/p&gt;

&lt;p&gt;The prepared state is precisely what allows this recovery to happen without guessing.&lt;/p&gt;

&lt;p&gt;Similarly, the &lt;strong&gt;coordinator&lt;/strong&gt; must durably remember its own decision.&lt;/p&gt;

&lt;p&gt;Imagine it decides &lt;strong&gt;COMMIT&lt;/strong&gt; , sends the message to one participant, then crashes.&lt;/p&gt;

&lt;p&gt;When it restarts, it cannot wake up and reconsider:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Maybe let’s abort instead.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Somebody may already have committed.&lt;/p&gt;

&lt;p&gt;So the coordinator’s global outcome also belongs in stable storage.&lt;/p&gt;

&lt;p&gt;MIT’s treatment of 2PC makes this durability requirement explicit: the coordinator force-writes its decision, prepared workers recover into the prepared state and ask for the outcome, and the coordinator retains the outcome until workers acknowledge it.&lt;/p&gt;

&lt;p&gt;The log is no longer merely an optimization for crash recovery.&lt;/p&gt;

&lt;p&gt;It is part of the protocol’s memory.&lt;/p&gt;




&lt;h3&gt;
  
  
  Then the Coordinator Disappears at Exactly the Wrong Time
&lt;/h3&gt;

&lt;p&gt;Now we reach the part where 2PC stops looking like a magical atomicity machine.&lt;/p&gt;

&lt;p&gt;A participant has voted:  &lt;strong&gt;YES&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It is prepared.&lt;br&gt;&lt;br&gt;
It has preserved its state.&lt;br&gt;&lt;br&gt;
It is waiting for: &lt;strong&gt;COMMIT&lt;/strong&gt; or  &lt;strong&gt;ABORT&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Then the coordinator becomes unreachable.&lt;/p&gt;

&lt;p&gt;What should the participant do?&lt;/p&gt;

&lt;p&gt;It cannot simply commit.&lt;/p&gt;

&lt;p&gt;Perhaps another participant voted &lt;strong&gt;NO&lt;/strong&gt; and the coordinator chose abort.&lt;/p&gt;

&lt;p&gt;It cannot simply abort.&lt;/p&gt;

&lt;p&gt;Perhaps everyone voted &lt;strong&gt;YES&lt;/strong&gt; , the coordinator chose commit, and another participant already committed.&lt;/p&gt;

&lt;p&gt;So the prepared participant waits.&lt;/p&gt;

&lt;p&gt;Its uncertainty is legitimate.&lt;/p&gt;

&lt;p&gt;Oracle calls this an &lt;strong&gt;in-doubt distributed transaction&lt;/strong&gt; : failure during 2PC can leave prepared participants waiting for the outcome, with associated data remaining locked until the transaction can be resolved.&lt;/p&gt;

&lt;p&gt;Academic treatments describe the same property more bluntly:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Two-Phase Commit is a blocking protocol.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If all surviving participants are prepared but none knows the global decision, they may have no safe action except waiting for the failed coordinator or another source of decisive information to recover.&lt;/p&gt;

&lt;p&gt;That is not an implementation bug.&lt;br&gt;&lt;br&gt;
It follows from what *&lt;em&gt;YES *&lt;/em&gt; means.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Prepared Participant Is Stuck Because It Is Being Correct
&lt;/h3&gt;

&lt;p&gt;This state can feel ridiculous.&lt;/p&gt;

&lt;p&gt;The server is alive.&lt;br&gt;&lt;br&gt;
Its database is alive.&lt;br&gt;&lt;br&gt;
Its disks are alive.&lt;br&gt;&lt;br&gt;
It has the transaction data.&lt;/p&gt;

&lt;p&gt;And yet it refuses to either commit or roll back.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Why?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Because it lacks &lt;strong&gt;authority&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Before preparing, the participant owned its local choice.&lt;/p&gt;

&lt;p&gt;After preparing, it delegated the final choice to the distributed commit decision.&lt;/p&gt;

&lt;p&gt;Now the coordinator is unavailable.&lt;/p&gt;

&lt;p&gt;The participant is not waiting because it is incapable of performing either operation.&lt;/p&gt;

&lt;p&gt;It is waiting because it cannot determine &lt;strong&gt;which operation preserves atomicity&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That is an important distinction.&lt;/p&gt;

&lt;p&gt;The server is &lt;em&gt;technically&lt;/em&gt; capable.&lt;br&gt;&lt;br&gt;
The system is &lt;em&gt;informationally&lt;/em&gt; stuck.&lt;/p&gt;

&lt;p&gt;The Origami Software Engineer has seen this recurring distributed-systems pattern in another costume:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Missing communication becomes missing knowledge.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And once the missing knowledge determines whether permanent state should exist, guessing becomes dangerous.&lt;/p&gt;




&lt;h3&gt;
  
  
  Locks Make the Waiting Visible
&lt;/h3&gt;

&lt;p&gt;Prepared transactions cannot casually release everything they were using.&lt;/p&gt;

&lt;p&gt;If another transaction could modify the same state while the original transaction’s outcome remained unresolved, the participant might no longer be able to honor its promise correctly.&lt;/p&gt;

&lt;p&gt;So prepared transactions may retain locks.&lt;/p&gt;

&lt;p&gt;Now uncertainty starts affecting unrelated work.&lt;/p&gt;

&lt;p&gt;Transaction 42 is in doubt.&lt;br&gt;&lt;br&gt;
Transaction 73 wants the same data.&lt;br&gt;&lt;br&gt;
Transaction 73 waits.&lt;/p&gt;

&lt;p&gt;Oracle’s documentation explicitly notes that in-doubt distributed transactions can keep data locked until the outcome is resolved; its error documentation even describes resources remaining locked by prepared distributed transactions.&lt;/p&gt;

&lt;p&gt;This is where availability pays the price for atomicity.&lt;/p&gt;

&lt;p&gt;2PC’s promise is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;We will not let half the distributed transaction permanently win while the other half permanently loses.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The cost is that, under some failures, the system may prefer to &lt;strong&gt;wait rather than guess&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Correctness is being protective.&lt;br&gt;&lt;br&gt;
Possibly overprotective.&lt;br&gt;&lt;br&gt;
But for good reason.&lt;/p&gt;




&lt;h3&gt;
  
  
  Two-Phase Commit and Two-Phase Locking Are Solving Different Problems
&lt;/h3&gt;

&lt;p&gt;The names are similar enough to cause unnecessary suffering.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Two-Phase Locking&lt;/strong&gt; is about concurrent transactions.&lt;/p&gt;

&lt;p&gt;It helps preserve &lt;strong&gt;consistency and isolation&lt;/strong&gt; by controlling the ordering of conflicting accesses.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Two-Phase Commit&lt;/strong&gt; is about one transaction whose work spans multiple participants.&lt;/p&gt;

&lt;p&gt;It helps preserve &lt;strong&gt;atomicity and durability&lt;/strong&gt; by coordinating whether every participant commits or every participant aborts.&lt;/p&gt;

&lt;p&gt;One asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Can these concurrent operations safely interleave?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The other asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Can these distributed pieces make one final decision?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A system may need both.&lt;/p&gt;

&lt;p&gt;Locks can ensure that other transactions do not corrupt the objects involved.&lt;/p&gt;

&lt;p&gt;2PC can ensure that the distributed transaction does not commit on only some machines.&lt;/p&gt;

&lt;p&gt;Different problem.&lt;br&gt;&lt;br&gt;
Different mechanism.&lt;/p&gt;

&lt;p&gt;Same uncomfortable theme:&lt;/p&gt;

&lt;p&gt;Once state is distributed, a property that looked local requires coordination.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Extra Phase Is Buying Certainty
&lt;/h3&gt;

&lt;p&gt;2PC is not cheap.&lt;/p&gt;

&lt;p&gt;Every distributed transaction now involves more messages.&lt;/p&gt;

&lt;p&gt;Before commit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;PREPARE&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;votes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;COMMIT&lt;/strong&gt; / &lt;strong&gt;ABORT&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;acknowledgements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Prepared state has to be written durably.&lt;/p&gt;

&lt;p&gt;The coordinator must persist enough information to recover its decision.&lt;/p&gt;

&lt;p&gt;Participants may retain locks while waiting.&lt;/p&gt;

&lt;p&gt;Failures can leave transactions in doubt.&lt;/p&gt;

&lt;p&gt;That can reduce availability.&lt;/p&gt;

&lt;p&gt;The transaction that once ended with: &lt;strong&gt;COMMIT&lt;/strong&gt; has become a small distributed protocol.&lt;br&gt;&lt;br&gt;
And that is precisely the point.&lt;/p&gt;

&lt;p&gt;The additional machinery exists because the simple operation stopped carrying enough information.&lt;/p&gt;

&lt;p&gt;One local database can know:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;My work succeeded.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A distributed transaction needs to know:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Everyone can complete the same outcome, and that outcome will survive crashes and communication failures.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That stronger claim costs more.&lt;/p&gt;




&lt;h3&gt;
  
  
  COMMIT Became a Conversation Because Nobody Owned the Whole Transaction
&lt;/h3&gt;

&lt;p&gt;At the beginning, the problem looked tiny.&lt;/p&gt;

&lt;p&gt;Move one unit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A = A + 1&lt;/li&gt;
&lt;li&gt;B = B - 1&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When both values lived under one transactional authority, atomicity could be enforced locally.&lt;/p&gt;

&lt;p&gt;Then A and B moved onto different machines.&lt;/p&gt;

&lt;p&gt;Now Server 1 could succeed while Server 2 failed.&lt;/p&gt;

&lt;p&gt;So independent commit was unsafe.&lt;/p&gt;

&lt;p&gt;We introduced a coordinator.&lt;/p&gt;

&lt;p&gt;But one &lt;strong&gt;COMMIT&lt;/strong&gt; broadcast could still reach only some participants.&lt;/p&gt;

&lt;p&gt;So the coordinator first asked whether everybody was &lt;strong&gt;prepared&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;YES&lt;/strong&gt; vote became a durable promise.&lt;/p&gt;

&lt;p&gt;Once everybody promised, the coordinator could choose one global outcome.&lt;/p&gt;

&lt;p&gt;Then failures created another problem: some participants might know the decision while others remained uncertain.&lt;/p&gt;

&lt;p&gt;So participants and coordinator had to preserve protocol state across crashes.&lt;/p&gt;

&lt;p&gt;And once a prepared participant could no longer discover the decision, waiting became safer than guessing.&lt;/p&gt;

&lt;p&gt;That is why &lt;strong&gt;COMMIT&lt;/strong&gt; stops being one instruction in a distributed transaction.&lt;/p&gt;

&lt;p&gt;It becomes a conversation about readiness, authority, durability, and shared outcome.&lt;/p&gt;

&lt;p&gt;Two-Phase Commit does not make failures disappear.&lt;/p&gt;

&lt;p&gt;It creates a disciplined boundary around what the system is allowed to do when failures happen.&lt;/p&gt;

&lt;p&gt;Before the boundary, abort is still safe.&lt;/p&gt;

&lt;p&gt;After the boundary, the chosen outcome has to be carried through.&lt;/p&gt;

&lt;p&gt;The extra phase was never ceremony.&lt;/p&gt;

&lt;p&gt;It was the price of turning several independent machines back into one atomic decision.&lt;/p&gt;

&lt;p&gt;That’s not failure.&lt;br&gt;&lt;br&gt;
That’s evolution.&lt;/p&gt;




&lt;h3&gt;
  
  
  The “I liked this” Starter Pack:
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Don’t let your fingers get lazy now.
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Like :&lt;/strong&gt; It tells me this was worth writing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A Comment:&lt;/strong&gt; Tell me your thoughts, your favorite snack, or a better title for this blog.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Boost it:&lt;/strong&gt; Especially with that one developer who definitely needs this.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Thanks for being here. It genuinely helps more than you know!&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;— Aaroophan Varatharajan&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Find me elsewhere:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Professional stuff:&lt;/strong&gt; &lt;a href="http://linkedin.com/in/Aaroophan" rel="noopener noreferrer"&gt;linkedin.com/in/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code stuff:&lt;/strong&gt; &lt;a href="http://github.com/Aaroophan" rel="noopener noreferrer"&gt;github.com/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UI stuff:&lt;/strong&gt; &lt;a href="https://aaroophan.dev/Aaroophan" rel="noopener noreferrer"&gt;aaroophan.dev/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Life stuff:&lt;/strong&gt; &lt;a href="http://instagram.com/aaroophan" rel="noopener noreferrer"&gt;instagram.com/Aaroophan&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>distributedcomputing</category>
      <category>distributedsystems</category>
      <category>architecture</category>
      <category>softwareengineering</category>
    </item>
  </channel>
</rss>
