<?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: Muhammad Ahsan Farooq </title>
    <description>The latest articles on DEV Community by Muhammad Ahsan Farooq  (@ahsanfarooq210).</description>
    <link>https://dev.to/ahsanfarooq210</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F989252%2F6a8c71b0-2f40-45da-9fe7-1e28d75b21f7.jpeg</url>
      <title>DEV Community: Muhammad Ahsan Farooq </title>
      <link>https://dev.to/ahsanfarooq210</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ahsanfarooq210"/>
    <language>en</language>
    <item>
      <title>LSM-Trees Explained: The Storage Engine Behind Millions of Writes per Second</title>
      <dc:creator>Muhammad Ahsan Farooq </dc:creator>
      <pubDate>Sun, 11 Oct 2026 07:58:41 +0000</pubDate>
      <link>https://dev.to/ahsanfarooq210/lsm-trees-explained-the-storage-engine-behind-millions-of-writes-per-second-1f3o</link>
      <guid>https://dev.to/ahsanfarooq210/lsm-trees-explained-the-storage-engine-behind-millions-of-writes-per-second-1f3o</guid>
      <description>&lt;p&gt;&lt;em&gt;MemTables, write-ahead logs, SSTables, Bloom filters, and compaction, from the first write to the last merge&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Most databases are designed around reading. Then you build a chat app, an IoT platform or an event log, and the job flips. The database spends its life absorbing writes, millions per second.&lt;/p&gt;

&lt;p&gt;Classic relational engines, such as InnoDB in MySQL, are built around &lt;strong&gt;B+ trees&lt;/strong&gt; that update fixed-size disk pages in place. Scattered updates mean random disk I/O, and under heavy write load that becomes the bottleneck.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Log-structured merge-trees (LSM-trees)&lt;/strong&gt; take the opposite approach: never modify anything on disk. Buffer writes in memory, record them in a log, flush them as sorted immutable files, and tidy up later in the background. This design powers Apache Cassandra, ScyllaDB, HBase, Google Bigtable, LevelDB and RocksDB.&lt;/p&gt;

&lt;p&gt;This post explains how LSM-trees work from the inside, with a worked example and diagrams for each step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In this post:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Why B+ trees struggle with writes,&lt;/strong&gt; and the idea behind LSM-trees&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The parts:&lt;/strong&gt; MemTable, write-ahead log, SSTables, sparse indexes and Bloom filters&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A worked example,&lt;/strong&gt; following real writes from memory to disk&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reads, deletes and tombstones&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compaction,&lt;/strong&gt; and the read, write and space trade-offs it creates&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use cases, case studies and tuning advice&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why B+ trees struggle with heavy writes
&lt;/h2&gt;

&lt;p&gt;A B+ tree keeps data sorted inside fixed-size pages, commonly 4 to 16 KB. To change a record, the database finds the right page, reads it into memory, modifies it, and writes the page back to the same place. If a page is full, it splits in two and the tree rebalances.&lt;/p&gt;

&lt;p&gt;That works well when updates are local. It works badly when keys arrive in random order, because every write lands on a different page. The disk jumps around, and each small change costs a full page read and write.&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%2F9qjnczmeubaeuze4szaq.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%2F9qjnczmeubaeuze4szaq.png" alt="in-place page updates vs sequential flush · 3 writes" width="799" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;in-place page updates vs sequential flush · 3 writes&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Sequential I/O is much cheaper than random I/O. The gap is largest on spinning disks, but SSDs also handle large sequential writes more efficiently than many small scattered ones.&lt;/p&gt;

&lt;h3&gt;
  
  
  The LSM-tree idea
&lt;/h3&gt;

&lt;p&gt;An LSM-tree turns every write into an append. It does four things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Accept the write in memory,&lt;/strong&gt; in a sorted buffer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Record it in a log&lt;/strong&gt; on disk, so a crash cannot lose it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flush the buffer&lt;/strong&gt; to disk as one sorted, immutable file when it fills up.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Merge files in the background&lt;/strong&gt; so reads stay fast.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  An analogy: the library cart
&lt;/h3&gt;

&lt;p&gt;Imagine a library that receives thousands of new books a day. A strict librarian would walk each book to its exact shelf spot, shifting other books to make room. That is a B+ tree.&lt;/p&gt;

&lt;p&gt;An LSM librarian drops new books on a cart. When the cart is full, they sort it once and seal it into a labeled box. Boxes are never reopened. Every so often, a few boxes are merged into one bigger sorted box. Adding a book is almost free. Finding one means checking the cart and then the boxes, newest first. That is the trade you accept with an LSM-tree: cheap writes, more work on reads and in the background.&lt;/p&gt;

&lt;h2&gt;
  
  
  Anatomy of an LSM-tree
&lt;/h2&gt;

&lt;p&gt;An LSM-tree has a few cooperating parts spread across memory and disk. Follow one write through them, from left to right:&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%2F0kf0zvu2yjzvqvjalz3d.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%2F0kf0zvu2yjzvqvjalz3d.png" alt="LSM-tree write path · 5 stages across memory and disk" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;LSM-tree write path · 5 stages across memory and disk&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The write-ahead log (WAL)
&lt;/h3&gt;

&lt;p&gt;RAM is volatile, so a MemTable alone would lose data in a crash. Before a write is acknowledged, it is appended to an on-disk &lt;strong&gt;write-ahead log&lt;/strong&gt;. The log is strictly append-only, so it uses fast sequential I/O. After a crash, the engine replays the log to rebuild the MemTable.&lt;/p&gt;

&lt;p&gt;How strong the guarantee is depends on the sync setting. If the engine waits for the log to reach the disk, the write is durable. Some systems default to syncing on a timer instead. Cassandra's commit log, for example, defaults to periodic sync, and relies on replication to cover a single node's crash.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The MemTable
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;MemTable&lt;/strong&gt; is an in-memory buffer that keeps keys in sorted order. Engines typically build it from a skip list or a balanced tree. Writes touch only RAM, so they finish almost instantly. RocksDB, for instance, defaults to a 64 MB write buffer.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. SSTables
&lt;/h3&gt;

&lt;p&gt;When the MemTable reaches its size limit, the engine freezes it into a read-only MemTable and starts a fresh active one for incoming writes. A background thread then writes the frozen table to disk as a &lt;strong&gt;Sorted String Table (SSTable)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;An SSTable has two defining properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sorted:&lt;/strong&gt; keys are stored in order, which makes lookups and merges efficient.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Immutable:&lt;/strong&gt; once written, the file is never modified. An update is a newer record in a newer SSTable. A delete is a special marker called a &lt;strong&gt;tombstone&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&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%2Fmunk7unceuqainhtr3wi.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%2Fmunk7unceuqainhtr3wi.png" alt="SSTable anatomy · 3 data blocks, 2 helpers" width="800" height="269"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;SSTable anatomy · 3 data blocks, 2 helpers&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. The sparse index and Bloom filters
&lt;/h3&gt;

&lt;p&gt;Over time, many SSTables pile up. A lookup could in theory open every one of them. Two small in-memory structures prevent that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sparse index:&lt;/strong&gt; because keys inside a file are sorted, the engine only stores the first key of each block, for example every 4 KB. To find a key, it binary-searches this index and reads just one block.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bloom filter:&lt;/strong&gt; a compact probabilistic structure that answers "is this key in the file?" with either &lt;em&gt;definitely not&lt;/em&gt; or &lt;em&gt;maybe&lt;/em&gt;. It never gives a false negative, so a &lt;em&gt;definitely not&lt;/em&gt; lets the engine skip the file without touching the disk. It can give false positives, but at about 10 bits per key the rate is around 1%.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A worked example: eight writes
&lt;/h2&gt;

&lt;p&gt;Let's trace a tiny key-value store that maps a user name to a city. To keep the example small, assume the MemTable flushes after every 4 writes. A real engine flushes after tens of megabytes.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;MemTable afterwards&lt;/th&gt;
&lt;th&gt;On disk afterwards&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;code&gt;put(alice, Lahore)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;alice=Lahore&lt;/td&gt;
&lt;td&gt;nothing yet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;code&gt;put(bob, Karachi)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;alice=Lahore, bob=Karachi&lt;/td&gt;
&lt;td&gt;nothing yet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;code&gt;put(alice, Dubai)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;alice=Dubai, bob=Karachi&lt;/td&gt;
&lt;td&gt;nothing yet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;put(carol, Berlin)&lt;/code&gt;, then the MemTable is full and flushes&lt;/td&gt;
&lt;td&gt;empty&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;SSTable 1:&lt;/strong&gt; alice=Dubai, bob=Karachi, carol=Berlin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;&lt;code&gt;put(bob, Oslo)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;bob=Oslo&lt;/td&gt;
&lt;td&gt;SSTable 1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;&lt;code&gt;delete(carol)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;bob=Oslo, carol=TOMBSTONE&lt;/td&gt;
&lt;td&gt;SSTable 1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;&lt;code&gt;put(dave, Paris)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;bob=Oslo, carol=TOMBSTONE, dave=Paris&lt;/td&gt;
&lt;td&gt;SSTable 1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;put(erin, Rome)&lt;/code&gt;, then the MemTable is full and flushes&lt;/td&gt;
&lt;td&gt;empty&lt;/td&gt;
&lt;td&gt;SSTable 1, plus &lt;strong&gt;SSTable 2:&lt;/strong&gt; bob=Oslo, carol=TOMBSTONE, dave=Paris, erin=Rome&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Four things are worth noticing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Overwrites in memory are free.&lt;/strong&gt; In step 3, &lt;code&gt;Lahore&lt;/code&gt; was replaced inside the MemTable. It never reached the disk.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A flush is one sequential write.&lt;/strong&gt; Each SSTable was produced in a single pass, already sorted.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The same key can live in several files.&lt;/strong&gt; &lt;code&gt;bob&lt;/code&gt; is in both SSTables, with different values. The newest one wins.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A delete is a write.&lt;/strong&gt; In step 6, nothing was erased. &lt;code&gt;carol=Berlin&lt;/code&gt; still sits in SSTable 1, and a tombstone in a newer place now hides it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All eight writes were also appended to the write-ahead log. Once a MemTable is safely flushed, the log segment that covered it can be discarded.&lt;/p&gt;

&lt;p&gt;This is the state the next section starts from.&lt;/p&gt;

&lt;h2&gt;
  
  
  The read path and tombstones
&lt;/h2&gt;

&lt;p&gt;Reading from an LSM-tree means searching from the newest data to the oldest and stopping at the first answer:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check the active &lt;strong&gt;MemTable&lt;/strong&gt;, then any frozen MemTables.&lt;/li&gt;
&lt;li&gt;For each &lt;strong&gt;SSTable&lt;/strong&gt;, newest first: ask the Bloom filter, then the sparse index, then read one data block.&lt;/li&gt;
&lt;li&gt;Return the newest version found. If the newest record is a tombstone, the key does not exist.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here are three lookups against the store from the worked example:&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%2Fo4htnddvvom89ect858e.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%2Fo4htnddvvom89ect858e.png" alt="read path · 3 lookups across 3 layers" width="800" height="342"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;read path · 3 lookups across 3 layers&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Notice that &lt;code&gt;get(alice)&lt;/code&gt; needed one disk read, even though two files exist. The Bloom filter ruled out SSTable 2 for free.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why reads cost more
&lt;/h3&gt;

&lt;p&gt;A key might need to be checked in several files. This extra work is called &lt;strong&gt;read amplification&lt;/strong&gt;. Bloom filters, block caches and compaction all exist to keep it small. Compaction matters most, because it reduces the number of files a read can touch.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deletes and tombstones
&lt;/h3&gt;

&lt;p&gt;SSTables are immutable, so a delete cannot erase anything. The engine writes a &lt;strong&gt;tombstone&lt;/strong&gt;, a marker saying "this key is deleted as of now". Reads treat a newest-record tombstone as a missing key. The tombstone and the data it hides are physically removed later, during compaction.&lt;/p&gt;

&lt;p&gt;Tombstones cannot always be dropped right away. Cassandra, for example, keeps them for &lt;code&gt;gc_grace_seconds&lt;/code&gt;, which defaults to 10 days, so that a replica that was offline during the delete still learns about it. Drop the tombstone too early and the deleted data can come back.&lt;/p&gt;

&lt;p&gt;This makes delete-heavy workloads risky. Using a table as a queue, where rows are inserted and then deleted, leaves piles of tombstones that every read has to scan past. Discord ran into a version of this: when it migrated its message store, the migration stalled at 99.9999% because the last token ranges held huge runs of tombstones that had never been compacted away.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compaction: keeping the files in check
&lt;/h2&gt;

&lt;p&gt;Without cleanup, SSTables accumulate forever. Reads must check more files, and old versions of keys and tombstones waste disk space. &lt;strong&gt;Compaction&lt;/strong&gt; is the background process that fixes this. It reads several SSTables, merge-sorts them, discards overwritten values and deleted data, and writes new consolidated files.&lt;/p&gt;

&lt;p&gt;Here is compaction applied to the two files from our worked example:&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%2Fj38b8vfhs3ko32682ttt.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%2Fj38b8vfhs3ko32682ttt.png" alt="compaction merge · 2 files into 1" width="800" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;compaction merge · 2 files into 1&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Because both inputs are already sorted, the merge is a single streaming pass over the disk. It is sequential I/O again, which is exactly what the design wants.&lt;/p&gt;

&lt;p&gt;A tombstone can be dropped only when it is safe, meaning the compaction includes every older file that could still hold the deleted key. Otherwise the old value would reappear.&lt;/p&gt;

&lt;h3&gt;
  
  
  Two main strategies
&lt;/h3&gt;

&lt;p&gt;Engines differ in &lt;em&gt;which&lt;/em&gt; files they merge and &lt;em&gt;when&lt;/em&gt;. The two classic strategies make opposite trade-offs:&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%2Flrha23juezwhxdg4goyh.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%2Flrha23juezwhxdg4goyh.png" alt="size-tiered vs leveled compaction" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;size-tiered vs leveled compaction&lt;/em&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Strategy&lt;/th&gt;
&lt;th&gt;How it works&lt;/th&gt;
&lt;th&gt;Strengths&lt;/th&gt;
&lt;th&gt;Costs&lt;/th&gt;
&lt;th&gt;Fits best&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Size-tiered (STCS)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Groups files of similar size. When enough exist, merges them into one larger file&lt;/td&gt;
&lt;td&gt;Low write amplification and fast ingestion&lt;/td&gt;
&lt;td&gt;High space amplification. Large merges can need up to 50% free disk&lt;/td&gt;
&lt;td&gt;Write-heavy workloads such as event logs and metrics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Leveled (LCS)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Stores data in levels. Each level is about 10x larger than the last, and files do not overlap above L0&lt;/td&gt;
&lt;td&gt;Low read amplification and good space efficiency, with roughly 10% overhead&lt;/td&gt;
&lt;td&gt;High write amplification and steady background I/O&lt;/td&gt;
&lt;td&gt;Read-heavy or space-constrained workloads&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In the leveled diagram, a read checks at most one file in each of L1 and below, because those files do not overlap. It must still check every L0 file, since fresh files can overlap.&lt;/p&gt;

&lt;p&gt;Time-series data has its own option. Cassandra's time-window compaction groups files by time window, so when data carries a time-to-live, whole windows can be dropped cheaply once they expire.&lt;/p&gt;

&lt;h3&gt;
  
  
  The three amplifications
&lt;/h3&gt;

&lt;p&gt;Compaction is a balancing act between three costs. Every tuning decision moves weight from one to another:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Amplification&lt;/th&gt;
&lt;th&gt;What it measures&lt;/th&gt;
&lt;th&gt;What drives it up&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Read&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;How many files or blocks a read must check&lt;/td&gt;
&lt;td&gt;Many overlapping files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Write&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Bytes written to disk for each byte the application wrote&lt;/td&gt;
&lt;td&gt;Compacting often, since every merge rewrites data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Space&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Disk used compared with the size of the live data&lt;/td&gt;
&lt;td&gt;Old versions and tombstones waiting to be merged away&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Size-tiered compaction favors low write amplification. Leveled compaction favors low read and space amplification. No strategy wins on all three.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compaction is not free
&lt;/h3&gt;

&lt;p&gt;Compaction competes with your queries for disk and CPU. If it falls behind, reads touch more files and latency climbs. Discord described this problem in its Cassandra clusters: nodes fell behind on compactions, which made reads more expensive and caused cascading latency. Watching the compaction backlog is as important as watching query latency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where LSM-trees shine, and where they do not
&lt;/h2&gt;

&lt;p&gt;LSM-trees fit workloads that write constantly, read mostly recent data, and rarely update or delete in place.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use cases
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Chat and message history:&lt;/strong&gt; messages are appended per channel and read mostly newest first. Discord stores its messages this way.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IoT telemetry and metrics:&lt;/strong&gt; millions of sensor readings per second, each keyed by device and time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Event logs, audit trails and activity feeds:&lt;/strong&gt; append-mostly data that is queried by key and time range.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User activity history:&lt;/strong&gt; Netflix described its viewing-history store as write-heavy, with a write-to-read ratio of about 9:1.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Embedded state stores:&lt;/strong&gt; RocksDB sits inside stream processors such as Kafka Streams and Apache Flink to hold large local state.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Foundations of other databases:&lt;/strong&gt; CockroachDB, TiKV and YugabyteDB build on LSM-tree engines, and MyRocks brings RocksDB to MySQL.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example: sensor readings with automatic expiry
&lt;/h3&gt;

&lt;p&gt;A time-series table in Cassandra pairs the write path with a compaction strategy built for time data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;sensor_readings&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;sensor_id&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;day&lt;/span&gt;       &lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;ts&lt;/span&gt;        &lt;span class="nb"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;value&lt;/span&gt;     &lt;span class="nb"&gt;double&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;sensor_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;day&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;ts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;compaction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'class'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'TimeWindowCompactionStrategy'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'compaction_window_unit'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'DAYS'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'compaction_window_size'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;default_time_to_live&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2592000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;-- 30 days&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is why this fits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Appends only.&lt;/strong&gt; Every reading is a new row, so there are no in-place updates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bounded partitions.&lt;/strong&gt; The &lt;code&gt;(sensor_id, day)&lt;/code&gt; partition key caps how large any one partition grows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cheap expiry.&lt;/strong&gt; Files are grouped by day, so data older than 30 days disappears when a whole file expires, instead of through millions of individual deletes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When an LSM-tree is the wrong tool
&lt;/h3&gt;

&lt;p&gt;The costs we covered earlier define the limits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Read-heavy random lookups&lt;/strong&gt; that a cache cannot absorb. A B+ tree reads one predictable path.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Strict, flat tail latency.&lt;/strong&gt; Compaction competes with queries and can cause spikes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Delete-heavy or queue-like tables.&lt;/strong&gt; Tombstones pile up, and reads must scan past them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tight disk budgets&lt;/strong&gt; with size-tiered compaction, which can need a lot of free space during merges.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Workload&lt;/th&gt;
&lt;th&gt;Better fit&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Millions of appends per second, mostly recent reads&lt;/td&gt;
&lt;td&gt;LSM-tree&lt;/td&gt;
&lt;td&gt;Writes stay sequential&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Read-heavy transactions with random lookups&lt;/td&gt;
&lt;td&gt;B+ tree&lt;/td&gt;
&lt;td&gt;One predictable lookup, no compaction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Time-series data with a retention window&lt;/td&gt;
&lt;td&gt;LSM-tree with time-window compaction&lt;/td&gt;
&lt;td&gt;Whole files expire at once&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A table used as a work queue&lt;/td&gt;
&lt;td&gt;A real message queue&lt;/td&gt;
&lt;td&gt;Insert-then-delete churn creates tombstones&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strict, flat read latency&lt;/td&gt;
&lt;td&gt;B+ tree, or a carefully tuned LSM-tree&lt;/td&gt;
&lt;td&gt;Compaction can cause latency spikes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Case studies
&lt;/h2&gt;

&lt;p&gt;Two engineering teams have written openly about running LSM-tree databases at scale. Their stories show both the strengths and the sharp edges.&lt;/p&gt;

&lt;h3&gt;
  
  
  Discord: from Cassandra to ScyllaDB
&lt;/h3&gt;

&lt;p&gt;Discord stores its chat messages in a database partitioned by channel and a time bucket. In 2017 the cluster ran 12 Cassandra nodes holding billions of messages. By early 2022 it had grown to 177 nodes holding trillions, and it had become what Discord called a high-toil system. Three problems traced back to the LSM-tree design and its runtime:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reads cost more than writes.&lt;/strong&gt; A write goes to the commit log and the MemTable. A read must check the MemTable and possibly several SSTables. Heavy concurrent reads on one channel created &lt;em&gt;hot partitions&lt;/em&gt;, which slowed the nodes serving them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compaction fell behind.&lt;/strong&gt; When compaction lags, reads touch more files. Discord's operators resorted to taking nodes out of rotation so they could catch up on compactions without serving traffic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JVM garbage collection.&lt;/strong&gt; Cassandra runs on the JVM, and garbage collection pauses caused latency spikes that took a lot of tuning to contain.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Discord moved the messages cluster to ScyllaDB, a Cassandra-compatible database written in C++ with no garbage collector. It also put Rust &lt;em&gt;data services&lt;/em&gt; in front of the database. These coalesce identical concurrent requests into a single query, and route requests by channel ID so that coalescing works well. The cut-over happened in May 2022. Here is how the two clusters compared afterwards, according to Discord:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Cassandra&lt;/th&gt;
&lt;th&gt;ScyllaDB&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Nodes&lt;/td&gt;
&lt;td&gt;177&lt;/td&gt;
&lt;td&gt;72&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Disk per node&lt;/td&gt;
&lt;td&gt;about 4 TB on average&lt;/td&gt;
&lt;td&gt;9 TB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;p99 latency, fetching historical messages&lt;/td&gt;
&lt;td&gt;40 to 125 ms&lt;/td&gt;
&lt;td&gt;15 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;p99 latency, inserting a message&lt;/td&gt;
&lt;td&gt;5 to 70 ms&lt;/td&gt;
&lt;td&gt;about 5 ms, steady&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The lesson is that both databases use the same LSM-tree design. The gains came from removing garbage collection pauses, giving each CPU core its own shard of work, and shielding the database from hot partitions. An LSM-tree is only as predictable as its compaction, its runtime and its access pattern.&lt;/p&gt;

&lt;h3&gt;
  
  
  Netflix: Cassandra for write-heavy data
&lt;/h3&gt;

&lt;p&gt;Netflix has used Cassandra's LSM-tree engine in two well-documented places.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Viewing history.&lt;/strong&gt; Netflix's first cloud-native viewing-history store used Cassandra because the data is time-series shaped and write-heavy, at a ratio of about 9 writes to 1 read. Netflix later redesigned it for a smaller storage footprint and consistent read and write performance as each member's history grows, splitting each member's data into a small set of recent records that change often and a larger set of older records that are stored compressed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live streaming origin.&lt;/strong&gt; For live events, Netflix needed storage with very high write availability. It treats any write that fails within 500 ms as a bug. Its requirements and how they were met:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Requirement&lt;/th&gt;
&lt;th&gt;How it was met&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Writes almost never fail&lt;/td&gt;
&lt;td&gt;A key-value layer on Cassandra with local-quorum writes, which keep working even if an entire availability zone is down&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Large payloads of a few megabytes&lt;/td&gt;
&lt;td&gt;Values are split into chunks, and each chunk can be retried and hedged safely&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;High write throughput&lt;/td&gt;
&lt;td&gt;Cassandra's write-optimized LSM-tree engine&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Read storms without hurting writes&lt;/td&gt;
&lt;td&gt;A write-through cache in front of Cassandra, so almost all reads are served from memory&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Netflix reports that Cassandra could serve reads at network line rate, but that doing so degraded concurrent writes. Adding a cache separated the read path from the write path. The write latency at the 99th percentile ended up close to the old S3-based design's median. The new setup was significantly more expensive, but low latency and high availability mattered more than cost.&lt;/p&gt;

&lt;p&gt;The pattern to take away is common to both companies. An LSM-tree gives you cheap writes, and you pair it with a cache or a coalescing layer to protect the read path.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical tuning checklist
&lt;/h2&gt;

&lt;p&gt;Exact settings differ between Cassandra, ScyllaDB and RocksDB, but the same levers exist everywhere:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Lever&lt;/th&gt;
&lt;th&gt;What it changes&lt;/th&gt;
&lt;th&gt;Guidance&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Compaction strategy&lt;/td&gt;
&lt;td&gt;The balance of read, write and space amplification&lt;/td&gt;
&lt;td&gt;Size-tiered for write-heavy ingest with disk headroom. Leveled for read-heavy data. Time-window for time series with a TTL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MemTable size&lt;/td&gt;
&lt;td&gt;How often data flushes, and how many files appear&lt;/td&gt;
&lt;td&gt;Larger buffers mean fewer, bigger flushes and less compaction, but use more RAM and mean a longer log replay after a crash&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bloom filter size&lt;/td&gt;
&lt;td&gt;False-positive rate against memory&lt;/td&gt;
&lt;td&gt;About 10 bits per key gives roughly a 1% false-positive rate. Spend more memory on read-heavy tables&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Block and key caches&lt;/td&gt;
&lt;td&gt;Repeated reads of hot data&lt;/td&gt;
&lt;td&gt;Size them to hold your hot set&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Free disk space&lt;/td&gt;
&lt;td&gt;Whether big merges can finish&lt;/td&gt;
&lt;td&gt;Leave generous headroom, especially with size-tiered compaction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Compaction throughput limit&lt;/td&gt;
&lt;td&gt;Background I/O against query latency&lt;/td&gt;
&lt;td&gt;Cap it so queries are not starved, but not so low that compaction falls behind&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Partition and key design&lt;/td&gt;
&lt;td&gt;Hot spots and partition size&lt;/td&gt;
&lt;td&gt;Bound partition size, for example with a time bucket, so no single partition grows without limit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TTLs and deletes&lt;/td&gt;
&lt;td&gt;Tombstone volume&lt;/td&gt;
&lt;td&gt;Prefer TTLs with time-window compaction over mass deletes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  What to monitor
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pending compactions.&lt;/strong&gt; A growing backlog is an early warning that reads are about to slow down.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Files touched per read.&lt;/strong&gt; This is your read amplification, measured directly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tombstones scanned per read.&lt;/strong&gt; High numbers point to a delete-heavy access pattern.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free disk space.&lt;/strong&gt; Running low during a large merge can stop compaction entirely.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;p99 read latency,&lt;/strong&gt; not just the average. Compaction trouble shows up in the tail first.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Common mistakes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Benchmarking a fresh database.&lt;/strong&gt; An LSM-tree behaves differently once data volume is large and compaction is running. Test at realistic size and let compaction reach a steady state.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Treating the log as a guarantee.&lt;/strong&gt; Check whether the write waits for the log to reach disk, or only to reach the operating system.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unbounded partitions.&lt;/strong&gt; One very large or very hot key undermines everything else you tuned.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Using deletes as a core operation.&lt;/strong&gt; If your design needs constant deletes, reconsider the design.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Summary: B+ tree vs LSM-tree
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;B+ tree&lt;/th&gt;
&lt;th&gt;LSM-tree&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Write pattern&lt;/td&gt;
&lt;td&gt;In-place page updates&lt;/td&gt;
&lt;td&gt;Sequential appends to a log and to immutable files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Write throughput&lt;/td&gt;
&lt;td&gt;Limited by random I/O and page splits&lt;/td&gt;
&lt;td&gt;Very high&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Read cost&lt;/td&gt;
&lt;td&gt;One tree lookup&lt;/td&gt;
&lt;td&gt;Checks the MemTable and possibly several files. Bloom filters and caches soften this&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deletes&lt;/td&gt;
&lt;td&gt;Removed in place&lt;/td&gt;
&lt;td&gt;Written as tombstones, removed later by compaction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Background work&lt;/td&gt;
&lt;td&gt;Page splits and rebalancing&lt;/td&gt;
&lt;td&gt;Compaction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Space overhead&lt;/td&gt;
&lt;td&gt;Fragmentation inside pages&lt;/td&gt;
&lt;td&gt;Old versions and tombstones until they are compacted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Typical systems&lt;/td&gt;
&lt;td&gt;MySQL (InnoDB), SQLite, and the indexes in PostgreSQL&lt;/td&gt;
&lt;td&gt;Cassandra, ScyllaDB, HBase, Bigtable, LevelDB, RocksDB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;An LSM-tree makes one big bet: writes should be cheap and sequential, and the cost of keeping data organized can be paid later, in the background. That bet pays off for chat history, telemetry, event logs and any workload that writes far more often than it reads in place.&lt;/p&gt;

&lt;p&gt;Keep three ideas in mind:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Every write is an append.&lt;/strong&gt; The write-ahead log protects it, the MemTable sorts it, and a flush turns it into an immutable sorted file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reads pay for it.&lt;/strong&gt; Bloom filters, sparse indexes and caches keep that cost down, and compaction keeps the file count under control.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compaction is the engine's real workload.&lt;/strong&gt; Choose its strategy deliberately, watch its backlog, and design keys and deletes so it can keep up.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Sources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://discord.com/blog/how-discord-stores-trillions-of-messages" rel="noopener noreferrer"&gt;Discord: How Discord Stores Trillions of Messages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://netflixtechblog.com/netflix-live-origin-41f1b0ad5371" rel="noopener noreferrer"&gt;Netflix TechBlog: Netflix Live Origin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://cassandra.link/post/scaling-time-series-data-storage-part-i" rel="noopener noreferrer"&gt;Netflix TechBlog: Scaling Time Series Data Storage, Part I&lt;/a&gt; (republished on Cassandra.link)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>database</category>
      <category>systemdesign</category>
      <category>backend</category>
      <category>distributedsystems</category>
    </item>
    <item>
      <title>PostgreSQL Locks and Deadlocks: How They Work and How to Fix Them</title>
      <dc:creator>Muhammad Ahsan Farooq </dc:creator>
      <pubDate>Sat, 10 Oct 2026 12:06:03 +0000</pubDate>
      <link>https://dev.to/ahsanfarooq210/postgresql-locks-and-deadlocks-how-they-work-and-how-to-fix-them-4i3h</link>
      <guid>https://dev.to/ahsanfarooq210/postgresql-locks-and-deadlocks-how-they-work-and-how-to-fix-them-4i3h</guid>
      <description>&lt;p&gt;&lt;em&gt;Table, row, and advisory locks, safe migrations, deadlock detection, and the queries to run when production is stuck&lt;/em&gt;&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%2F6xra0tb3f9b5stj1polk.jpeg" 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%2F6xra0tb3f9b5stj1polk.jpeg" alt="PostgreSQL locks and deadlocks" width="800" height="597"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PostgreSQL lets thousands of queries run at once without trampling each other's data. Locks are what make that safe. Deadlocks are what you get when the waiting goes in a circle.&lt;/p&gt;

&lt;p&gt;Thanks to multi-version concurrency control (MVCC), a reader never blocks a writer, and a writer never blocks a reader. Every query works from a consistent snapshot. But two writers changing the same row, or a schema change on a busy table, still have to take turns. That waiting is where slow queries, stuck migrations and &lt;code&gt;deadlock detected&lt;/code&gt; errors come from.&lt;/p&gt;

&lt;p&gt;This post explains how Postgres locks work, how they go wrong, and how to fix them. Each idea comes with a runnable example and a real-world use case.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In this post:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The three lock levels:&lt;/strong&gt; table, row and advisory&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why one &lt;code&gt;ALTER TABLE&lt;/code&gt; can freeze an app,&lt;/strong&gt; and how to migrate safely&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How deadlocks form,&lt;/strong&gt; and how Postgres detects and breaks them&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prevention patterns:&lt;/strong&gt; consistent ordering, short transactions, retries and &lt;code&gt;SKIP LOCKED&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Diagnosis:&lt;/strong&gt; the queries to run when production is stuck&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The big picture: three lock levels
&lt;/h2&gt;

&lt;p&gt;Postgres locks at three levels. Most locks are taken for you. You choose explicitly only at the row and advisory levels.&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%2F8yrig61zv2i643dcnew6.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%2F8yrig61zv2i643dcnew6.png" alt="three lock levels · table, row, advisory" width="799" height="290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;three lock levels · table, row, advisory&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Each level matters in a different situation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Table-level:&lt;/strong&gt; schema changes and bulk operations such as &lt;code&gt;ALTER TABLE&lt;/code&gt; and &lt;code&gt;CREATE INDEX&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Row-level:&lt;/strong&gt; many transactions updating the same rows, such as balances, counters and inventory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Advisory:&lt;/strong&gt; your application needs a mutex across servers, such as one nightly job at a time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Locks live until the transaction ends.&lt;/strong&gt; Postgres releases table and row locks at &lt;code&gt;COMMIT&lt;/code&gt; or &lt;code&gt;ROLLBACK&lt;/code&gt;, not when the statement finishes. This one rule explains most lock trouble, because a long transaction holds its locks for its whole lifetime.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table-level locks
&lt;/h2&gt;

&lt;p&gt;Every statement takes a table-level lock automatically. There are eight modes. Four of them cover most of what you will meet:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;Taken by&lt;/th&gt;
&lt;th&gt;In plain English&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ACCESS SHARE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The weakest lock. Only &lt;code&gt;ACCESS EXCLUSIVE&lt;/code&gt; conflicts with it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ROW EXCLUSIVE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;INSERT&lt;/code&gt;, &lt;code&gt;UPDATE&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Many writers can hold it on one table at once&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SHARE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;CREATE INDEX&lt;/code&gt; (without &lt;code&gt;CONCURRENTLY&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Others can read, but nobody can write&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ACCESS EXCLUSIVE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ALTER TABLE&lt;/code&gt; (most forms), &lt;code&gt;DROP TABLE&lt;/code&gt;, &lt;code&gt;TRUNCATE&lt;/code&gt;, &lt;code&gt;VACUUM FULL&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Blocks everything, including plain &lt;code&gt;SELECT&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The other four modes sit in between. For example, &lt;code&gt;CREATE INDEX CONCURRENTLY&lt;/code&gt; and regular &lt;code&gt;VACUUM&lt;/code&gt; take &lt;code&gt;SHARE UPDATE EXCLUSIVE&lt;/code&gt;, which lets reads and writes continue.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can two sessions hold these at once?
&lt;/h3&gt;

&lt;p&gt;This matrix shows which of the four modes can coexist on the same table.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;ACCESS SHARE&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;ROW EXCLUSIVE&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;SHARE&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;ACCESS EXCLUSIVE&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;ACCESS SHARE&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;ROW EXCLUSIVE&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;SHARE&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;ACCESS EXCLUSIVE&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Two writers never block each other at the table level, because &lt;code&gt;ROW EXCLUSIVE&lt;/code&gt; does not conflict with itself. If they collide, it happens at the row level (next section).&lt;/p&gt;

&lt;h3&gt;
  
  
  Example: a schema change that blocks reads
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Session A&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="k"&gt;COLUMN&lt;/span&gt; &lt;span class="n"&gt;note&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;-- takes ACCESS EXCLUSIVE&lt;/span&gt;
&lt;span class="c1"&gt;-- transaction stays open...&lt;/span&gt;

&lt;span class="c1"&gt;-- Session B&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;              &lt;span class="c1"&gt;-- needs ACCESS SHARE, so it waits&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Session B hangs until Session A commits or rolls back. Remember the rule from earlier: locks live until the transaction ends.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use case: running a migration without an outage
&lt;/h3&gt;

&lt;p&gt;The dangerous case is not the &lt;code&gt;ALTER TABLE&lt;/code&gt; itself, which is often instant. It is the waiting. Postgres queues lock requests in order, so a pending &lt;code&gt;ACCESS EXCLUSIVE&lt;/code&gt; request makes every later query line up behind it.&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%2Flsiu6fflnknibmd0nqkp.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%2Flsiu6fflnknibmd0nqkp.png" alt="lock queue · how one migration stalls an app" width="800" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;lock queue · how one migration stalls an app&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A safe migration practice has four parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Set a &lt;code&gt;lock_timeout&lt;/code&gt;&lt;/strong&gt; so the migration gives up instead of queuing the whole app behind it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build indexes with &lt;code&gt;CREATE INDEX CONCURRENTLY&lt;/code&gt;&lt;/strong&gt; so writes continue. It cannot run inside a transaction block, and a failed run can leave an invalid index to drop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check for long-running transactions&lt;/strong&gt; in &lt;code&gt;pg_stat_activity&lt;/code&gt; before you start.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep the migration transaction short&lt;/strong&gt; and retry later if it times out.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;lock_timeout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'3s'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="k"&gt;COLUMN&lt;/span&gt; &lt;span class="n"&gt;note&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;-- fails fast if it cannot get the lock&lt;/span&gt;

&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;CONCURRENTLY&lt;/span&gt; &lt;span class="n"&gt;idx_orders_customer&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Row-level locks
&lt;/h2&gt;

&lt;p&gt;Row locks are what writers actually fight over. Postgres takes them automatically on &lt;code&gt;UPDATE&lt;/code&gt; and &lt;code&gt;DELETE&lt;/code&gt;, and you can request them yourself with &lt;code&gt;SELECT ... FOR UPDATE&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Postgres records a row lock inside the row itself, in the &lt;code&gt;xmax&lt;/code&gt; field of the tuple header. That has two consequences:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No lock escalation.&lt;/strong&gt; Some databases convert many row locks into one table lock when they run low on memory. Postgres does not, so it can lock millions of rows individually.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Locking has a write cost.&lt;/strong&gt; Marking a row changes its page on disk, so &lt;code&gt;SELECT ... FOR UPDATE&lt;/code&gt; over many rows creates write I/O.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example: two writers, one row
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Session A&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;accounts&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;-- locks row 1&lt;/span&gt;

&lt;span class="c1"&gt;-- Session B&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;accounts&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;-- waits for A&lt;/span&gt;

&lt;span class="c1"&gt;-- Session C&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;accounts&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                 &lt;span class="c1"&gt;-- returns at once, old value&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fua0uxkrvmih4fsvnru0f.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%2Fua0uxkrvmih4fsvnru0f.png" alt="MVCC row locking · 3 sessions on one row" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;MVCC row locking · 3 sessions on one row&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Session C is not blocked because MVCC gives it the last committed version of the row. Session B has to wait because only one transaction can modify a row at a time.&lt;/p&gt;

&lt;h3&gt;
  
  
  The four row-lock modes
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;Taken by&lt;/th&gt;
&lt;th&gt;Conflicts with&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;FOR KEY SHARE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Foreign key checks, such as inserting a child row&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FOR UPDATE&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;FOR SHARE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SELECT ... FOR SHARE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;FOR NO KEY UPDATE&lt;/code&gt;, &lt;code&gt;FOR UPDATE&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;FOR NO KEY UPDATE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;UPDATE&lt;/code&gt; that leaves key columns alone, or &lt;code&gt;SELECT ... FOR NO KEY UPDATE&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;FOR SHARE&lt;/code&gt;, &lt;code&gt;FOR NO KEY UPDATE&lt;/code&gt;, &lt;code&gt;FOR UPDATE&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;FOR UPDATE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;DELETE&lt;/code&gt;, &lt;code&gt;UPDATE&lt;/code&gt; of key columns, or &lt;code&gt;SELECT ... FOR UPDATE&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;All four modes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The weaker modes exist so that foreign keys do not block unrelated work. A normal &lt;code&gt;UPDATE&lt;/code&gt; takes &lt;code&gt;FOR NO KEY UPDATE&lt;/code&gt;, which does not conflict with the &lt;code&gt;FOR KEY SHARE&lt;/code&gt; that a foreign key check takes. You can update a customer row while new orders for that customer are being inserted.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use case: selling the last item in stock
&lt;/h3&gt;

&lt;p&gt;Two buyers check out at once and only one item is left. If both read &lt;code&gt;stock = 1&lt;/code&gt; and then both decrement it, you oversell.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;stock&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt; &lt;span class="k"&gt;FOR&lt;/span&gt; &lt;span class="k"&gt;UPDATE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;-- the second buyer waits here&lt;/span&gt;
&lt;span class="c1"&gt;-- the application checks that stock &amp;gt; 0&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;stock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stock&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;COMMIT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second buyer waits at the &lt;code&gt;SELECT&lt;/code&gt;, then sees &lt;code&gt;stock = 0&lt;/code&gt; once the first buyer commits. When the check is simple, one atomic statement is lighter and needs no explicit lock:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;stock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stock&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;stock&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;-- 1 row updated: success. 0 rows updated: sold out.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Advisory locks
&lt;/h2&gt;

&lt;p&gt;Advisory locks are locks whose meaning only your application knows. You pass Postgres a number, and it guarantees that only one session holds that number at a time. It never ties the lock to any table or row. That makes it a handy mutex for coordinating work across servers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example: run a nightly job on one server
&lt;/h3&gt;

&lt;p&gt;Every server schedules the same job. Only the one that wins the lock runs it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;pg_try_advisory_lock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;-- true: you hold it. false: someone else does.&lt;/span&gt;

&lt;span class="c1"&gt;-- ... run the job if you got true ...&lt;/span&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;pg_advisory_unlock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Ff23fq6cct6cij4misqj5.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%2Ff23fq6cct6cij4misqj5.png" alt="advisory lock · 3 servers, 1 winner" width="799" height="286"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;advisory lock · 3 servers, 1 winner&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Four functions to know
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;If the lock is taken&lt;/th&gt;
&lt;th&gt;Released&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pg_advisory_lock(key)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Waits&lt;/td&gt;
&lt;td&gt;When you call &lt;code&gt;pg_advisory_unlock&lt;/code&gt;, or the session ends&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pg_try_advisory_lock(key)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns &lt;code&gt;false&lt;/code&gt; at once&lt;/td&gt;
&lt;td&gt;Same&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pg_advisory_xact_lock(key)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Waits&lt;/td&gt;
&lt;td&gt;Automatically at the end of the transaction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pg_try_advisory_xact_lock(key)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns &lt;code&gt;false&lt;/code&gt; at once&lt;/td&gt;
&lt;td&gt;Automatically at the end of the transaction&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Use cases
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Single-runner jobs:&lt;/strong&gt; cron-style tasks that must not overlap across instances.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Per-customer serialization:&lt;/strong&gt; call &lt;code&gt;pg_advisory_xact_lock(customer_id)&lt;/code&gt; at the start of a transaction so two workers never process the same customer at once.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Migration guards:&lt;/strong&gt; stop two deploys from running migrations at the same time. Several migration tools do this.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Two pitfalls
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Prefer the transaction-level versions.&lt;/strong&gt; Session-level locks outlive commits and rollbacks, so a forgotten unlock holds the lock until the connection closes. They are also unsafe behind a pooler in transaction mode, such as PgBouncer, because your next statement may run on a different connection.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keys are shared by the whole database.&lt;/strong&gt; Two unrelated features that both pick &lt;code&gt;42&lt;/code&gt; will block each other. Use the two-integer form, &lt;code&gt;pg_advisory_lock(namespace, id)&lt;/code&gt;, or a documented key scheme.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How deadlocks form
&lt;/h2&gt;

&lt;p&gt;A deadlock is a standstill. Two or more transactions each hold a lock the other needs, so each waits for the other forever. Waiting alone is normal in a database. A deadlock is waiting in a circle.&lt;/p&gt;

&lt;p&gt;Deadlocks depend entirely on the order of operations. If every transaction touches resources in the same order, a cycle cannot form.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example: two bank transfers in opposite directions
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Transaction A: move 100 from account 1 to account 2&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;accounts&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;accounts&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;-- waits for B&lt;/span&gt;

&lt;span class="c1"&gt;-- Transaction B: move 50 from account 2 to account 1, at the same moment&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;accounts&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;accounts&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;-- waits for A&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2F9ck9pn8njxx03b6yx0lo.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%2F9ck9pn8njxx03b6yx0lo.png" alt="deadlock · 2 transactions, 2 rows, 1 cycle" width="799" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;deadlock · 2 transactions, 2 rows, 1 cycle&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Step by step:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A locks account 1.&lt;/li&gt;
&lt;li&gt;B locks account 2.&lt;/li&gt;
&lt;li&gt;A tries to lock account 2 and waits for B.&lt;/li&gt;
&lt;li&gt;B tries to lock account 1 and waits for A.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Neither can finish, so neither will ever release its lock. Run each transfer alone and both succeed. The bug only appears when they overlap in time, which is why deadlocks often show up under load and not in testing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where deadlocks hide in real applications
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ledgers and transfers:&lt;/strong&gt; money moves between two accounts in either direction, as above.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overlapping batch jobs:&lt;/strong&gt; two jobs update the same set of rows but walk through them in different orders.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A single multi-row statement:&lt;/strong&gt; &lt;code&gt;UPDATE ... WHERE id IN (...)&lt;/code&gt; does not promise any lock order. Two concurrent statements over overlapping rows can lock them in opposite orders.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Foreign keys:&lt;/strong&gt; inserting child rows takes &lt;code&gt;FOR KEY SHARE&lt;/code&gt; on the parent row, which can collide with another transaction that updates or deletes that parent.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How Postgres detects and breaks a deadlock
&lt;/h2&gt;

&lt;p&gt;Postgres does not check for deadlocks on every lock wait. The check is expensive, and most waits end on their own within milliseconds. So Postgres is lazy: it waits first, and checks only if a transaction is still blocked after &lt;code&gt;deadlock_timeout&lt;/code&gt;, which defaults to 1 second.&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%2Fccf8p3oblbx7e3sfhb6e.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%2Fccf8p3oblbx7e3sfhb6e.png" alt="deadlock detection · 2 checks, 3 outcomes" width="800" height="599"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;deadlock detection · 2 checks, 3 outcomes&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The process has three steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Wait.&lt;/strong&gt; A blocked transaction sleeps for &lt;code&gt;deadlock_timeout&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build the wait-for graph.&lt;/strong&gt; If it is still blocked, Postgres traces who is waiting on whom.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Break the cycle.&lt;/strong&gt; If the graph contains a loop, Postgres aborts one transaction. The others are unblocked and complete.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The transaction that runs the check is normally the one that gets aborted, which is usually the one whose wait timer fired first. Do not write code that depends on which side loses.&lt;/p&gt;

&lt;h3&gt;
  
  
  What your application sees
&lt;/h3&gt;

&lt;p&gt;The aborted transaction fails with SQLSTATE &lt;code&gt;40P01&lt;/code&gt; and its whole transaction is rolled back:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ERROR:  deadlock detected
DETAIL:  Process 6021 waits for ShareLock on transaction 8113; blocked by process 6044.
         Process 6044 waits for ShareLock on transaction 8112; blocked by process 6021.
HINT:  See server log for query details.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The process IDs and transaction IDs differ every time. Postgres also writes the full details, including the queries involved, to the server log.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tuning &lt;code&gt;deadlock_timeout&lt;/code&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lower values&lt;/strong&gt; find real deadlocks sooner, but add checking work to every lock wait that lasts longer than the timeout.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Higher values&lt;/strong&gt; reduce that work, but a real deadlock then stalls the stuck transactions for longer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The 1 second default suits most systems. It is also the threshold for &lt;code&gt;log_lock_waits&lt;/code&gt;, which logs any lock wait longer than &lt;code&gt;deadlock_timeout&lt;/code&gt; and is worth enabling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preventing locks and deadlocks
&lt;/h2&gt;

&lt;p&gt;You cannot remove locking, and you should not try. You can make waits short and cycles impossible. Five habits do most of the work.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Lock in a consistent order
&lt;/h3&gt;

&lt;p&gt;This is the most effective fix. If every transaction locks rows in the same order, a cycle cannot form. The second transaction simply waits for the first.&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%2Fbqmfdg682a4sjbuqaw0b.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%2Fbqmfdg682a4sjbuqaw0b.png" alt="lock ordering · deadlock vs short wait" width="800" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;lock ordering · deadlock vs short wait&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In the transfer example, always lock the lower account ID first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;accounts&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="k"&gt;FOR&lt;/span&gt; &lt;span class="k"&gt;UPDATE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;-- lowest ID first&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;accounts&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;accounts&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;COMMIT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For batch jobs, sort the IDs in your application before you send a bulk &lt;code&gt;UPDATE&lt;/code&gt;, so every job walks the rows in the same order.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Keep transactions short
&lt;/h3&gt;

&lt;p&gt;A transaction holds its locks until it ends, so every millisecond inside it widens the window for a collision. Do slow work before &lt;code&gt;BEGIN&lt;/code&gt; or after &lt;code&gt;COMMIT&lt;/code&gt;, never between.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Bad: the row stays locked during a slow network call&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;BEGIN&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UPDATE orders SET status = $1 WHERE id = $2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;paid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;paymentApi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;capture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;COMMIT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Better: slow work first, then one quick statement&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;receipt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;paymentApi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;capture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UPDATE orders SET status = $1 WHERE id = $2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;paid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also set &lt;code&gt;idle_in_transaction_session_timeout&lt;/code&gt;. It ends sessions that open a transaction and then sit idle, which would otherwise hold locks indefinitely.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Retry when a deadlock happens
&lt;/h3&gt;

&lt;p&gt;In a busy system, an occasional deadlock is normal. Catch SQLSTATE &lt;code&gt;40P01&lt;/code&gt; (deadlock) and &lt;code&gt;40001&lt;/code&gt; (serialization failure), roll back, and run the whole transaction again after a short, randomized delay.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Pool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PoolClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pg&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Pool&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;RETRYABLE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;40P01&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;40001&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;withRetry&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;work&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PoolClient&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;attempts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;attempt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;attempt&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;BEGIN&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;work&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;COMMIT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;err&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ROLLBACK&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;RETRYABLE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;attempt&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;attempts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="c1"&gt;// exponential backoff with jitter&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;delay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;attempt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;release&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The retried work must be safe to run twice. Keep external side effects, such as emails and payments, outside the transaction.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Do not wait when you do not have to
&lt;/h3&gt;

&lt;p&gt;Sometimes the best way to avoid lock trouble is to refuse to queue. Postgres gives you three tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;SKIP LOCKED&lt;/code&gt;:&lt;/strong&gt; ignore rows another transaction has locked and take the next ones.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;NOWAIT&lt;/code&gt;:&lt;/strong&gt; fail immediately with error &lt;code&gt;55P03&lt;/code&gt; if a row is locked.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;lock_timeout&lt;/code&gt;:&lt;/strong&gt; fail with the same error after a set time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The classic use case is a job queue. With a plain &lt;code&gt;FOR UPDATE&lt;/code&gt;, every worker reaches for the same first row and the rest line up behind it.&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%2F47m35461ilw54geidzd3.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%2F47m35461ilw54geidzd3.png" alt="job queue · plain FOR UPDATE vs SKIP LOCKED" width="800" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;job queue · plain FOR UPDATE vs SKIP LOCKED&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;jobs&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'pending'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;FOR&lt;/span&gt; &lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;SKIP&lt;/span&gt; &lt;span class="n"&gt;LOCKED&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;-- process the job, then:&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;jobs&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'done'&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;COMMIT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Workers no longer block each other on the same job. &lt;code&gt;SKIP LOCKED&lt;/code&gt; gives each caller a deliberately incomplete view of the table, so use it for queues and work distribution, not for general reads. Strict first-in-first-out ordering is also not guaranteed.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Lock only what you need
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pick the weakest row lock that works.&lt;/strong&gt; If you only need to stop concurrent updates and are not changing key columns, &lt;code&gt;FOR NO KEY UPDATE&lt;/code&gt; blocks less than &lt;code&gt;FOR UPDATE&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Touch fewer rows.&lt;/strong&gt; Narrow the &lt;code&gt;WHERE&lt;/code&gt; clause and do not update rows whose values will not change.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Index foreign key columns.&lt;/strong&gt; Without an index on the referencing column, checks and cascading deletes scan more of the table and hold locks for longer.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Diagnosing lock problems in production
&lt;/h2&gt;

&lt;p&gt;There are two kinds of symptoms. Queries that hang point to a lock wait, and the fix is to find the blocker. &lt;code&gt;deadlock detected&lt;/code&gt; errors point to a lock-ordering bug, and the fix is in your code. Start by finding out who is blocking whom.&lt;/p&gt;

&lt;h3&gt;
  
  
  Find the blocked queries
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;pg_blocking_pids&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;blocked_by&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;wait_event_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;wait_event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;query_start&lt;/span&gt;    &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;waiting_for&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;        &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;pg_stat_activity&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;cardinality&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pg_blocking_pids&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each row is a session that is waiting. &lt;code&gt;blocked_by&lt;/code&gt; lists the process IDs holding the lock it needs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Find the blockers
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;xact_start&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;transaction_age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;last_query&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;pg_stat_activity&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;unnest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pg_blocking_pids&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;pg_stat_activity&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The usual culprit is a session in state &lt;code&gt;idle in transaction&lt;/code&gt;. An application opened a transaction, did some work, and then stopped talking to the database without committing. Its locks stay held. The &lt;code&gt;last_query&lt;/code&gt; column shows the last statement it ran, which usually points to the code path at fault.&lt;/p&gt;

&lt;p&gt;If you must unblock production, &lt;code&gt;pg_cancel_backend(pid)&lt;/code&gt; cancels the running query. &lt;code&gt;pg_terminate_backend(pid)&lt;/code&gt; closes the connection and rolls back its transaction. Fix the cause afterwards, because the same blocker will come back.&lt;/p&gt;

&lt;p&gt;For the full picture, the &lt;code&gt;pg_locks&lt;/code&gt; view lists every lock that is held or awaited. A row-lock wait shows up there as a wait on the holder's &lt;code&gt;transactionid&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Settings worth reviewing
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setting&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;th&gt;Advice&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;log_lock_waits&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Logs any lock wait longer than &lt;code&gt;deadlock_timeout&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Turn it on&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;deadlock_timeout&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;How long to wait before checking for a deadlock&lt;/td&gt;
&lt;td&gt;Keep the 1 second default&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lock_timeout&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Makes a statement give up if it waits too long for a lock&lt;/td&gt;
&lt;td&gt;Set it per session for migrations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;idle_in_transaction_session_timeout&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Ends sessions that sit idle inside a transaction&lt;/td&gt;
&lt;td&gt;Set a value that fits your app&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Reading a deadlock in the server log
&lt;/h3&gt;

&lt;p&gt;When a deadlock happens, the log shows each process, the lock it waited for, and the query it was running. Find the two statements and write down the order in which each one locks rows. They will be opposite. Make both code paths lock in the same order and the deadlock goes away.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cheat sheet: symptom, cause, fix
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;Likely cause&lt;/th&gt;
&lt;th&gt;Fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Everything hangs right after a deploy&lt;/td&gt;
&lt;td&gt;A migration is waiting for &lt;code&gt;ACCESS EXCLUSIVE&lt;/code&gt;, and other queries have queued behind it&lt;/td&gt;
&lt;td&gt;Cancel it. Rerun with &lt;code&gt;lock_timeout&lt;/code&gt;, and use &lt;code&gt;CREATE INDEX CONCURRENTLY&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Many queries stuck on one row&lt;/td&gt;
&lt;td&gt;A hot row updated inside long transactions&lt;/td&gt;
&lt;td&gt;Shorten transactions, or use one atomic &lt;code&gt;UPDATE&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;deadlock detected&lt;/code&gt; (&lt;code&gt;40P01&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Transactions lock rows in different orders&lt;/td&gt;
&lt;td&gt;Lock in a consistent order, and retry with backoff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sessions &lt;code&gt;idle in transaction&lt;/code&gt; holding locks&lt;/td&gt;
&lt;td&gt;The app opened a transaction and then stalled, or crashed&lt;/td&gt;
&lt;td&gt;Set &lt;code&gt;idle_in_transaction_session_timeout&lt;/code&gt;, and keep transactions short&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Workers queue up on a job table&lt;/td&gt;
&lt;td&gt;Plain &lt;code&gt;SELECT ... FOR UPDATE&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Use &lt;code&gt;FOR UPDATE SKIP LOCKED&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Two servers run the same cron job&lt;/td&gt;
&lt;td&gt;No coordination between instances&lt;/td&gt;
&lt;td&gt;Use &lt;code&gt;pg_try_advisory_lock&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Locks are not the enemy. They are how Postgres keeps concurrent writers from corrupting each other's data. Trouble starts when locks are held too long or requested in conflicting orders. Keep three ideas in mind:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Locks last until the transaction ends.&lt;/strong&gt; Short transactions mean short waits.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Readers never block writers, but writers block writers, and schema changes block everyone.&lt;/strong&gt; Treat &lt;code&gt;ALTER TABLE&lt;/code&gt; on a busy table with respect.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deadlocks come from inconsistent ordering.&lt;/strong&gt; Lock in the same order everywhere, and retry when one slips through.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When something does go wrong, &lt;code&gt;pg_stat_activity&lt;/code&gt; and &lt;code&gt;pg_blocking_pids()&lt;/code&gt; will usually show you the blocker within a minute.&lt;/p&gt;

&lt;h3&gt;
  
  
  Further reading
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.postgresql.org/docs/current/explicit-locking.html" rel="noopener noreferrer"&gt;PostgreSQL docs: Explicit Locking&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.postgresql.org/docs/current/sql-lock.html" rel="noopener noreferrer"&gt;PostgreSQL docs: LOCK&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cybertec-postgresql.com/en/postgresql-understanding-deadlocks/" rel="noopener noreferrer"&gt;CYBERTEC: Understanding deadlocks in PostgreSQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://planetscale.com/blog/deadlocks-and-downtime" rel="noopener noreferrer"&gt;PlanetScale: Deadlocks and downtime&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@hnasr/postgres-locks-a-deep-dive-9fc158a5641c" rel="noopener noreferrer"&gt;Hussein Nasser: Postgres locks, a deep dive&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>postgres</category>
      <category>database</category>
      <category>sql</category>
      <category>backend</category>
    </item>
    <item>
      <title>How Databases Scale to Millions of Reads and Writes per Second</title>
      <dc:creator>Muhammad Ahsan Farooq </dc:creator>
      <pubDate>Fri, 09 Oct 2026 20:31:02 +0000</pubDate>
      <link>https://dev.to/ahsanfarooq210/how-databases-scale-to-millions-of-reads-and-writes-per-second-4o29</link>
      <guid>https://dev.to/ahsanfarooq210/how-databases-scale-to-millions-of-reads-and-writes-per-second-4o29</guid>
      <description>&lt;p&gt;&lt;em&gt;Replicas, caches, sharding, LSM-trees, and the consistency trade-offs that come with each&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Every database hits a ceiling. One server can take only so many CPU cores and so much RAM before the next upgrade costs far more than it delivers. To serve millions of operations per second, you stop making one machine faster and start spreading the work across many.&lt;/p&gt;

&lt;p&gt;Two terms get mixed up here. &lt;strong&gt;Performance&lt;/strong&gt; is how fast the system answers a single request. &lt;strong&gt;Scalability&lt;/strong&gt; is whether it keeps answering that fast as load grows. A database can be quick at 100 requests per second and fall over at 100,000. This post is about the second problem.&lt;/p&gt;

&lt;p&gt;The core idea is to split the read path from the write path, because they fail in different ways and need different tools. Then choose storage engines, caches and consistency models that fit each path, and accept the trade-offs between consistency, availability and latency.&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%2Fqjy995m6c40txcbaee2x.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%2Fqjy995m6c40txcbaee2x.png" alt="Read path and write path" width="799" height="323"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;read path and write path · 6 components, 2 lanes&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Reads are served from copies: an edge cache, a distributed cache and replicas. Writes are buffered by a queue and split across shards.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In this post:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Part 1:&lt;/strong&gt; scaling reads with replicas, caches, indexes and denormalization&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 2:&lt;/strong&gt; scaling writes with sharding, LSM-trees, queues and connection pools&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 3:&lt;/strong&gt; consistency models, CAP, PACELC and distributed SQL&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A one-page cheat sheet&lt;/strong&gt; you can keep&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Part 1: Scaling reads
&lt;/h2&gt;

&lt;p&gt;In most web applications, reads outnumber writes by 100:1 or even 1,000:1. That imbalance is good news: reads are easier to scale, because the same data can be copied and served from many places.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Primary-replica replication
&lt;/h3&gt;

&lt;p&gt;Send every write to one &lt;strong&gt;primary&lt;/strong&gt; node. The primary streams those changes to one or more read-only &lt;strong&gt;replicas&lt;/strong&gt;, and a load balancer spreads read traffic across the replica pool. Add replicas and read capacity grows almost linearly.&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%2F84x6j8i8k69ubia72jw8.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%2F84x6j8i8k69ubia72jw8.png" alt="Primary-replica replication" width="800" height="325"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;primary-replica replication · 1 primary, 3 replicas&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Replicas can lag the primary slightly. The dashed path sends a user who just wrote back to the primary, so they always see their own change.&lt;/p&gt;

&lt;p&gt;The catch is &lt;strong&gt;replication lag&lt;/strong&gt;. Replication is usually asynchronous, so the primary does not wait for replicas before acknowledging a write. That keeps write latency low, but a replica can briefly serve stale data.&lt;/p&gt;

&lt;p&gt;For cases where staleness is visible to users, such as seeing your own post right after publishing it, use &lt;strong&gt;read-your-own-writes&lt;/strong&gt;. Route that user's reads to the primary (or a replica known to be caught up) for a short window, while everyone else reads from the asynchronous replicas.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Multi-layer distributed caching
&lt;/h3&gt;

&lt;p&gt;Sending millions of concurrent reads to a disk-backed database is unsustainable. Put a distributed in-memory cache such as Redis or Memcached in front of it. Large platforms report hit rates above 95-99%. Netflix's EVCache is a well-known example. At those rates the database sees only a small fraction of the real traffic.&lt;/p&gt;

&lt;p&gt;To see why this matters, take 1,000,000 reads per second. At a 90% hit rate, 100,000 reads reach the database. At 95%, 50,000 do. At 99%, only 10,000 do.&lt;/p&gt;

&lt;p&gt;Two patterns cover most cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cache-aside (lazy loading):&lt;/strong&gt; the application checks the cache first. On a miss, it reads from the database, fills the cache and returns the result.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write-through:&lt;/strong&gt; every update is written synchronously to both the cache and the database, so later reads get fresh data. The price is slightly higher write latency.&lt;/li&gt;
&lt;/ul&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%2F82v7cap3x36xjhow9f0t.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%2F82v7cap3x36xjhow9f0t.png" alt="Cache-aside read" width="800" height="309"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;cache-aside read · 1 decision, 2 paths&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The three common strategies behave differently on writes. Write-behind is covered in Part 2.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Strategy&lt;/th&gt;
&lt;th&gt;How it works&lt;/th&gt;
&lt;th&gt;Write latency&lt;/th&gt;
&lt;th&gt;Main risk&lt;/th&gt;
&lt;th&gt;Best for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cache-aside&lt;/td&gt;
&lt;td&gt;The app reads the cache and loads from the database on a miss&lt;/td&gt;
&lt;td&gt;Unchanged&lt;/td&gt;
&lt;td&gt;Stale entries until the TTL expires or you invalidate them&lt;/td&gt;
&lt;td&gt;Read-heavy data that tolerates brief staleness&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Write-through&lt;/td&gt;
&lt;td&gt;Every write goes to the cache and the database together&lt;/td&gt;
&lt;td&gt;Slightly higher&lt;/td&gt;
&lt;td&gt;Extra write cost for data that is rarely read&lt;/td&gt;
&lt;td&gt;Data that must be fresh on the next read&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Write-behind&lt;/td&gt;
&lt;td&gt;Writes hit the cache, which flushes to the database later&lt;/td&gt;
&lt;td&gt;Lowest&lt;/td&gt;
&lt;td&gt;Unflushed writes are lost if the cache node fails&lt;/td&gt;
&lt;td&gt;Bursty writes where small loss risk is acceptable&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  3. Preventing cache stampedes
&lt;/h3&gt;

&lt;p&gt;When a popular key expires, thousands of requests can miss the cache in the same millisecond. If nothing stops them, they all hit the database with the same query. This is a &lt;strong&gt;cache stampede&lt;/strong&gt;, also called the thundering herd, and it can turn one expired key into an outage.&lt;/p&gt;

&lt;p&gt;Two defenses work well together:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Request coalescing:&lt;/strong&gt; the first request for a missing key goes to the database. Duplicate requests wait for that single result and are served from the new cache entry.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Probabilistic early expiration:&lt;/strong&gt; each request has a small, growing chance of refreshing a key in the background as it nears its TTL, so the key is usually refreshed before it ever expires.&lt;/li&gt;
&lt;/ul&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%2Fq1aa1vmv8u5iq9ywjo4e.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%2Fq1aa1vmv8u5iq9ywjo4e.png" alt="Request coalescing, before and after" width="799" height="317"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;request coalescing · before and after&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The database sees one query instead of thousands, and the waiting requests are served from the fresh entry.&lt;/p&gt;

&lt;p&gt;Here is a minimal cache-aside read with in-process coalescing in TypeScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;inflight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cached&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`user:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cached&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cached&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Coalesce: one database query per key, everyone else awaits it&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;inflight&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;load&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`user:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;EX&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;})().&lt;/span&gt;&lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;inflight&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="nx"&gt;inflight&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;load&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;inflight&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This coalesces per process only. Across a fleet of servers, you still get one query per server, so use a distributed lock or a caching proxy for global coalescing. Adding random jitter to TTLs also stops many keys from expiring together.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Indexing and denormalization
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Indexes:&lt;/strong&gt; a secondary index (usually a B-tree or B+ tree) turns a full-table scan, O(N), into a logarithmic lookup, O(log N). It is the cheapest read optimization you have.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Denormalization:&lt;/strong&gt; multi-table JOINs get expensive at scale in both CPU and disk I/O. Duplicating the fields you need into the target record, or into a materialized view, replaces the join with a fast, flat lookup. You pay for it with extra storage and more work to keep copies in sync.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;In short:&lt;/strong&gt; copy the data (replicas), keep hot data in memory (caches), and make each lookup cheaper (indexes and denormalization).&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 2: Scaling writes
&lt;/h2&gt;

&lt;p&gt;Write-heavy systems such as real-time messaging, IoT telemetry and clickstream logging are harder. Read replicas do not help, because every write still has to land on a primary storage engine. You need to spread the writes themselves.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Sharding (horizontal partitioning)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Sharding&lt;/strong&gt; splits one large dataset across several independent database nodes. Each node, or shard, holds a distinct slice of the data. A &lt;strong&gt;shard key&lt;/strong&gt;, such as &lt;code&gt;user_id&lt;/code&gt; or a hash of a composite key, decides which shard stores a given row.&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%2F4brynskvpcmtzp02s4oi.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%2F4brynskvpcmtzp02s4oi.png" alt="Shard key choice: balanced vs hot shard" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;shard key choice · balanced vs hot shard&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;With range partitioning, the newest IDs always land on the last shard. A hashed key spreads the same writes across every shard.&lt;/p&gt;

&lt;p&gt;The key you pick matters more than almost anything else:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Avoid hot keys.&lt;/strong&gt; With range-based partitioning, sequentially increasing IDs send all new writes to the last shard. The rest of the cluster sits idle.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prefer high-cardinality, evenly distributed keys.&lt;/strong&gt; UUIDs or hash-based partitioning spread writes across every node.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Know the trade-off.&lt;/strong&gt; Hash sharding balances load but makes range scans and cross-shard queries more expensive.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Write-optimized storage engines: LSM-trees vs B-trees
&lt;/h3&gt;

&lt;p&gt;Traditional relational databases use &lt;strong&gt;B-trees&lt;/strong&gt;, which update pages in place. Under heavy write volume, those random disk writes become the bottleneck.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Log-structured merge-trees (LSM-trees)&lt;/strong&gt; avoid this. Wide-column and key-value stores such as Apache Cassandra, ScyllaDB and RocksDB use them. A write goes to an in-memory buffer (the &lt;strong&gt;MemTable&lt;/strong&gt;) and is flushed to disk as an immutable, sorted file (an &lt;strong&gt;SSTable&lt;/strong&gt;). Because the disk work is sequential, these engines sustain millions of writes per second at very low write latency.&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%2F4lq66400gb18lh0gedy6.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%2F4lq66400gb18lh0gedy6.png" alt="LSM-tree write path" width="800" height="326"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;LSM-tree write path · memory to disk to compaction&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The trade-off shows up on reads. A lookup may check the MemTable and several SSTables, and background compaction has to merge files over time. LSM-trees buy write throughput with read and compaction cost.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;B-tree&lt;/th&gt;
&lt;th&gt;LSM-tree&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Write pattern&lt;/td&gt;
&lt;td&gt;Random, in-place page updates&lt;/td&gt;
&lt;td&gt;Sequential appends&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Write throughput&lt;/td&gt;
&lt;td&gt;Limited by random disk I/O&lt;/td&gt;
&lt;td&gt;Very high&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Read cost&lt;/td&gt;
&lt;td&gt;One tree lookup&lt;/td&gt;
&lt;td&gt;May check the MemTable and several SSTables&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Background work&lt;/td&gt;
&lt;td&gt;Page splits and rebalancing&lt;/td&gt;
&lt;td&gt;Compaction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Typical engines&lt;/td&gt;
&lt;td&gt;Traditional relational databases&lt;/td&gt;
&lt;td&gt;Cassandra, ScyllaDB, RocksDB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  3. Asynchronous buffering and event streaming
&lt;/h3&gt;

&lt;p&gt;To absorb bursts, put a durable queue such as &lt;strong&gt;Apache Kafka&lt;/strong&gt; or RabbitMQ between your application and the database. The API accepts the event and returns quickly. Ingestion workers then consume from the queue, group individual writes into batches and bulk-insert them.&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%2F8up0ia36viwi57zlduef.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%2F8up0ia36viwi57zlduef.png" alt="Asynchronous write buffering" width="800" height="189"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;asynchronous write buffering · 4 stages&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This &lt;strong&gt;load leveling&lt;/strong&gt; protects the database from sudden spikes and prevents thread starvation in the application tier. The cost is that writes become eventually visible, which your product has to be able to tolerate.&lt;/p&gt;

&lt;p&gt;A related pattern is &lt;strong&gt;write-behind (write-back) caching&lt;/strong&gt;. The application writes to the cache, and the cache flushes to the database asynchronously. It is very fast, but data not yet flushed can be lost if the cache node fails, so use it only where that risk is acceptable.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Connection pooling
&lt;/h3&gt;

&lt;p&gt;Opening a new database connection for every API request costs real CPU and memory. Unclosed connections are worse. They leak, exhaust the pool and eventually starve threads.&lt;/p&gt;

&lt;p&gt;Keep a &lt;strong&gt;pool&lt;/strong&gt; of persistent, reusable connections, or put a database proxy in front of the database. This removes most handshake overhead and keeps throughput stable under high concurrency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In short:&lt;/strong&gt; split the writes across nodes, use an engine built for appends, and buffer bursts behind a queue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 3: Consistency, CAP and distributed SQL
&lt;/h2&gt;

&lt;p&gt;Once data spreads across nodes and regions, network partitions stop being hypothetical. They happen. The &lt;strong&gt;CAP theorem&lt;/strong&gt; says that during a partition you must choose between consistency and availability. &lt;strong&gt;PACELC&lt;/strong&gt; extends it: even with no partition, you still trade latency against consistency, because coordinating replicas takes time.&lt;/p&gt;

&lt;p&gt;Read the decision tree below from the top. First ask whether a partition is happening, then follow the trade-off that applies.&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%2Fj80sk75xs6mptv2gzwul.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%2Fj80sk75xs6mptv2gzwul.png" alt="CAP and PACELC decision tree" width="800" height="363"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;CAP and PACELC decision tree · 1 question, 2 branches, 4 outcomes&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Cassandra and DynamoDB sit on the availability and low-latency side. Spanner and Aurora DSQL pay in latency to keep consistency.&lt;/p&gt;

&lt;h3&gt;
  
  
  AP vs CP systems
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AP (availability + partition tolerance):&lt;/strong&gt; Apache Cassandra and Amazon DynamoDB, in their default setups, keep accepting writes during a partition and synchronize in the background. The result is &lt;strong&gt;eventual consistency&lt;/strong&gt;. Replicas converge, but readers may briefly see different values.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CP (consistency + partition tolerance):&lt;/strong&gt; MongoDB and HBase favor consistency. If a node cannot reach a quorum, it refuses reads or writes instead of risking stale or conflicting data. You give up availability for the duration of the partition.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Many of these systems are tunable, so treat the labels as defaults, not absolutes. A practical rule: choose AP when a stale read is tolerable (feeds, carts, telemetry), and CP when a wrong answer costs money (payments, inventory, ledgers).&lt;/p&gt;

&lt;h3&gt;
  
  
  Distributed SQL
&lt;/h3&gt;

&lt;p&gt;Distributed SQL databases such as Google Spanner and Amazon Aurora DSQL aim for both worlds: SQL, ACID transactions and strong guarantees, with multi-region, active-active availability and no hand-written sharding in your application.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Optimistic concurrency control (OCC):&lt;/strong&gt; Aurora DSQL runs a read-write transaction locally without taking locks up front. At commit time, an adjudicator service checks whether a conflicting transaction wrote to the same keys during that window. If one did, a transaction is rejected and must be retried. OCC works best when conflicts are rare, and your application code must be ready to retry.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Synchronized clocks:&lt;/strong&gt; Spanner (TrueTime) and Aurora DSQL (Amazon Time Sync) rely on precisely synchronized clocks to give transactions a consistent global order. That lets reads be served from the local region with strong snapshot semantics, without a cross-region round trip for every read.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not free. Commits that span regions still pay a latency cost for coordination, which is exactly the latency-versus-consistency trade-off PACELC describes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In short:&lt;/strong&gt; pick consistency or availability per feature, and know what each database does when the network breaks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cheat sheet
&lt;/h2&gt;

&lt;p&gt;Reads scale by copying data to more places. Writes scale by splitting data across more nodes.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Read-heavy workloads&lt;/th&gt;
&lt;th&gt;Write-heavy workloads&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Data partitioning&lt;/td&gt;
&lt;td&gt;Read replicas (primary-replica)&lt;/td&gt;
&lt;td&gt;Horizontal sharding with evenly distributed hash keys&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Caching&lt;/td&gt;
&lt;td&gt;Cache-aside or write-through (Redis, Memcached)&lt;/td&gt;
&lt;td&gt;Write-behind (asynchronous cache-to-database flush)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage engine&lt;/td&gt;
&lt;td&gt;B+ tree indexes and denormalized views&lt;/td&gt;
&lt;td&gt;LSM-trees&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ingestion&lt;/td&gt;
&lt;td&gt;CDN or edge caching, request coalescing&lt;/td&gt;
&lt;td&gt;Message queues (Kafka) and batching&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Consistency&lt;/td&gt;
&lt;td&gt;Eventual consistency, read-your-own-writes&lt;/td&gt;
&lt;td&gt;Distributed SQL with OCC, or CRDTs for conflict-free multi-region writes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Scaling to millions of operations per second is rarely one big trick. It is a series of small decisions, made in a sensible order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Index and denormalize before you buy more hardware.&lt;/li&gt;
&lt;li&gt;Add replicas and a cache to absorb reads, and guard against stampedes.&lt;/li&gt;
&lt;li&gt;When writes outgrow one node, shard on an evenly distributed key and consider a write-optimized engine.&lt;/li&gt;
&lt;li&gt;Buffer bursts with a queue and pool your connections.&lt;/li&gt;
&lt;li&gt;Decide, feature by feature, how much staleness you can accept, and choose AP or CP behavior to match.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Every step buys capacity and charges you in consistency, complexity or operational cost. Measure before you add the next layer.&lt;/p&gt;

&lt;p&gt;Two topics worth exploring next: &lt;strong&gt;write-behind caching with Redis Streams&lt;/strong&gt;, and &lt;strong&gt;conflict-free replicated data types (CRDTs)&lt;/strong&gt; for resolving conflicts in multi-region AP databases.&lt;/p&gt;

</description>
      <category>database</category>
      <category>systemdesign</category>
      <category>backend</category>
      <category>scalability</category>
    </item>
    <item>
      <title>Beyond Microservices: Surviving the Storm with Cell-Based Architecture</title>
      <dc:creator>Muhammad Ahsan Farooq </dc:creator>
      <pubDate>Tue, 03 Mar 2026 16:39:30 +0000</pubDate>
      <link>https://dev.to/ahsanfarooq210/beyond-microservices-surviving-the-storm-with-cell-based-architecture-bnm</link>
      <guid>https://dev.to/ahsanfarooq210/beyond-microservices-surviving-the-storm-with-cell-based-architecture-bnm</guid>
      <description>&lt;p&gt;&lt;em&gt;Containing failures before they become outages, with lessons from Slack, DoorDash, and AWS&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For a decade, the answer to scaling was to break the monolith. Slice a giant codebase along domain lines, and let independent services scale, deploy and fail on their own. Microservices delivered on that promise, up to a point.&lt;/p&gt;

&lt;p&gt;Then systems grew. Dozens of services became hundreds. They shared databases, caches and queues, and each of those became load-bearing. Teams added circuit breakers, retries and timeouts. Those tools help, but they treat symptoms. Slowly, teams had rebuilt the monolith with network hops in between: a &lt;strong&gt;networked monolith&lt;/strong&gt;, where one sick component can slow down everyone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cell-based architecture&lt;/strong&gt; goes after the root cause. Instead of one big shared pool that serves all customers, you run many small, identical, self-contained copies of your whole stack, called &lt;strong&gt;cells&lt;/strong&gt;. Each cell serves a slice of your customers. When something breaks, only that slice is affected.&lt;/p&gt;

&lt;p&gt;This post explains how cells work, why they contain failures, and how to adopt them, with examples from Slack, DoorDash and AWS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In this post:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The problem:&lt;/strong&gt; gray failures, and why shared infrastructure turns small faults into global outages&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What a cell is,&lt;/strong&gt; and the one rule that makes the pattern work&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The router:&lt;/strong&gt; partition keys, cell mapping and request flow&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Failover and draining,&lt;/strong&gt; and the arithmetic of blast radius&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Case studies:&lt;/strong&gt; Slack, DoorDash and AWS shuffle sharding&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An adoption playbook,&lt;/strong&gt; the costs, and a readiness checklist&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The problem: from monolith to networked monolith
&lt;/h2&gt;

&lt;p&gt;A classic microservice stack looks clean on a whiteboard. A pool of web servers feeds a pool of application servers, which share one database cluster and one global Redis cache. Traffic round-robins across everything, and scaling out is easy: add more pods.&lt;/p&gt;

&lt;p&gt;The weakness is not scale. It is &lt;strong&gt;interconnection&lt;/strong&gt;. Every request path depends on the same shared infrastructure, so a small fault in one corner can reach everyone.&lt;/p&gt;

&lt;h3&gt;
  
  
  Binary failures vs gray failures
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Binary failures are the easy kind.&lt;/strong&gt; A server crashes or a database goes offline. Health checks notice, the load balancer stops sending traffic, and automation takes over.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gray failures are the dangerous kind.&lt;/strong&gt; A component is degraded but not dead, so nothing triggers automated remediation. Slack describes them as failures where different components have different views of whether the system is available. A highway with one lane crawling at 10 mph does not stop traffic. It backs it up until everything gridlocks.&lt;/p&gt;

&lt;p&gt;Common gray failures include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Packet loss within a single Availability Zone&lt;/li&gt;
&lt;li&gt;A Redis shard slowing down under memory pressure&lt;/li&gt;
&lt;li&gt;A retry storm caused by a bad deployment config&lt;/li&gt;
&lt;li&gt;Connection pool exhaustion behind a slow dependency&lt;/li&gt;
&lt;li&gt;A noisy neighbor throttling CPU on a shared host&lt;/li&gt;
&lt;li&gt;DNS resolution latency spikes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How one slow node takes everything down
&lt;/h3&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%2F6gijl501qdex547m67n3.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%2F6gijl501qdex547m67n3.png" alt="gray failure cascade · illustrative, 4 stages" width="800" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;gray failure cascade · illustrative, 4 stages&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The numbers in the picture are illustrative, but the arithmetic behind the mechanism is not. Little's law says the number of requests in flight equals the arrival rate times the average time each one takes. Suppose an app tier has 100 worker threads, receives 1,000 requests per second, and normally answers in 50 ms. Now 10% of requests touch the slow node and take 2 seconds:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Average latency&lt;/th&gt;
&lt;th&gt;Threads needed&lt;/th&gt;
&lt;th&gt;Threads available&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Healthy&lt;/td&gt;
&lt;td&gt;50 ms&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10% of requests hit the slow node&lt;/td&gt;
&lt;td&gt;0.9 × 50 ms + 0.1 × 2,000 ms = 245 ms&lt;/td&gt;
&lt;td&gt;245&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The pool is exhausted, even though 90% of requests are perfectly healthy. Once threads run out, the healthy requests queue up behind the slow ones, and everyone sees the slowdown. Retries make it worse by adding load to a tier that is already struggling.&lt;/p&gt;

&lt;p&gt;The standard defenses are circuit breakers, bulkheaded thread pools, timeouts and retries with jitter. They help at the margins, but they all treat symptoms. The root cause is that &lt;strong&gt;all requests share all infrastructure&lt;/strong&gt;, so the blast radius of any failure is effectively the whole platform.&lt;/p&gt;

&lt;p&gt;Slack's own incident review asked the question this way after a 2021 network fault in a single Availability Zone: why was this outage visible to users at all? The answer led to the design in this post.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a cell is
&lt;/h2&gt;

&lt;p&gt;The name comes from marine engineering. Ships are built with watertight bulkheads, walls that divide the hull into compartments. If the hull is breached, only the damaged compartment floods. A common retelling of the Titanic's sinking is that its bulkheads did not reach high enough, so water spilled from one compartment into the next. The design assumption was violated, and the failure cascaded the way it does in a poorly isolated distributed system.&lt;/p&gt;

&lt;p&gt;AWS's guidance defines it precisely: a cell-based architecture uses multiple isolated instances of a workload. Each instance, a &lt;strong&gt;cell&lt;/strong&gt;, is independent, shares no state with other cells, and handles a subset of the overall requests. If a workload uses 10 cells to serve 100 requests, a failure in one cell leaves 90% of the requests unaffected.&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%2F2921jkuphf8pyqa6cpbg.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%2F2921jkuphf8pyqa6cpbg.png" alt="cell-based architecture · router, 4 cells, control plane" width="799" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;cell-based architecture · router, 4 cells, control plane&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The pattern has three parts:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Its job&lt;/th&gt;
&lt;th&gt;Design rule&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cell router&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Maps each request to exactly one cell&lt;/td&gt;
&lt;td&gt;The thinnest possible layer. It routes and does nothing else&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cell&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A complete workload that can run on its own&lt;/td&gt;
&lt;td&gt;No shared state, and no calls to other cells&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Control plane&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Provisions and removes cells, assigns and migrates tenants&lt;/td&gt;
&lt;td&gt;Keep it thin, read-mostly, and cacheable at the cell edge&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Building cells does not necessarily mean multiplying your infrastructure. AWS notes that an application with 30 hosts can keep the same 30 hosts, grouped into cells behind a router.&lt;/p&gt;

&lt;h3&gt;
  
  
  Anatomy of a cell
&lt;/h3&gt;

&lt;p&gt;A cell is not a single service or a single database. It is a complete copy of your application stack, scoped to a bounded set of tenants:&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%2Fu4a420tn07oxijdzza4y.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%2Fu4a420tn07oxijdzza4y.png" alt="inside one cell · compute, data, observability" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;inside one cell · compute, data, observability&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Every cell owns its own:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Compute:&lt;/strong&gt; API and worker containers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storage:&lt;/strong&gt; database shards, not a connection to a shared cluster&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache:&lt;/strong&gt; its own Redis or Memcached cluster&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Queues:&lt;/strong&gt; its own Kafka topics or SQS queues&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observability:&lt;/strong&gt; its own metrics namespace, so a sick cell stands out on a dashboard instead of being hidden inside a global average&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The golden rule: cells never talk to each other
&lt;/h3&gt;

&lt;p&gt;A request that enters Cell 4 lives and dies in Cell 4. There are no cross-cell service calls, no shared databases and no shared caches.&lt;/p&gt;

&lt;p&gt;This rule is not negotiable. The moment one cell depends on another, a slow cell can drag its neighbor down, and you have rebuilt the networked monolith with extra steps. If a request really needs data owned by another tenant, solve it at the routing layer by sending the request to the right cell, or by replicating data asynchronously. Never let cells call each other synchronously.&lt;/p&gt;

&lt;h3&gt;
  
  
  The control plane
&lt;/h3&gt;

&lt;p&gt;Some concerns sit outside any one cell: assigning tenants to cells, provisioning new cells, migrating tenants, global feature flags and billing state. These belong to the &lt;strong&gt;control plane&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The discipline is to keep it &lt;strong&gt;read-mostly&lt;/strong&gt; and to &lt;strong&gt;cache what cells need at the cell edge&lt;/strong&gt;. If the control plane has a brief outage, each cell should keep serving traffic from its cached state. A control plane outage must never become a cell outage.&lt;/p&gt;

&lt;h2&gt;
  
  
  The routing layer
&lt;/h2&gt;

&lt;p&gt;If cells are the body of this architecture, the router is the brain. AWS calls it the thinnest possible layer: it routes requests to the right cell, and only that. Every request passes through it, so it must be deterministic and extremely reliable. This is one of the few components worth over-engineering from the start.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: choose the partition key
&lt;/h3&gt;

&lt;p&gt;The partition key decides how customers are sliced across cells. It is the most consequential design decision in the whole system. AWS says the key should align with the grain of the service, meaning the natural way its workload can be divided with minimal cross-cell interaction.&lt;/p&gt;

&lt;p&gt;A good partition key has three properties:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;It co-locates related data.&lt;/strong&gt; Nearly everything a request needs belongs to the same key value.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It distributes reasonably evenly.&lt;/strong&gt; No single value carries a disproportionate share of traffic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It is present on every request.&lt;/strong&gt; The router can read it without extra lookups.&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Partition key&lt;/th&gt;
&lt;th&gt;Typical fit&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Organization or tenant ID&lt;/td&gt;
&lt;td&gt;B2B SaaS and multi-tenant platforms&lt;/td&gt;
&lt;td&gt;A workspace, company or account&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User ID&lt;/td&gt;
&lt;td&gt;Consumer apps with isolated user data&lt;/td&gt;
&lt;td&gt;Social, gaming and messaging apps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Region&lt;/td&gt;
&lt;td&gt;Compliance and data residency needs&lt;/td&gt;
&lt;td&gt;EU-only customer data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Order or delivery ID&lt;/td&gt;
&lt;td&gt;Workflows scoped to one transaction&lt;/td&gt;
&lt;td&gt;Food delivery, ride-hailing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Merchant or store ID&lt;/td&gt;
&lt;td&gt;Marketplaces&lt;/td&gt;
&lt;td&gt;One seller's catalog and orders&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Avoid keys that are too coarse, such as &lt;code&gt;country&lt;/code&gt;, where a single value could be larger than a cell can handle. Avoid keys that are too fine, such as &lt;code&gt;session_id&lt;/code&gt;, which would need an unmanageable number of cells. The sweet spot is an entity that owns a meaningful, bounded set of data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: map keys to cells
&lt;/h3&gt;

&lt;p&gt;The router needs to know which cell owns which key. There are three common approaches:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Approach&lt;/th&gt;
&lt;th&gt;How it works&lt;/th&gt;
&lt;th&gt;Strength&lt;/th&gt;
&lt;th&gt;Weakness&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Lookup table&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A small, fast store maps &lt;code&gt;org_id&lt;/code&gt; to &lt;code&gt;cell_id&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Flexible. Moving a tenant is one row update&lt;/td&gt;
&lt;td&gt;An extra lookup per request, so it must be cached aggressively&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Deterministic hash&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cell = hash(org_id) % number_of_cells&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No lookups, stateless and fast&lt;/td&gt;
&lt;td&gt;Adding cells reshuffles most tenants, and you cannot move one tenant alone&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Hybrid&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Hash by default, with a lookup table for exceptions&lt;/td&gt;
&lt;td&gt;Speed on the common path and flexibility where it matters&lt;/td&gt;
&lt;td&gt;Two mechanisms to maintain&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Most production systems end up with the hybrid. Large enterprise tenants get pinned to specific cells for compliance, capacity or contractual reasons, and everyone else is hashed. A useful refinement is to hash into a fixed number of buckets, such as 1,024, and map buckets to cells. Adding a cell then means reassigning a few buckets, not rehashing everyone.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BUCKETS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;cellFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;orgId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// 1. Pinned tenants (compliance, very large customers) come from the lookup table&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pinned&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pinnedTenants&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;orgId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pinned&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;pinned&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// 2. Everyone else: a stable hash picks a bucket, and the bucket maps to a cell&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;stableHash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;orgId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;BUCKETS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;bucketToCell&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: follow one request
&lt;/h3&gt;

&lt;p&gt;Here is the full lifecycle of a request for the tenant &lt;code&gt;acme-corp-7291&lt;/code&gt;:&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%2Fahz01lhbnnkpu6erubtg.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%2Fahz01lhbnnkpu6erubtg.png" alt="request lifecycle through the cell router · 7 steps" width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;request lifecycle through the cell router · 7 steps&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Step 4 matters. The router tracks cell health, so it can steer traffic away from a sick cell. That capability is what makes failover possible, which is the next topic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Failover and draining
&lt;/h2&gt;

&lt;p&gt;Because the router tracks cell health, it can act when a cell goes bad. What it should do depends on what kind of cell you built.&lt;/p&gt;

&lt;h3&gt;
  
  
  Two kinds of cells, two kinds of failover
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tenant-partitioned cells&lt;/strong&gt; own the data for specific tenants. If one fails, other cells cannot simply take over, because the tenant's data lives in the failed cell. The value here is containment: only that cell's tenants are affected, and the fix is scoped to one small environment. Recovery means repairing the cell, restoring it from backups, or failing over to a standby that holds replicated data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Replica cells&lt;/strong&gt; are interchangeable copies that can serve any customer, for example one per Availability Zone. Here the router can shift traffic from a sick cell to healthy ones. This is the model Slack uses.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Many systems combine both: cells aligned to Availability Zones, with tenants partitioned inside them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Draining, as Slack does it
&lt;/h3&gt;

&lt;p&gt;Slack's cells are Availability Zones. After a 2021 incident, its engineers set four goals for an AZ drain:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Move as much traffic as possible out of an AZ within 5 minutes.&lt;/li&gt;
&lt;li&gt;Cause no user-visible errors. In-flight requests finish normally.&lt;/li&gt;
&lt;li&gt;Make drains and undrains incremental, down to 1% of traffic, so a recovered AZ can be tested gently.&lt;/li&gt;
&lt;li&gt;Never depend on resources inside the AZ being drained.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To meet them, Slack made each service talk only to services in its own AZ, a design it calls &lt;strong&gt;silo&lt;/strong&gt;ing. Draining an AZ then needs no change inside the services. It only requires steering new user requests away at the edge. Edge Envoy load balancers receive per-AZ weights from a control plane, and an AZ whose weight is set to zero stops getting new requests while existing ones complete. The change propagates in seconds. Slack also chose to keep a human in the loop: an operator decides when to drain.&lt;/p&gt;

&lt;p&gt;The same idea works for any cell router. This picture shows the effect on three cells as Cell A is drained:&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%2F54hkerzb8r1gzytt9l0l.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%2F54hkerzb8r1gzytt9l0l.png" alt="illustrative router weights · 3 cells, 3 states" width="800" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;illustrative router weights · 3 cells, 3 states&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here is an illustrative control-plane routine. It lowers the weight in steps and stops if the receiving cells start to struggle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;drainCell&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cellId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;steps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;weight&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;controlPlane&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setCellWeight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cellId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// the router applies it within seconds&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="nx"&gt;_000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;                                &lt;span class="c1"&gt;// watch error rates before going further&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;errorRatesRising&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;otherCells&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cellId&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Drain paused: receiving cells are struggling&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Hard failover vs draining
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Hard failover&lt;/th&gt;
&lt;th&gt;Draining&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;How it works&lt;/td&gt;
&lt;td&gt;Remap all of a cell's traffic at once&lt;/td&gt;
&lt;td&gt;Shift weight gradually while in-flight requests finish&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Main risk&lt;/td&gt;
&lt;td&gt;A sudden surge overwhelms the receiving cells&lt;/td&gt;
&lt;td&gt;Slower to complete&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Capacity needed&lt;/td&gt;
&lt;td&gt;Spare capacity everywhere, immediately&lt;/td&gt;
&lt;td&gt;Spare capacity, claimed in steps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best for&lt;/td&gt;
&lt;td&gt;A cell that is completely down&lt;/td&gt;
&lt;td&gt;Gray failures, where you are still deciding&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Either way, the receiving cells need spare capacity. The next section works out how much.&lt;/p&gt;

&lt;h2&gt;
  
  
  Blast radius: the math that sells it
&lt;/h2&gt;

&lt;p&gt;With N equal cells, a failure in one cell affects about 1/N of your customers. AWS's example: with 10 cells serving 100 requests, a failure in one cell leaves 90% of the requests untouched.&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%2Fr0dlfhcy1lcbj542ye0w.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%2Fr0dlfhcy1lcbj542ye0w.png" alt="computed: 1/N users affected, 1/(N-1) spare capacity, for N equal cells" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;computed: 1/N users affected, 1/(N-1) spare capacity, for N equal cells&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The chart also shows the price of recovery. If a failed cell's traffic is spread evenly over the survivors, each one needs 1/(N-1) of spare capacity. With 10 cells that is about 11%. With 100 cells it is about 1%. If you instead pair cells so each fails over to a single neighbor, every cell must keep 100% spare capacity, which is why spreading the load matters. More cells mean a smaller blast radius and a smaller proportional safety margin, but also more environments to run.&lt;/p&gt;

&lt;h3&gt;
  
  
  Before and after
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Failure&lt;/th&gt;
&lt;th&gt;Without cells&lt;/th&gt;
&lt;th&gt;With 100 cells&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Bad deployment&lt;/td&gt;
&lt;td&gt;Reaches everyone as the rollout proceeds&lt;/td&gt;
&lt;td&gt;Rolled out cell by cell. The first cell exposes about 1% of customers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Corrupt data or a bad migration&lt;/td&gt;
&lt;td&gt;Every tenant is at risk&lt;/td&gt;
&lt;td&gt;Only the tenants in that cell&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Infrastructure fault&lt;/td&gt;
&lt;td&gt;Everyone sharing the infrastructure&lt;/td&gt;
&lt;td&gt;Contained to the affected cell, and traffic can be drained from it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Noisy tenant&lt;/td&gt;
&lt;td&gt;Degrades all other tenants&lt;/td&gt;
&lt;td&gt;Degrades only its own cell&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Poison pill request&lt;/td&gt;
&lt;td&gt;Can take down the shared pool&lt;/td&gt;
&lt;td&gt;Crashes one cell's workers, and the rest keep serving&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Before cells, one engineer pushing a bad config at 2 a.m. could take down the whole platform. After cells, the same mistake reaches 1% of customers. It is still an incident, but it is a small one that is recoverable and debuggable by a single on-call engineer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deploy one cell at a time
&lt;/h3&gt;

&lt;p&gt;Safe deployments get dramatically easier. In a pooled system, a canary sends 5 to 10% of global traffic to the new version, so a bug hits a random slice of all customers. With cells, you deploy to one cell. The affected customers are known, bounded and can even be notified. AWS recommends applying changes gradually, compartment by compartment.&lt;/p&gt;

&lt;p&gt;A rollout plan for 100 cells might look like this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Wave&lt;/th&gt;
&lt;th&gt;Cells&lt;/th&gt;
&lt;th&gt;Cumulative customers exposed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;One canary cell, ideally with internal or low-risk tenants&lt;/td&gt;
&lt;td&gt;1%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;The next 4 cells&lt;/td&gt;
&lt;td&gt;5%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;The next 20 cells&lt;/td&gt;
&lt;td&gt;25%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Everything else&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Pause between waves, watch per-cell error rates, and halt automatically if a wave looks worse than the baseline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-world case studies
&lt;/h2&gt;

&lt;p&gt;Three companies show three different ways to apply the idea. I checked each against the team's own write-up.&lt;/p&gt;

&lt;h3&gt;
  
  
  Slack: Availability Zones as cells
&lt;/h3&gt;

&lt;p&gt;On June 30, 2021, a network link between Availability Zones in Slack's main region began to fail intermittently. The cloud provider removed it, put it back, and removed it permanently later that day. On paper it was a routine hardware failure, so Slack's engineers asked why users saw it at all.&lt;/p&gt;

&lt;p&gt;The answer was a gray failure. One user request can fan out into hundreds of calls to backends, and every call must succeed. Failure detection needs some failures before it can exclude a bad server. Slack's main datastore also needs a single available primary for each write, so a shard whose primary is unreachable cannot accept writes. Different components held different views of what was healthy, and the whole system suffered.&lt;/p&gt;

&lt;p&gt;Slack's response was to treat each Availability Zone as a cell and to silo services so they only talk within their own zone. That turns an AZ drain into an edge routing change, as described in the previous section. The design target was to drain most of a zone's traffic within 5 minutes, which matters because Slack's 99.99% availability SLA allows less than an hour of total unavailability per year.&lt;/p&gt;

&lt;p&gt;Note what Slack did not do. Its cells are replicas aligned to Availability Zones, not partitions of customers by tenant. The pattern is flexible: what matters is that the isolation boundary is real, and that you can steer traffic around it.&lt;/p&gt;

&lt;h3&gt;
  
  
  DoorDash: cells for isolation, plus cheaper traffic
&lt;/h3&gt;

&lt;p&gt;DoorDash's microservices run in multiple isolated cells. Every service has one Kubernetes deployment per cell, and traffic between cells is not permitted, which limits the blast radius of a single cell failure. Services not yet migrated live in a global cell, reached through internal Envoy routers. Each cell is made of several Kubernetes clusters, and each cluster spans multiple Availability Zones.&lt;/p&gt;

&lt;p&gt;The cost problem came from success. As the number of microservices grew, so did cross-AZ data transfer charges, which are billed on both sending and receiving. DoorDash's answer was to enable Envoy's zone-aware routing in its service mesh, so callers prefer callees in their own zone, while still balancing load so no pod is overloaded. Even with pods spread evenly across zones, about 10% of traffic still crosses zones.&lt;/p&gt;

&lt;p&gt;The investigation is instructive. Flow logs and metrics showed that the largest source of cross-AZ cost was non-storage traffic within each cell, and about 20% of that cost was traffic to a single load balancer in front of an event ingestion pipeline. That path had several extra hops. DoorDash moved the service into the same cell as its clients and let their sidecars route directly to its pods. The savings were large enough that the cloud provider reached out to ask whether DoorDash was having a production incident.&lt;/p&gt;

&lt;p&gt;The lesson is that cells give you a bounded place to optimize. Because traffic stays inside a cell, you can count the hops and measure the cost. Note that the savings came from zone-aware routing, which the cell boundary made tractable. DoorDash did not publish a single overall percentage.&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS: shuffle sharding, cells without hard partitions
&lt;/h3&gt;

&lt;p&gt;Amazon uses a variant called &lt;strong&gt;shuffle sharding&lt;/strong&gt; for workloads where pinning each customer to one cell is impractical, such as DNS. Instead of one cell per customer, each customer gets a random subset of workers, and different customers get different subsets.&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%2Fumhrxkfumd97okj9swb2.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%2Fumhrxkfumd97okj9swb2.png" alt="shuffle sharding · 8 workers, 3 customers" width="799" height="344"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;shuffle sharding · 8 workers, 3 customers&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The arithmetic is simple. With 8 workers and 2 per customer, there are 28 possible pairs. Only a customer assigned the very same pair as the troublemaker loses both workers, which is 1 in 28, or about 3.6%. Ordinary sharding into 4 shards would put 25% of customers on the failed shard. Customers who share a single worker still have the other one, as long as their clients retry.&lt;/p&gt;

&lt;p&gt;Amazon Route 53 applies this at scale. It arranges capacity into 2,048 virtual name servers and gives every domain a shuffle shard of four, which allows about 730 billion distinct shards. No domain shares more than two virtual name servers with any other. If one domain is hit by a DDoS attack, its four name servers see a spike, and no other customer notices.&lt;/p&gt;

&lt;p&gt;Shuffle sharding needs no partition key and works well for stateless workloads. It is a useful tool when you cannot commit to hard cells.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation playbook
&lt;/h2&gt;

&lt;p&gt;You do not need to boil the ocean. Most teams start with two or three cells for one critical service and expand from there. Five phases cover the work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 1: find your partition key
&lt;/h3&gt;

&lt;p&gt;Look at your data model for the entity that naturally owns everything else. In B2B SaaS that is usually &lt;code&gt;org_id&lt;/code&gt; or &lt;code&gt;tenant_id&lt;/code&gt;. Draw the dependency graph and check that the vast majority of queries can be answered inside one tenant's scope.&lt;/p&gt;

&lt;p&gt;If you cannot find a clean partition key, stop here. Cells without one produce a system that is complex without being resilient.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 2: build the router
&lt;/h3&gt;

&lt;p&gt;Stand up a gateway that does four things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Extracts the partition key from the request, such as a JWT claim, a path parameter or a header&lt;/li&gt;
&lt;li&gt;Looks up the cell assignment from a fast, cached store&lt;/li&gt;
&lt;li&gt;Proxies the request to that cell's ingress&lt;/li&gt;
&lt;li&gt;Applies a configurable fallback policy when a cell is unavailable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keep it as thin as AWS recommends. Build on a battle-tested proxy such as Envoy or NGINX, and add cell-aware routing on top rather than writing a proxy from scratch.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 3: provision cells as code
&lt;/h3&gt;

&lt;p&gt;Every cell must be identical by definition. Use Terraform or Pulumi modules that take a &lt;code&gt;cell_id&lt;/code&gt; and stamp out the whole stack. Manual drift is a ticking time bomb: if Cell 7's Redis configuration differs subtly from Cell 12's, you will find out at the worst possible moment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt; &lt;span class="s2"&gt;"cell_12"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;source&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"./modules/cell"&lt;/span&gt;
  &lt;span class="nx"&gt;cell_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"cell-12"&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;
  &lt;span class="nx"&gt;az&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1b"&lt;/span&gt;

  &lt;span class="c1"&gt;# Capacity is identical for every cell&lt;/span&gt;
  &lt;span class="nx"&gt;api_instance_count&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
  &lt;span class="nx"&gt;worker_instance_count&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
  &lt;span class="nx"&gt;db_instance_class&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"db.r6g.large"&lt;/span&gt;
  &lt;span class="nx"&gt;redis_node_count&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tenant assignments belong in the control plane's data, not in the infrastructure code. Adding a cell should be a one-line change that triggers an automated pipeline. If it takes days of manual work, you will not spin up cells when you need them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 4: per-cell observability
&lt;/h3&gt;

&lt;p&gt;This is not optional, because it is how the whole design pays off. Tag every metric and log line with &lt;code&gt;cell_id&lt;/code&gt;. Build dashboards that show all cells side by side, so a degraded cell stands out like a red square in a grid of green. Alert on &lt;strong&gt;per-cell error rates&lt;/strong&gt;, not just global averages, because global averages are exactly the metric that hides localized failures.&lt;/p&gt;

&lt;p&gt;A useful test: if your on-call engineer has to query logs to find out which cell is sick, your observability is not good enough.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 5: build tenant migration tooling
&lt;/h3&gt;

&lt;p&gt;Build the tool that moves a tenant between cells before you need it in an emergency. You will need it when a cell becomes a hot spot, when an enterprise customer asks for data residency, and when you drain a degraded cell. One safe pattern is a dual-write with a delayed read flip:&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%2Fmfw8jxlm0mougcw4d8km.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%2Fmfw8jxlm0mougcw4d8km.png" alt="tenant migration · 6 stages, where reads and writes go" width="800" height="305"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;tenant migration · 6 stages, where reads and writes go&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Start dual-writing.&lt;/strong&gt; All new writes go to both cells. Reads still come from the old cell, the source of truth.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backfill.&lt;/strong&gt; Copy the historical data to the new cell, then compare checksums until they match.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flip reads&lt;/strong&gt; to the new cell and watch error rates for a few minutes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cut over.&lt;/strong&gt; Stop writing to the old cell and update the cell map so the tenant routes to the new cell.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clean up&lt;/strong&gt; the old cell's copy of the data.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The writes in step 1 must be idempotent and ordered, or the backfill can overwrite newer data with older data. Build that guarantee in from the start.&lt;/p&gt;

&lt;h2&gt;
  
  
  The cost: trade-offs you must accept
&lt;/h2&gt;

&lt;p&gt;Cell-based architecture is not free. Anyone selling it without discussing the costs is doing you a disservice.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;You now run N production environments.&lt;/strong&gt; With 50 cells you have 50 databases to back up, 50 Redis clusters to monitor and 50 queue setups to watch. A schema migration becomes 50 coordinated operations. Infrastructure as code stops being a best practice and becomes a requirement for survival.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not everything fits in a cell.&lt;/strong&gt; Authentication, global feature flags, payment methods and anything shared between tenants must live in the control plane or be replicated to each cell. Keep the control plane as thin as possible, because it is a shared dependency and the more it does, the more its failures matter.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-cell queries are gone.&lt;/strong&gt; A query that used to join across all users now has to fan out to every cell and merge the results, which is slow and complex. The standard answer is a separate analytics pipeline: every cell streams its events to a warehouse, and analytics queries run there instead of against operational databases. That is a good pattern anyway, but cells make it mandatory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You need spare capacity.&lt;/strong&gt; As the previous chart showed, each surviving cell needs about 1/(N-1) of spare capacity to absorb a failed neighbor's traffic when load is spread evenly. That is a modest overhead for large N, but real.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Big tenants do not fit neatly.&lt;/strong&gt; A tenant larger than a typical cell needs a cell of its own, or a larger one.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Challenge&lt;/th&gt;
&lt;th&gt;Mitigation&lt;/th&gt;
&lt;th&gt;Effort&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;N environments to manage&lt;/td&gt;
&lt;td&gt;Strict infrastructure as code and automated cell provisioning&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Global data needs&lt;/td&gt;
&lt;td&gt;A thin control plane with caching at the cell edge&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cross-cell analytics&lt;/td&gt;
&lt;td&gt;A separate asynchronous analytics pipeline&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Moving tenants between cells&lt;/td&gt;
&lt;td&gt;Dual-write migration tooling&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Very large tenants&lt;/td&gt;
&lt;td&gt;Dedicated or larger cells&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Spare capacity for failover&lt;/td&gt;
&lt;td&gt;Spread load evenly, and use more, smaller cells&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Is cell-based architecture right for you?
&lt;/h2&gt;

&lt;p&gt;The pattern is powerful, but it is not for everyone. Adopting it too early is premature optimization. Adopting it too late means living through incidents that cells would have contained.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It fits well when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You run B2B SaaS with clear tenant boundaries&lt;/li&gt;
&lt;li&gt;A single Availability Zone outage is unacceptable&lt;/li&gt;
&lt;li&gt;Your volume is high enough that blast radius is a real concern&lt;/li&gt;
&lt;li&gt;You have data residency or compliance requirements, such as EU-only data&lt;/li&gt;
&lt;li&gt;Your team has strong infrastructure-as-code and platform engineering maturity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;It fits poorly when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You are an early-stage startup still finding product-market fit&lt;/li&gt;
&lt;li&gt;Cross-user queries sit at the core of your product&lt;/li&gt;
&lt;li&gt;You have a small team with no platform engineering capacity&lt;/li&gt;
&lt;li&gt;Your workload is inherently global, such as a CDN or a search index&lt;/li&gt;
&lt;li&gt;No natural partition key exists in your data model&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Readiness checklist
&lt;/h3&gt;

&lt;p&gt;Be honest with yourself before committing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I can name a partition key that keeps more than 90% of related data together&lt;/li&gt;
&lt;li&gt;All of my production infrastructure is covered by infrastructure as code&lt;/li&gt;
&lt;li&gt;I can see per-service and per-dependency health, not only global averages&lt;/li&gt;
&lt;li&gt;My organization will fund a platform investment of several months&lt;/li&gt;
&lt;li&gt;I know which data is global and cannot live in a cell&lt;/li&gt;
&lt;li&gt;I have sized the spare capacity needed to absorb a failed cell&lt;/li&gt;
&lt;li&gt;I have, or can build, tooling to move a tenant between cells without downtime&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As a rule of thumb, if you cannot tick more than a few of these, the architecture will fight you instead of helping you. Start with the gaps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Microservices gave us deployment independence and team autonomy. Cells add something more fundamental: &lt;strong&gt;failure containment&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Traditional reliability engineering asks how to prevent failures. Cell-based architecture asks a different question: given that failures are inevitable, how far can we stop them from spreading? Cells do not reduce the probability of failure. They reduce its consequence, and at scale, reducing consequences is far more tractable than eliminating causes.&lt;/p&gt;

&lt;p&gt;For a smaller company the economics differ, but the pattern scales down gracefully. Even three to five cells for your most critical service can cut your blast radius without a platform-wide overhaul.&lt;/p&gt;

&lt;p&gt;The place to start is always the same: &lt;strong&gt;find your partition key.&lt;/strong&gt; Identify the entity around which everything else pivots, and ask whether slicing along that line could save you from your next all-hands incident at 2 a.m.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/wellarchitected/latest/reducing-scope-of-impact-with-cell-based-architecture/what-is-a-cell-based-architecture.html" rel="noopener noreferrer"&gt;AWS Well-Architected: Reducing the Scope of Impact with Cell-Based Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://slack.engineering/slacks-migration-to-a-cellular-architecture/" rel="noopener noreferrer"&gt;Slack Engineering: Slack's Migration to a Cellular Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://careersatdoordash.com/blog/staying-in-the-zone-how-doordash-used-a-service-mesh-to-manage-data-transfer-reducing-hops-and-cloud-spend/" rel="noopener noreferrer"&gt;DoorDash: Staying in the Zone&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://builder.aws.com/content/3F06NpJ8YeoIGP8VHTw4n81pFn8/workload-isolation-using-shuffle-sharding" rel="noopener noreferrer"&gt;AWS Builders' Library: Workload isolation using shuffle-sharding&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>architecture</category>
      <category>distributedsystems</category>
      <category>systemdesign</category>
      <category>backenddevelopment</category>
    </item>
    <item>
      <title>Caching, Consistency, and Trade-offs: Designing Scalable Distributed Systems</title>
      <dc:creator>Muhammad Ahsan Farooq </dc:creator>
      <pubDate>Sat, 24 Jan 2026 17:00:10 +0000</pubDate>
      <link>https://dev.to/ahsanfarooq210/caching-consistency-and-trade-offs-designing-scalable-distributed-systems-3nlf</link>
      <guid>https://dev.to/ahsanfarooq210/caching-consistency-and-trade-offs-designing-scalable-distributed-systems-3nlf</guid>
      <description>&lt;p&gt;When building distributed systems, performance rarely comes for free. Every optimisation introduces a trade-off, and nowhere is this more visible than in &lt;strong&gt;caching and consistency&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Modern applications — social networks, e-commerce platforms, streaming services — rely heavily on caching to achieve low latency and massive scale. But once data is cached and replicated across systems, a fundamental question arises:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;How consistent does the data need to be?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The uncomfortable truth is that there is no universal answer. The right consistency model depends entirely on what your system is doing and what the cost of being wrong actually is. A stale like count on a social post is annoying. A stale account balance during a fund transfer is catastrophic.&lt;/p&gt;

&lt;p&gt;This post walks through caching strategies, consistency models, and how production systems at scale actually navigate these trade-offs — not in theory, but in practice.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Caching Exists in the First Place
&lt;/h2&gt;

&lt;p&gt;At scale, databases are expensive — both in latency and throughput. A single database can handle tens of thousands of queries per second under ideal conditions. A cached response from Redis or Memcached can handle millions.&lt;/p&gt;

&lt;p&gt;Caching exists to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reduce database load&lt;/li&gt;
&lt;li&gt;Improve response times&lt;/li&gt;
&lt;li&gt;Absorb traffic spikes&lt;/li&gt;
&lt;li&gt;Enable global scalability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A cache stores frequently accessed data closer to the application, often in-memory, making reads orders of magnitude faster than hitting a database.&lt;/p&gt;

&lt;p&gt;But caching also introduces a fundamental challenge: &lt;strong&gt;the cache and the database can temporarily disagree.&lt;/strong&gt; The moment you put data in two places, you have to decide which one is right when they differ — and that question has no clean answer.&lt;/p&gt;

&lt;p&gt;That disagreement is where consistency models come into play.&lt;/p&gt;




&lt;h2&gt;
  
  
  Common Caching Strategies
&lt;/h2&gt;

&lt;p&gt;Caching is not a single technique — it's a family of patterns, each with different trade-offs around freshness, write latency, and failure behavior. Choosing the wrong one for a given workload is one of the most common sources of subtle bugs in distributed systems.&lt;/p&gt;




&lt;h3&gt;
  
  
  1. Cache-Aside (Lazy Loading)
&lt;/h3&gt;

&lt;p&gt;This is the most widely used caching pattern, and for good reason — it's simple, resilient, and maps naturally to how most applications think about data access.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How It Works&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Application checks the cache&lt;/li&gt;
&lt;li&gt;If data exists (cache hit) → return it immediately&lt;/li&gt;
&lt;li&gt;If not (cache miss) → fetch from database, store in cache, return to caller
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Read Flow:

Client → Cache → Hit? → Return data
                ↓ Miss
              Database → Populate cache → Return data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simple to implement and reason about&lt;/li&gt;
&lt;li&gt;Cache failures don't break the system (you fall back to the database)&lt;/li&gt;
&lt;li&gt;Database remains the source of truth at all times&lt;/li&gt;
&lt;li&gt;Only data that is actually requested gets cached — no wasted memory on cold data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cache misses cause latency spikes, especially under a cold start or after a flush&lt;/li&gt;
&lt;li&gt;Cached data can serve stale values between the write and the next TTL expiry&lt;/li&gt;
&lt;li&gt;Writes require careful invalidation logic — miss one code path and stale data lingers indefinitely&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The cold start problem is real.&lt;/strong&gt; When a cache-aside system restarts or is flushed, the first wave of requests all miss and hammer the database simultaneously. This is called a &lt;strong&gt;thundering herd&lt;/strong&gt; and can bring a database to its knees if not handled with request coalescing or staggered cache warming.&lt;/p&gt;

&lt;p&gt;This pattern naturally produces &lt;strong&gt;eventual consistency&lt;/strong&gt; — cached data lags behind the database by up to one TTL window.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Write-Through Cache
&lt;/h3&gt;

&lt;p&gt;Instead of lazily populating the cache on reads, write-through caches keep the cache proactively up-to-date on every write.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How It Works&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every write goes to the cache first&lt;/li&gt;
&lt;li&gt;The cache synchronously writes to the database before acknowledging success&lt;/li&gt;
&lt;li&gt;Reads always find fresh data in the cache
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Write Flow:

Client → Cache → Database (synchronous)
                ↓
          Acknowledge write only after both succeed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cache always contains fresh data — reads are both fast and consistent&lt;/li&gt;
&lt;li&gt;No stale reads under normal operation&lt;/li&gt;
&lt;li&gt;Simpler read logic since cache misses are rare&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Higher write latency — every write pays for two round trips (cache + database)&lt;/li&gt;
&lt;li&gt;Cache becomes a critical dependency — if the cache is unavailable, writes fail&lt;/li&gt;
&lt;li&gt;You pay the cost of caching even for data that is rarely read&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Write-through is particularly well-suited for &lt;strong&gt;read-heavy workloads where write latency is acceptable&lt;/strong&gt; — user profile data, configuration, reference tables. It leans naturally toward &lt;strong&gt;strong consistency for reads&lt;/strong&gt; since the cache and database are kept in sync on every write.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Write-Behind (Write-Back) Cache
&lt;/h3&gt;

&lt;p&gt;Write-behind inverts the durability guarantee. Writes are acknowledged immediately after hitting the cache, and the database is updated asynchronously in the background.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How It Works&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Client writes to the cache; acknowledgement is immediate&lt;/li&gt;
&lt;li&gt;The cache (or a background process) flushes writes to the database asynchronously&lt;/li&gt;
&lt;li&gt;Reads are served from the cache while the flush is pending
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Write Flow:

Client → Cache → Acknowledge immediately
                ↓ (async, background)
              Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Extremely fast writes — no waiting for database round trips&lt;/li&gt;
&lt;li&gt;High write throughput — ideal for bursty workloads&lt;/li&gt;
&lt;li&gt;Can batch multiple writes to the database for efficiency&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data loss risk — if the cache fails before flushing, writes are gone&lt;/li&gt;
&lt;li&gt;Complex recovery logic — what do you do with unflushed writes after a crash?&lt;/li&gt;
&lt;li&gt;The database is temporarily inconsistent with the cache by design&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Write-behind is appropriate when &lt;strong&gt;throughput matters more than durability&lt;/strong&gt; — metrics aggregation, clickstream logging, analytics counters. It is rarely appropriate for anything where losing a write would be unacceptable to the user or the business.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Consistency Question
&lt;/h2&gt;

&lt;p&gt;Once data is cached and replicated across multiple nodes, systems must make an explicit decision:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Should all users see the same data at the same time — or is "eventually correct" good enough?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is not a philosophical question. It's an engineering constraint with direct consequences for latency, availability, and correctness. The answer differs not just between systems, but often between different features within the same system.&lt;/p&gt;




&lt;h2&gt;
  
  
  Strong Consistency
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What It Means
&lt;/h3&gt;

&lt;p&gt;Strong consistency guarantees that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every read returns the most recent write — no exceptions&lt;/li&gt;
&lt;li&gt;All users see the same data at the same time, regardless of which replica serves them&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From the user's perspective, the system behaves like a single, perfectly synchronized machine. There is no observable "lag" between writing data and reading it back, anywhere in the system.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Strong Consistency Is Achieved
&lt;/h3&gt;

&lt;p&gt;Guaranteeing this across distributed nodes is non-trivial. Common mechanisms include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Synchronous replication&lt;/strong&gt; — every replica must acknowledge a write before the write is considered successful&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Distributed consensus protocols&lt;/strong&gt; — algorithms like Raft or Paxos ensure all nodes agree on the order of operations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quorum-based reads and writes&lt;/strong&gt; — in a cluster of N replicas, reads and writes both contact a majority (quorum), ensuring at least one node in the read set always has the most recent write&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The cost is visible: &lt;strong&gt;writes block until all required replicas confirm.&lt;/strong&gt; On a healthy network this adds tens of milliseconds. During a network partition or a slow replica, it can cause writes to fail or stall indefinitely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Predictable, easy-to-reason-about behavior&lt;/li&gt;
&lt;li&gt;No stale reads under any circumstances&lt;/li&gt;
&lt;li&gt;Correct by construction — no conflict resolution needed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Higher write and read latency&lt;/li&gt;
&lt;li&gt;Reduced availability during network issues — some operations fail rather than proceeding with stale data&lt;/li&gt;
&lt;li&gt;Poor global scalability — coordinating across geographically distributed replicas is slow&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When Strong Consistency Is the Right Choice
&lt;/h3&gt;

&lt;p&gt;Strong consistency is essential when &lt;strong&gt;the cost of returning incorrect data is unacceptable&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Banking and financial transactions&lt;/li&gt;
&lt;li&gt;Payment processing and fund transfers&lt;/li&gt;
&lt;li&gt;Inventory reservation (overselling is a real, expensive problem)&lt;/li&gt;
&lt;li&gt;Distributed locks and leader election&lt;/li&gt;
&lt;li&gt;Medical records and regulated data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In these domains, &lt;strong&gt;being slow is always better than being wrong.&lt;/strong&gt; A user waiting 500ms for a fund transfer to confirm is fine. A user being debited twice because two replicas disagreed is not.&lt;/p&gt;




&lt;h2&gt;
  
  
  Eventual Consistency
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What It Means
&lt;/h3&gt;

&lt;p&gt;Eventual consistency guarantees that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If no new writes occur, all replicas will eventually converge to the same value&lt;/li&gt;
&lt;li&gt;Temporary inconsistencies between replicas are explicitly permitted&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The word "eventually" is doing a lot of work here. In practice, well-designed eventually consistent systems converge in milliseconds to seconds — not minutes or hours. But the window exists, and software must be designed to tolerate it.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Eventual Consistency Works
&lt;/h3&gt;

&lt;p&gt;Eventual consistency is typically achieved through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Asynchronous replication&lt;/strong&gt; — writes are acknowledged immediately, replicas catch up in the background&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time-based cache expiration (TTL)&lt;/strong&gt; — cached values expire and are refreshed from the source on demand&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Background synchronization&lt;/strong&gt; — periodic reconciliation jobs that detect and resolve divergence&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Writes return fast. The system reconciles differences later.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Concrete Example
&lt;/h3&gt;

&lt;p&gt;Picture this: you like a photo on Instagram.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Your like is written to the nearest data center — acknowledged in ~50ms&lt;/li&gt;
&lt;li&gt;You immediately see the updated count (your local replica is current)&lt;/li&gt;
&lt;li&gt;A user in Tokyo sees the old count for another 200ms while replication catches up&lt;/li&gt;
&lt;li&gt;The system converges — both users see the same count&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Nothing broke. No data was lost. The system &lt;strong&gt;optimized for speed and availability&lt;/strong&gt;, accepting a brief window of inconsistency as a known and acceptable cost.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Very low write latency — no waiting for remote replicas&lt;/li&gt;
&lt;li&gt;High availability — writes succeed even during partial failures&lt;/li&gt;
&lt;li&gt;Excellent global scalability — no cross-region coordination required&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Stale reads are possible, and software must be written to handle this gracefully&lt;/li&gt;
&lt;li&gt;More complex conflict resolution when two replicas receive concurrent writes&lt;/li&gt;
&lt;li&gt;Harder to reason about system state at any given moment&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When Eventual Consistency Is the Right Choice
&lt;/h3&gt;

&lt;p&gt;Eventual consistency is ideal when availability and latency matter more than momentary precision:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Social media feeds and timelines&lt;/li&gt;
&lt;li&gt;Like counts, view counts, follower counts&lt;/li&gt;
&lt;li&gt;Product recommendations&lt;/li&gt;
&lt;li&gt;Search indexes&lt;/li&gt;
&lt;li&gt;Analytics dashboards&lt;/li&gt;
&lt;li&gt;Content delivery via CDN&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For these use cases, serving a value that is 200ms stale has zero impact on the user experience. Serving a 500ms delayed response does.&lt;/p&gt;




&lt;h2&gt;
  
  
  CAP Theorem: Why This Trade-off Is Inevitable
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;CAP Theorem&lt;/strong&gt;, formulated by computer scientist Eric Brewer, explains why no distributed system can fully escape these trade-offs.&lt;/p&gt;

&lt;p&gt;A distributed system can guarantee only &lt;strong&gt;two of three&lt;/strong&gt; properties simultaneously:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Property&lt;/th&gt;
&lt;th&gt;What it means&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Consistency&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Every read returns the most recent write&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Availability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Every request receives a response (not an error)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Partition Tolerance&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The system continues operating despite network partitions&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The critical insight is that &lt;strong&gt;network partitions are not optional.&lt;/strong&gt; Networks fail. Packets drop. Data centers lose connectivity. A distributed system that can't tolerate partitions isn't really distributed — it's just a single node with extra steps.&lt;/p&gt;

&lt;p&gt;Since partition tolerance is non-negotiable, the real trade-off is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CP systems&lt;/strong&gt; sacrifice availability during a partition — some requests fail rather than return stale data (e.g., ZooKeeper, HBase)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AP systems&lt;/strong&gt; sacrifice consistency during a partition — requests succeed but may return stale data (e.g., Cassandra, DynamoDB in eventual mode, CouchDB)&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Important nuance:&lt;/strong&gt; CAP is often misread as a binary choice. In reality, it describes behavior &lt;em&gt;during a network partition&lt;/em&gt;. Most of the time, partitions aren't happening — and during normal operation, well-designed systems can offer both strong consistency &lt;em&gt;and&lt;/em&gt; high availability. The trade-off only becomes forced under failure conditions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Caching-heavy systems almost always choose &lt;strong&gt;AP&lt;/strong&gt; — they prioritize availability. The cost of failing a request is higher than the cost of temporarily serving stale data.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conflict Resolution: The Hidden Cost of Eventual Consistency
&lt;/h2&gt;

&lt;p&gt;When writes happen concurrently on different replicas — before replication catches up — you get conflicting values. The system has to decide which one wins. This is not a hypothetical edge case; at scale, it happens constantly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Last-Write-Wins (LWW)
&lt;/h3&gt;

&lt;p&gt;The simplest strategy: the write with the most recent timestamp wins. All other concurrent writes are discarded.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simple&lt;/strong&gt; and widely used (Cassandra, Redis)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dangerous&lt;/strong&gt; if clocks are not synchronized — clock skew can cause a newer write to be overwritten by an older one&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data loss&lt;/strong&gt; is possible — a legitimate write can be silently discarded&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;LWW is appropriate when losing occasional writes is acceptable (counters, metrics) and unacceptable when every write must be preserved (financial records, user content).&lt;/p&gt;

&lt;h3&gt;
  
  
  Vector Clocks
&lt;/h3&gt;

&lt;p&gt;Instead of trusting wall-clock time, vector clocks track the &lt;strong&gt;causal history&lt;/strong&gt; of each write — which writes each node was aware of when it made its update.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Accurate conflict detection&lt;/strong&gt; — can identify when two writes are genuinely concurrent vs. when one clearly happened after another&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enables intelligent merging&lt;/strong&gt; — rather than discarding one write, the system can attempt to merge both&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Complex&lt;/strong&gt; to implement and reason about; adds overhead to every read and write&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;DynamoDB uses a variant of this approach. It's the right choice when data loss is unacceptable and writes must be reconciled rather than discarded.&lt;/p&gt;

&lt;h3&gt;
  
  
  Application-Level Merging
&lt;/h3&gt;

&lt;p&gt;For some data structures, domain logic produces a better result than any generic strategy.&lt;/p&gt;

&lt;p&gt;Consider a shopping cart: if two sessions concurrently add different items, the correct merge is to include &lt;em&gt;both&lt;/em&gt; items — not to pick one and discard the other. This requires the application to understand the semantics of its data, not just timestamps.&lt;/p&gt;

&lt;p&gt;Amazon's Dynamo paper describes exactly this approach for shopping carts and it remains a canonical example of why application-level merging is sometimes the only right answer.&lt;/p&gt;




&lt;h2&gt;
  
  
  Choosing the Right Approach
&lt;/h2&gt;

&lt;p&gt;There is no universally "best" consistency model — only &lt;strong&gt;contextual decisions&lt;/strong&gt; driven by what the cost of being wrong actually is.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Requirement&lt;/th&gt;
&lt;th&gt;Best Fit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Financial accuracy and transactions&lt;/td&gt;
&lt;td&gt;Strong Consistency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Global low-latency reads&lt;/td&gt;
&lt;td&gt;Eventual Consistency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;High write throughput&lt;/td&gt;
&lt;td&gt;Eventual Consistency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Regulatory compliance&lt;/td&gt;
&lt;td&gt;Strong Consistency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User-facing metrics and counters&lt;/td&gt;
&lt;td&gt;Eventual Consistency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inventory management&lt;/td&gt;
&lt;td&gt;Strong Consistency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Social feeds and recommendations&lt;/td&gt;
&lt;td&gt;Eventual Consistency&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The most important architectural insight is that &lt;strong&gt;the right answer is almost always hybrid.&lt;/strong&gt; Real production systems don't pick one model — they apply strong consistency surgically on critical paths and lean on eventual consistency for everything else.&lt;/p&gt;




&lt;h2&gt;
  
  
  From Theory to Practice: Caching in Real Production Systems
&lt;/h2&gt;

&lt;p&gt;So far, we've discussed &lt;em&gt;why&lt;/em&gt; consistency trade-offs exist and &lt;em&gt;how&lt;/em&gt; the two models work conceptually. The real challenge begins when these ideas meet production traffic, global users, and failure scenarios.&lt;/p&gt;

&lt;p&gt;In real systems, caching is not an optimization — it is &lt;strong&gt;a foundational architectural decision.&lt;/strong&gt; And with caching comes the unavoidable reality: data will be stale sometimes.&lt;/p&gt;

&lt;p&gt;The key question is not &lt;em&gt;how to avoid inconsistency&lt;/em&gt; — you can't, not at scale. The question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Where can we tolerate it, and how do we control it?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  The First Rule of Production Caching
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Not all data deserves the same consistency guarantees.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Large-scale systems explicitly separate data into two categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Critical paths&lt;/strong&gt; — money, inventory, correctness-sensitive state. Strong consistency. Minimal or no caching.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non-critical paths&lt;/strong&gt; — feeds, counters, recommendations, metadata. Eventual consistency. Aggressive caching.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Failing to make this separation explicit is how systems end up with subtle, hard-to-reproduce bugs where a payment succeeds but the balance doesn't update, or an item shows as in-stock after the last unit was sold.&lt;/p&gt;




&lt;h3&gt;
  
  
  Social Media Platforms: Optimizing for Speed
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Typical stack:&lt;/strong&gt; SQL or NoSQL primary store, Redis or Memcached distributed cache, CDN for static content, async aggregation pipelines for counters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How caching is applied:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Like counts, view counts, follower counts → aggressively cached, refreshed via TTL and async pipelines&lt;/li&gt;
&lt;li&gt;User feeds → precomputed and cached per user, rebuilt on write events&lt;/li&gt;
&lt;li&gt;Writes → fast, non-blocking, acknowledged before replication completes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Consistency model:&lt;/strong&gt; Eventual consistency everywhere.&lt;/p&gt;

&lt;p&gt;If a user briefly sees &lt;strong&gt;1,001 likes instead of 1,002&lt;/strong&gt;, nothing meaningful has gone wrong. The product experience is unaffected. At millions of reads per second, the alternative — synchronous replication before every read — would require orders of magnitude more infrastructure and deliver noticeably worse latency. The trade-off is obvious and correct.&lt;/p&gt;




&lt;h3&gt;
  
  
  E-commerce: Deliberately Hybrid
&lt;/h3&gt;

&lt;p&gt;E-commerce systems are the canonical example of why a single consistency model is the wrong approach.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Product Catalog:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cached aggressively, served via cache + CDN&lt;/li&gt;
&lt;li&gt;TTL-based invalidation (minutes to hours)&lt;/li&gt;
&lt;li&gt;Consistency model: &lt;strong&gt;Eventual&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Why: A 30-second delay in reflecting a price change is acceptable. No money is at risk.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Inventory &amp;amp; Checkout:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Minimal caching, strong consistency, database-level transactions and locks&lt;/li&gt;
&lt;li&gt;Consistency model: &lt;strong&gt;Strong&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Why: Overselling a product that doesn't exist is operationally costly and a terrible user experience. The cost of being wrong is concrete and immediate.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;The same system, running the same business, using two different consistency models for two different features. This is not a compromise — it's the correct design.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Financial &amp;amp; Payment Systems: Correctness Wins, Always
&lt;/h3&gt;

&lt;p&gt;In financial systems, caching is used &lt;em&gt;around&lt;/em&gt; the core, never inside it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Safe to cache:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Exchange rates and reference data (with short TTLs)&lt;/li&gt;
&lt;li&gt;User profile metadata&lt;/li&gt;
&lt;li&gt;Authentication tokens and session data&lt;/li&gt;
&lt;li&gt;Reporting and analytics dashboards&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Never cached:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Account balances&lt;/li&gt;
&lt;li&gt;Ledger entries&lt;/li&gt;
&lt;li&gt;Transaction state&lt;/li&gt;
&lt;li&gt;Authorization results during an active transaction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Consistency model:&lt;/strong&gt; Strong consistency for all money movement; eventual consistency is acceptable only for analytics, historical reporting, and non-transactional reads.&lt;/p&gt;

&lt;p&gt;The rule of thumb in fintech is: if getting this wrong could cause a compliance issue, a customer dispute, or a financial loss — it doesn't go in the cache.&lt;/p&gt;




&lt;h3&gt;
  
  
  Microservices: Caching at Every Layer
&lt;/h3&gt;

&lt;p&gt;In microservice architectures, caching appears at multiple levels simultaneously:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;In-process cache&lt;/strong&gt; — local memory within a single service instance, fastest possible, no network hop&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Regional cache&lt;/strong&gt; — shared Redis or Memcached cluster within a region, shared across service instances&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Global CDN / edge cache&lt;/strong&gt; — geographically distributed, used for public content and API responses&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A common pattern: Service A caches responses from Service B, versioned by a hash of Service B's response payload. When Service B's data changes, it emits an event that Service A's consumers use to invalidate the relevant cache entries. This is fast and keeps caches fresh — but it introduces the hardest problem in distributed systems.&lt;/p&gt;




&lt;h2&gt;
  
  
  Cache Invalidation: Where Systems Actually Break
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;"There are only two hard things in Computer Science: cache invalidation and naming things."&lt;br&gt;
— Phil Karlton&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Most caching failures in production are not caused by cache misses or cold starts. They're caused by &lt;strong&gt;incorrect invalidation logic&lt;/strong&gt; — a code path that writes to the database but forgets to update the cache, or an invalidation event that gets dropped during a deployment, or a race condition between a write and its corresponding cache delete.&lt;/p&gt;

&lt;p&gt;The consequences are insidious because stale cache entries don't produce errors — they produce silently wrong data. Users see outdated information. Bugs are hard to reproduce. By the time the on-call engineer is paged, the bad data has been read by thousands of users and the cache has already self-healed via TTL.&lt;/p&gt;




&lt;h2&gt;
  
  
  Cache Invalidation Strategies That Actually Work
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Time-Based Invalidation (TTL)
&lt;/h3&gt;

&lt;p&gt;Every cache entry carries an expiration time. After the TTL expires, the next read fetches fresh data from the source and repopulates the cache.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt; Simple, predictable, self-healing. Stale data has a bounded lifetime.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt; Data can be stale for up to one full TTL window. TTL values require calibration — too short and you lose the performance benefit; too long and stale data lingers.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In production, TTL is &lt;strong&gt;mandatory&lt;/strong&gt; — even when other invalidation strategies are in place. It is the last line of defense. If explicit invalidation fails for any reason, TTL ensures the cache self-corrects eventually.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  2. Explicit Invalidation on Writes
&lt;/h3&gt;

&lt;p&gt;When a write occurs, explicitly delete or update the corresponding cache entry so the next read fetches fresh data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt; Fresher data. Lower probability of stale reads for popular entries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt; Complex. Every write path must know which cache entries to invalidate. Miss one and the stale entry persists until TTL. Partial failures (write succeeds, invalidation fails) produce inconsistency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rule:&lt;/strong&gt; Never rely on explicit invalidation alone. &lt;strong&gt;Always combine with TTL.&lt;/strong&gt; Explicit invalidation is an optimization that improves freshness; TTL is the safety net that handles all the cases explicit invalidation misses.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Versioned Caching
&lt;/h3&gt;

&lt;p&gt;Instead of deleting cache entries when data changes, include a version number in the cache key. Bumping the version implicitly invalidates all old entries — they become unreachable, not deleted.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Old key: user_profile:v3:user_9821
New key: user_profile:v4:user_9821  ← bumped after a schema change
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt; No mass deletion operations. No race conditions between invalidation and concurrent reads. Easy rollback — just decrement the version. Clean handling of schema or format changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt; Higher memory usage — old versioned entries accumulate until evicted. Requires discipline to bump versions consistently.&lt;/p&gt;

&lt;p&gt;Large-scale systems often prefer &lt;strong&gt;version bumps over explicit invalidation&lt;/strong&gt;, particularly during deployments or data migrations. The old entries simply age out naturally.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. Event-Driven Invalidation
&lt;/h3&gt;

&lt;p&gt;Data changes emit events to a message bus (Kafka, SQS, etc.). Consumers subscribe and invalidate the relevant cache entries in near real-time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Database write → Event published → Cache consumer → Delete/update cache entry
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt; Near real-time freshness across services. Scales naturally as you add more consumers. Decouples invalidation logic from write logic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt; Requires reliable event delivery — if an event is dropped, the cache entry stays stale until TTL. Eventual consistency by design. Significantly more complex to debug when things go wrong.&lt;/p&gt;

&lt;p&gt;This is the backbone of modern event-driven architectures and is commonly used for cross-service cache invalidation in microservice systems. It's powerful, but it introduces exactly the kind of subtle, hard-to-reproduce failure modes that require strong observability to manage.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Production Rulebook
&lt;/h2&gt;

&lt;p&gt;Distilling everything above into principles that actually hold under production conditions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;TTL is non-negotiable.&lt;/strong&gt; It is not optional. It is the safety net under every other strategy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Never rely on a single invalidation strategy.&lt;/strong&gt; Combine TTL with explicit invalidation or event-driven invalidation for defense in depth.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Strong consistency is a surgical tool.&lt;/strong&gt; Reserve it for paths where incorrect data has a real, concrete cost.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Eventual consistency dominates read paths.&lt;/strong&gt; For most data, most of the time, it is the right default.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Design for failure, not perfection.&lt;/strong&gt; Your cache will serve stale data sometimes. Design for that reality explicitly — through TTLs, idempotent reads, and graceful degradation — rather than pretending it won't happen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Separate your critical and non-critical paths explicitly.&lt;/strong&gt; Don't leave this implicit. Document which data can be stale and by how much, and which data must be fresh.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If your cache occasionally serves stale data but your system stays up and your critical paths remain correct, &lt;strong&gt;you're doing it right.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion: Design for Reality, Not Perfection
&lt;/h2&gt;

&lt;p&gt;Caching and consistency are not opposing forces to be resolved. They are &lt;strong&gt;complementary tools&lt;/strong&gt; that, when applied with precision, allow systems to be both fast and correct — just not always both at once, for every piece of data.&lt;/p&gt;

&lt;p&gt;Strong consistency offers correctness. Eventual consistency offers scale. The engineer's job is not to pick one forever, but to draw the line carefully: here we need correctness, here we can afford scale.&lt;/p&gt;

&lt;p&gt;The fastest, most reliable systems in production don't eliminate consistency trade-offs — they &lt;strong&gt;make them explicit, document them, and design around them deliberately.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That intentionality is what separates systems that are fast-and-correct from systems that are just fast until something breaks.&lt;/p&gt;




&lt;h2&gt;
  
  
  Further Reading
&lt;/h2&gt;

&lt;p&gt;If this framing resonated, the following are worth reading in depth:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Amazon's Dynamo paper (2007)&lt;/strong&gt; — the foundational paper on eventual consistency, conflict resolution, and vector clocks in production&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Martin Kleppmann's *Designing Data-Intensive Applications&lt;/strong&gt;* — the most thorough treatment of these topics available in book form&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The CAP Theorem revisited (Brewer, 2012)&lt;/strong&gt; — Brewer's own clarifications on what CAP does and doesn't say&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloudflare's blog on cache invalidation at edge&lt;/strong&gt; — practical war stories from operating one of the world's largest caching layers&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>distributedsystems</category>
      <category>eventualconsistency</category>
      <category>captheorem</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>Idempotency: Making Retries Safe in Distributed Systems</title>
      <dc:creator>Muhammad Ahsan Farooq </dc:creator>
      <pubDate>Sun, 04 Jan 2026 13:38:56 +0000</pubDate>
      <link>https://dev.to/ahsanfarooq210/the-art-of-safe-retries-implementing-idempotency-in-distributed-systems-g2i</link>
      <guid>https://dev.to/ahsanfarooq210/the-art-of-safe-retries-implementing-idempotency-in-distributed-systems-g2i</guid>
      <description>&lt;p&gt;&lt;em&gt;Retries are unavoidable in distributed systems, so any endpoint with side effects must survive being called twice. This post shows how to build that with idempotency keys, Redis and a database constraint.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The double-charge problem
&lt;/h2&gt;

&lt;p&gt;Distributed systems fail. Networks drop packets, services time out, containers restart and clients retry. None of this is exceptional; it is the normal operating environment.&lt;/p&gt;

&lt;p&gt;The danger starts when a retry runs a side effect twice. Picture a client sending "Charge the customer $50." The server charges the card, then crashes before it can respond. The client gets no confirmation, assumes failure and retries. Without protection, the customer is charged twice.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client                    Server                   Payment provider
  |                         |                            |
  |-- POST /charge $50 ----&amp;gt;|                            |
  |                         |-- charge $50 -------------&amp;gt;|
  |                         |&amp;lt;-- success ----------------|
  |                         X  crashes before replying   |
  |   ... timeout ...       |                            |
  |-- POST /charge $50 ----&amp;gt;|   (retry)                  |
  |                         |-- charge $50 -------------&amp;gt;|  &amp;lt;- second charge
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not a corner case. Two facts every backend engineer should internalize:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A timeout is not a failure.&lt;/strong&gt; It only means no response arrived, not that the work didn't happen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A missing response is not an unprocessed request.&lt;/strong&gt; The server may have finished the job perfectly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because of that ambiguity, retries are both necessary and dangerous. Idempotency is what makes them safe.&lt;/p&gt;

&lt;h2&gt;
  
  
  What idempotency means
&lt;/h2&gt;

&lt;p&gt;An operation is &lt;strong&gt;idempotent&lt;/strong&gt; if performing it many times has the same effect as performing it once.&lt;/p&gt;

&lt;p&gt;Safe to retry:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SET balance = 100
DELETE /users/123
PUT /profiles/123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These leave the same final state however often they run. A repeated &lt;code&gt;DELETE&lt;/code&gt; may return 404 instead of 204, but the state is unchanged, and the state is what counts.&lt;/p&gt;

&lt;p&gt;Dangerous to retry:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;balance += 100       // run twice, you get +200
POST /orders         // duplicate orders
sendEmail()          // spams the user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most real-world &lt;code&gt;POST&lt;/code&gt; endpoints are not naturally idempotent, so we have to design them to be. There are two routes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Make the operation naturally idempotent&lt;/strong&gt; when you can: set absolute values instead of incrementing, use upserts, or let the client choose the resource ID and use &lt;code&gt;PUT&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add an idempotency key&lt;/strong&gt; when you can't, which is the case for charging a card, creating an order or sending a message.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Idempotency-Key pattern
&lt;/h2&gt;

&lt;p&gt;The standard fix, used by payment APIs such as Stripe and Adyen, is the &lt;strong&gt;idempotency key&lt;/strong&gt;. The client attaches a unique key to each logical operation, and the server uses it to recognise repeats.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The client's job&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generate a unique identifier (a UUID v4 works) once per user intent.&lt;/li&gt;
&lt;li&gt;Send it in a header such as &lt;code&gt;Idempotency-Key&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Reuse the same key on every retry of that operation, and a new key for a new operation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The server's job&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Atomically claim the key before doing any work.&lt;/li&gt;
&lt;li&gt;If the key was already completed, return the stored response without re-running the side effect.&lt;/li&gt;
&lt;li&gt;If it is new, run the operation, store the result under the key, and return it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here is the full lifecycle, including the lost response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client                      Server                        Redis / DB
  |-- POST + key K --------&amp;gt;|                                |
  |                         |-- claim K (SET NX) -----------&amp;gt;|
  |                         |&amp;lt;-- claimed --------------------|
  |                         |   run side effect              |
  |                         |-- save result under K --------&amp;gt;|
  |&amp;lt;-- 201 + result --------|                                |
  |      (response lost)                                     |
  |-- retry, same key K ---&amp;gt;|                                |
  |                         |-- claim K --------------------&amp;gt;|
  |                         |&amp;lt;-- already done + result ------|
  |&amp;lt;-- 201 + saved result --|   side effect NOT run again    |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server can meet four situations, and each needs a defined answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Key is new:&lt;/strong&gt; claim it, run the operation, store and return the result.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key is complete, same payload:&lt;/strong&gt; replay the stored response. Adding an &lt;code&gt;Idempotent-Replayed: true&lt;/code&gt; header helps debugging.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key is still in progress:&lt;/strong&gt; return &lt;code&gt;409 Conflict&lt;/code&gt;. The client should wait briefly and retry.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key exists but the payload differs:&lt;/strong&gt; return &lt;code&gt;422&lt;/code&gt;. The client has a bug, because one key must map to one operation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With this in place, a retry replays the stored result instead of re-running the side effect, so the outcome is effectively once. The next sections add the layers that keep that true when Redis loses data or a request outlives its lock.&lt;/p&gt;

&lt;h2&gt;
  
  
  Server implementation (Node.js, Express, Redis)
&lt;/h2&gt;

&lt;p&gt;The middleware below handles all four situations from the lifecycle above. It claims the key atomically with &lt;code&gt;SET NX&lt;/code&gt;, so there is no gap between "check" and "set" for a concurrent request to slip through.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createHash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;randomUUID&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node:crypto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NextFunction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;redis&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;redis&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;REDIS_URL&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;RESULT_TTL_SECONDS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// keep finished results for 24 hours&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;LOCK_TTL_SECONDS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;             &lt;span class="c1"&gt;// must exceed your slowest request&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Entry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;processing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;fingerprint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;completed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;fingerprint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Same key + different request means the client has a bug.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fingerprintOf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nf"&gt;createHash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sha256&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;originalUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hex&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// "Try again" answers are not results. Never store them: release the key instead.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isFinal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;202&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;409&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;429&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Only touch the key if we still own it. If our lock expired and a retry&lt;/span&gt;
&lt;span class="c1"&gt;// claimed the key, its token differs and we leave its claim alone.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;OWNED&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`local v = redis.call('GET', KEYS[1])
if not v or cjson.decode(v).token ~= ARGV[1] then return 0 end`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;RELEASE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;OWNED&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
return redis.call('DEL', KEYS[1])`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;COMPLETE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;OWNED&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
return redis.call('SET', KEYS[1], ARGV[2], 'EX', ARGV[3])`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;idempotency&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextFunction&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Idempotency-Key&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A valid Idempotency-Key header is required&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Scope keys per account (req.user comes from your auth middleware)&lt;/span&gt;
  &lt;span class="c1"&gt;// so two customers can never collide on the same key.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cacheKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`idem:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fingerprint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fingerprintOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;randomUUID&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// proves which request owns the claim&lt;/span&gt;

  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// 1. Atomically claim the key. Only one concurrent request can win.&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;claimed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;cacheKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;processing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fingerprint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;satisfies&lt;/span&gt; &lt;span class="nx"&gt;Entry&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;NX&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;EX&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;LOCK_TTL_SECONDS&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// 2. Someone already claimed it: replay, reject or ask the client to wait.&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;claimed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cacheKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;409&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Please retry&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt; &lt;span class="c1"&gt;// expired in between&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Entry&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fingerprint&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;fingerprint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;422&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Idempotency-Key was reused with a different request&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;processing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;409&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Request already in progress&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Idempotent-Replayed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;true&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// 3. We own the key. Capture the response so it can be stored and replayed.&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sendJson&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;save&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;isFinal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;COMPLETE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;cacheKey&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="na"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
              &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;completed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="nx"&gt;fingerprint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;satisfies&lt;/span&gt; &lt;span class="nx"&gt;Entry&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
              &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;RESULT_TTL_SECONDS&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
          &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;// a transient answer is not final: let a retry run again&lt;/span&gt;
          &lt;span class="nx"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;RELEASE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;cacheKey&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="na"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

      &lt;span class="c1"&gt;// Persist before replying, so any result the client sees can be replayed.&lt;/span&gt;
      &lt;span class="nx"&gt;save&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;idempotency store failed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;sendJson&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Redis unavailable: fail closed rather than risk a duplicate charge&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compared with a simple "check the cache, then set it" middleware, this version fixes five weaknesses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No race window.&lt;/strong&gt; &lt;code&gt;SET NX&lt;/code&gt; makes claiming the key one atomic step, so two simultaneous requests cannot both run.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payload fingerprint.&lt;/strong&gt; Reusing a key for a different request is rejected instead of silently returning the wrong response.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transient answers release the key.&lt;/strong&gt; A &lt;code&gt;5xx&lt;/code&gt;, &lt;code&gt;409&lt;/code&gt;, &lt;code&gt;429&lt;/code&gt; or &lt;code&gt;202&lt;/code&gt; is not a result, so it is never stored and the client's retry gets a real second attempt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Only the owner releases or completes the key.&lt;/strong&gt; Each claim stores a random token, and a small Lua script deletes or overwrites the key only if the token still matches. Without it, a request that outlived &lt;code&gt;LOCK_TTL_SECONDS&lt;/code&gt; could wipe out a newer retry's claim.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Store, then reply.&lt;/strong&gt; The result is saved before the response leaves, which closes the gap where a client sees a result that was never recorded.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two practical notes. The middleware hooks &lt;code&gt;res.json&lt;/code&gt;, so every response from an idempotent route, including your error handler's, must go through &lt;code&gt;res.json&lt;/code&gt;. A response sent any other way leaves the key held until the lock expires. And on Express 4, async handlers need a wrapper (Express 5 handles this natively), or a thrown error never reaches your error handler and the request hangs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The charge endpoint, backed by the database
&lt;/h2&gt;

&lt;p&gt;Redis is a fast first line of defence, but it is a cache. Keys expire, and a Redis restart can lose them. For money, the durable guarantee should live in your primary database, where a unique constraint makes a duplicate record impossible:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;payments&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt;              &lt;span class="n"&gt;uuid&lt;/span&gt;        &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;account_id&lt;/span&gt;      &lt;span class="n"&gt;uuid&lt;/span&gt;        &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;idempotency_key&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt;        &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;amount_cents&lt;/span&gt;    &lt;span class="nb"&gt;bigint&lt;/span&gt;      &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;CHECK&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount_cents&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;status&lt;/span&gt;          &lt;span class="nb"&gt;text&lt;/span&gt;        &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;CHECK&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'charging'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'succeeded'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'failed'&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
  &lt;span class="n"&gt;created_at&lt;/span&gt;      &lt;span class="n"&gt;timestamptz&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="n"&gt;updated_at&lt;/span&gt;      &lt;span class="n"&gt;timestamptz&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="k"&gt;UNIQUE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;account_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;idempotency_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The endpoint inserts first and charges second. The insert is the durable claim on the key. If it conflicts, an earlier attempt already handled this key, and the endpoint either returns that outcome or, if the attempt died mid-charge, resumes it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;randomUUID&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node:crypto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;idempotency&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./idempotency&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Express 5, or wrap async handlers on Express 4&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="c1"&gt;// Auth middleware runs first so that req.user is set.&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;LEASE_SECONDS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// longer than your payment provider's timeout&lt;/span&gt;

&lt;span class="c1"&gt;// Charge the provider and record the outcome. Used by first attempts and resumed ones.&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;chargeAndSettle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;paymentId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amountCents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Forward the same key so the provider deduplicates as well.&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;paymentProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;charge&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;amountCents&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;idempotencyKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isDefinitiveDecline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// e.g. card declined: retrying cannot help&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s2"&gt;`UPDATE payments SET status = 'failed', updated_at = now() WHERE id = $1`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;paymentId&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;failed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// outcome unknown: leave the row in 'charging' so a retry can resume it&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`UPDATE payments SET status = 'succeeded', updated_at = now() WHERE id = $1`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;paymentId&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;succeeded&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/charge&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;idempotency&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;amountCents&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// integer cents, never floating-point dollars&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isInteger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amountCents&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;amountCents&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;amountCents must be a positive integer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Idempotency-Key&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;accountId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;send&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;created&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;failed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;402&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;transactionId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;created&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;transactionId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// 1. Insert the payment, or discover that this key already created one.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;inserted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`INSERT INTO payments (id, account_id, idempotency_key, amount_cents, status)
     VALUES ($1, $2, $3, $4, 'charging')
     ON CONFLICT (account_id, idempotency_key) DO NOTHING
     RETURNING id`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;randomUUID&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nx"&gt;accountId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amountCents&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inserted&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rowCount&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;paymentId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;inserted&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;chargeAndSettle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;paymentId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amountCents&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;paymentId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// 2. The key was used before. Redis may have forgotten it, but the database remembers.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;rows&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`SELECT id, status, amount_cents FROM payments
      WHERE account_id = $1 AND idempotency_key = $2`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;accountId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;existing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="c1"&gt;// pg returns bigint as a string, so convert before comparing.&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;existing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;amount_cents&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;amountCents&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;422&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Idempotency-Key was reused with a different amount&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;existing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;charging&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;existing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;existing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// already settled: replay the outcome&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// 3. Still 'charging'. Take over only if the previous attempt's lease has expired.&lt;/span&gt;
  &lt;span class="c1"&gt;//    This single UPDATE is the lock: of several simultaneous retries, exactly one matches.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;claim&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`UPDATE payments
        SET updated_at = now()
      WHERE id = $1
        AND status = 'charging'
        AND updated_at &amp;lt; now() - make_interval(secs =&amp;gt; $2)
      RETURNING id`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;existing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;LEASE_SECONDS&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;claim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rowCount&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Another attempt is working on it right now.&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Retry-After&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;5&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;409&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Payment is still being processed, retry shortly&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;chargeAndSettle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;existing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amountCents&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;existing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Server running on port 3000&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here &lt;code&gt;pool&lt;/code&gt; is your &lt;code&gt;pg&lt;/code&gt; connection pool, &lt;code&gt;paymentProvider&lt;/code&gt; is your provider's SDK, and &lt;code&gt;isDefinitiveDecline&lt;/code&gt; is a small function that recognises your provider's "this can never succeed" errors.&lt;/p&gt;

&lt;p&gt;A few details are worth calling out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A crash after the insert is recoverable.&lt;/strong&gt; The row stays in &lt;code&gt;charging&lt;/code&gt;. Once its lease expires, the next retry takes it over and resumes the charge with the same provider key. Returning the stale row as if it were finished would report success for a payment that never happened.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The &lt;code&gt;UPDATE&lt;/code&gt; is the lock.&lt;/strong&gt; Two retries arriving together both try to take over the row, but Postgres applies the updates one at a time. The first moves &lt;code&gt;updated_at&lt;/code&gt; forward and wins. The second no longer matches the lease condition and gets &lt;code&gt;409&lt;/code&gt;. Nothing holds a transaction open during the slow network call to the provider.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The lease bounds the damage of a second crash.&lt;/strong&gt; If the winner also dies, the row becomes claimable again after &lt;code&gt;LEASE_SECONDS&lt;/code&gt;. Even if two attempts did overlap, the shared provider key means the card is charged once.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The stored amount wins.&lt;/strong&gt; A reused key with a different amount is rejected with &lt;code&gt;422&lt;/code&gt; instead of silently charging a different sum.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unknown outcomes are retried; known ones are final.&lt;/strong&gt; A timeout leaves the row in &lt;code&gt;charging&lt;/code&gt; so a retry can resume it. A definitive decline is recorded as &lt;code&gt;failed&lt;/code&gt; and replayed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reconcile the leftovers.&lt;/strong&gt; If a client never retries, a row can sit in &lt;code&gt;charging&lt;/code&gt; indefinitely. A small background job that checks the provider and settles old rows covers that.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With the middleware, the unique constraint, the lease and the forwarded provider key working together, this endpoint is safe to retry.&lt;/p&gt;

&lt;h2&gt;
  
  
  Client implementation (TypeScript, Axios)
&lt;/h2&gt;

&lt;p&gt;The client plays a crucial role. &lt;strong&gt;The key must be generated once per user intent, not once per request attempt.&lt;/strong&gt; If each retry gets a fresh key, the server sees unrelated requests and the protection is gone.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;axios&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sleep&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// Retry only when the outcome is unknown or the server asked us to wait.&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;isRetryable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isAxiosError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// network failure or timeout&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;409&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;429&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;charge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amountCents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;idempotencyKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;maxAttempts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;attempt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;attempt&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.example.com/api/charge&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;amountCents&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Idempotency-Key&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;idempotencyKey&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="nx"&gt;_000&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;isRetryable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;attempt&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;maxAttempts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="c1"&gt;// Exponential backoff with jitter, so retries don't arrive in waves.&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;delay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;attempt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;delay&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Create the key when the user clicks "Pay", not inside the retry loop.&lt;/span&gt;
&lt;span class="c1"&gt;// crypto.randomUUID() is global in browsers and Node 19+.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;idempotencyKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randomUUID&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;charge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;idempotencyKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few rules make this robust:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;One key per intent.&lt;/strong&gt; Keep it in component state or &lt;code&gt;sessionStorage&lt;/code&gt;, so a page refresh or a double click reuses it instead of starting a second payment. If the user changes the order, that is a new intent, so create a new key.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retry only what is safe to retry.&lt;/strong&gt; Network errors, timeouts, &lt;code&gt;5xx&lt;/code&gt;, &lt;code&gt;409&lt;/code&gt; and &lt;code&gt;429&lt;/code&gt; qualify. A &lt;code&gt;400&lt;/code&gt;, &lt;code&gt;402&lt;/code&gt; or &lt;code&gt;422&lt;/code&gt; will fail the same way again, so surface it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Back off with jitter.&lt;/strong&gt; Fixed-interval retries from many clients can hammer a recovering server all at once.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Disable the button while a request is pending,&lt;/strong&gt; but never treat that as the protection. The key is the protection.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Edge cases that bite in production
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The in-flight race.&lt;/strong&gt; Request A checks Redis and finds nothing, then request B does the same, and both process the payment. This happens with double clicks and with a client that retries while the first attempt is still running. The fix is the atomic &lt;code&gt;SET NX&lt;/code&gt; claim shown earlier. The second request loses the claim and gets &lt;code&gt;409&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Same key, different payload.&lt;/strong&gt; Fingerprint the method, URL and body when the key is first used, and reject mismatches with &lt;code&gt;422&lt;/code&gt;. Otherwise a bug in the client silently returns the response for a different operation. The database layer repeats the check on the amount.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Crash mid-request.&lt;/strong&gt; The &lt;code&gt;processing&lt;/code&gt; marker expires after the lock TTL, so a dead request never blocks its key forever. A row left in &lt;code&gt;charging&lt;/code&gt; is taken over by the next retry once its lease expires, and the provider key protects the side effect itself.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Slow requests.&lt;/strong&gt; The lock TTL must be longer than your slowest request, or a second request can claim the key while the first is still running. The ownership token stops the late request from overwriting the newer claim, and the database lease and provider key stop a duplicate charge. For genuinely long jobs, return &lt;code&gt;202 Accepted&lt;/code&gt; with a status URL instead.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redis loses the key.&lt;/strong&gt; After a restart or failover, a retry arrives with no Redis entry. The unique constraint on &lt;code&gt;(account_id, idempotency_key)&lt;/code&gt; catches it, and the endpoint replays or resumes the existing payment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Failed requests.&lt;/strong&gt; A &lt;code&gt;4xx&lt;/code&gt; is deterministic, so replaying it is correct. Transient answers (&lt;code&gt;5xx&lt;/code&gt;, &lt;code&gt;409&lt;/code&gt;, &lt;code&gt;429&lt;/code&gt;, &lt;code&gt;202&lt;/code&gt;) are never stored; they release the key so the retry can run again.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key scope.&lt;/strong&gt; Namespace keys by account or API client. A global namespace lets one customer's key collide with another's.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retention.&lt;/strong&gt; Keep results long enough to cover realistic retry windows. 24 hours is a common default. Clients must never reuse a key after that.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Side effects outside your database.&lt;/strong&gt; Emails, webhooks and queue messages are not covered by a row constraint. Write them to an outbox table in the same transaction, and have consumers deduplicate on an event ID.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When to use it
&lt;/h2&gt;

&lt;p&gt;You don't need this on every endpoint, but if retries are possible and the operation has side effects, idempotency is not optional. It is mandatory for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Payments:&lt;/strong&gt; never charge twice.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Order creation:&lt;/strong&gt; no duplicate orders or shipments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Webhooks:&lt;/strong&gt; providers retry aggressively, so receivers should deduplicate on the event ID.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mobile clients:&lt;/strong&gt; unstable networks make retries routine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Notifications:&lt;/strong&gt; one email or push per event, not three.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A real-world reference: Stripe
&lt;/h2&gt;

&lt;p&gt;Stripe's API is the best-known example. It assumes network failures are normal and that clients will retry. In API v1, once an endpoint starts executing, Stripe saves the status code and body of the first request for a given key and returns them on every retry, including &lt;code&gt;500&lt;/code&gt; errors. It compares the parameters of a retry with the original and rejects a mismatch, accepts keys up to 255 characters, and may prune keys once they are at least 24 hours old.&lt;/p&gt;

&lt;p&gt;Two of Stripe's choices differ from the middleware above, and both are defensible. Stripe replays server errors, while this middleware releases the key on &lt;code&gt;5xx&lt;/code&gt;. Stripe also doesn't save a result when validation fails or a concurrent request conflicts, because no endpoint ran. What matters is that you pick one behaviour and document it for your API's clients.&lt;/p&gt;

&lt;h2&gt;
  
  
  Production checklist
&lt;/h2&gt;

&lt;p&gt;Before shipping an idempotent endpoint, confirm that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The client generates one key per intent and reuses it on every retry.&lt;/li&gt;
&lt;li&gt;The server claims the key atomically before doing any work.&lt;/li&gt;
&lt;li&gt;A random ownership token ensures a request can only release or complete a claim it still holds.&lt;/li&gt;
&lt;li&gt;Keys are scoped per account and limited in length.&lt;/li&gt;
&lt;li&gt;A different payload under the same key is rejected, in Redis and in the database.&lt;/li&gt;
&lt;li&gt;A unique constraint in the primary database backs the guarantee for money-critical writes.&lt;/li&gt;
&lt;li&gt;Interrupted work can be resumed safely: a lease on in-progress rows and the same key forwarded to the downstream provider.&lt;/li&gt;
&lt;li&gt;Transient responses (&lt;code&gt;5xx&lt;/code&gt;, &lt;code&gt;409&lt;/code&gt;, &lt;code&gt;429&lt;/code&gt;, &lt;code&gt;202&lt;/code&gt;) are never stored, and the behaviour is documented for API consumers.&lt;/li&gt;
&lt;li&gt;Every response from an idempotent route goes through &lt;code&gt;res.json&lt;/code&gt;, including error responses.&lt;/li&gt;
&lt;li&gt;Locks and stored results have TTLs, and the lock TTL exceeds your slowest request.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Idempotency is what turns an unreliable network into a dependable system. It moves correctness out of the network layer, which you can't trust, and into durable storage, which you can. Clients can then retry as aggressively as they need to without fear of duplicate side effects.&lt;/p&gt;

&lt;p&gt;Next time you design a &lt;code&gt;POST&lt;/code&gt; endpoint, ask yourself:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"What happens if this is called twice?"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If the answer is "disaster", it's time to add an idempotency key.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Updated: thanks to Raza Hussain and Saksham Jain for catching two bugs in the first version. A retry now resumes a payment left in progress by a crash instead of returning it as done, and the Redis claim now uses an ownership token with a compare-and-delete script.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>distributedsystems</category>
      <category>systemdesign</category>
      <category>backend</category>
      <category>api</category>
    </item>
    <item>
      <title>Fanout at Scale: Push vs. Pull Strategies in Distributed Systems</title>
      <dc:creator>Muhammad Ahsan Farooq </dc:creator>
      <pubDate>Sun, 21 Dec 2025 12:34:01 +0000</pubDate>
      <link>https://dev.to/ahsanfarooq210/fanout-at-scale-push-vs-pull-strategies-in-distributed-systems-228l</link>
      <guid>https://dev.to/ahsanfarooq210/fanout-at-scale-push-vs-pull-strategies-in-distributed-systems-228l</guid>
      <description>&lt;h2&gt;
  
  
  Fanout Push vs. Pull: Solving the Feed Distribution Problem at Scale
&lt;/h2&gt;

&lt;p&gt;Modern systems don’t fail because they can’t store data — they fail because they can’t &lt;strong&gt;deliver the right data to the right consumers at the right time&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;fanout problem&lt;/strong&gt; is one of the most fundamental challenges in distributed systems, especially visible in social media feeds, notification systems, messaging platforms, and event-driven architectures.&lt;/p&gt;

&lt;p&gt;At its core, fanout answers one question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;When a single event occurs, how do we efficiently deliver it to millions of consumers?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are two dominant strategies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Fanout-on-Write (Push)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fanout-on-Read (Pull)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both are valid. Both are widely used. And both come with serious trade-offs.&lt;/p&gt;

&lt;p&gt;Let’s break it down.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The Actual Fanout Problem
&lt;/h2&gt;

&lt;p&gt;Imagine a social media post:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A user posts &lt;strong&gt;one update&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;That user has &lt;strong&gt;10 followers… or 100 million followers&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Each follower expects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Low latency&lt;/li&gt;
&lt;li&gt;Personalized feeds&lt;/li&gt;
&lt;li&gt;High availability&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;The naive solution — “just send the post to everyone” — collapses under:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write amplification&lt;/li&gt;
&lt;li&gt;Storage explosion&lt;/li&gt;
&lt;li&gt;Hot partitions&lt;/li&gt;
&lt;li&gt;Latency spikes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is &lt;strong&gt;fanout&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;One write → many reads&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The challenge is deciding &lt;strong&gt;when&lt;/strong&gt; and &lt;strong&gt;where&lt;/strong&gt; that fanout happens.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Fanout-on-Write (Push Model)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How It Works
&lt;/h3&gt;

&lt;p&gt;When a user creates content:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The system &lt;strong&gt;immediately distributes (pushes)&lt;/strong&gt; the content to followers&lt;/li&gt;
&lt;li&gt;Each follower gets a &lt;strong&gt;precomputed feed entry&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Reading the feed becomes a &lt;strong&gt;simple lookup&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User posts → System pushes post to N follower feeds
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What Problem It Solves
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Ultra-fast feed reads&lt;/li&gt;
&lt;li&gt;Predictable latency&lt;/li&gt;
&lt;li&gt;Minimal computation during reads&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why It’s Powerful
&lt;/h3&gt;

&lt;p&gt;Reads massively outnumber writes in social systems.&lt;br&gt;
Fanout-on-write &lt;strong&gt;moves complexity to write time&lt;/strong&gt;, making reads cheap.&lt;/p&gt;

&lt;h3&gt;
  
  
  Core Trade-Offs
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Advantage&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Extremely fast reads&lt;/td&gt;
&lt;td&gt;Massive write amplification&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Simple read queries&lt;/td&gt;
&lt;td&gt;Heavy storage usage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Predictable latency&lt;/td&gt;
&lt;td&gt;Hot users can overload the system&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A celebrity with 100M followers can generate:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;100M feed writes for one post&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is not theoretical — it’s an operational nightmare.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Fanout-on-Read (Pull Model)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How It Works
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Content is written &lt;strong&gt;once&lt;/strong&gt;, stored centrally&lt;/li&gt;
&lt;li&gt;When a user opens their feed:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;The system fetches recent posts from accounts they follow&lt;/li&gt;
&lt;li&gt;Merges, ranks, and filters them &lt;strong&gt;at read time&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User opens feed → System pulls content from many sources
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What Problem It Solves
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Eliminates write amplification&lt;/li&gt;
&lt;li&gt;Handles massive fanout safely&lt;/li&gt;
&lt;li&gt;Simplifies writes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Trade-Offs
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Advantage&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Minimal write cost&lt;/td&gt;
&lt;td&gt;Complex, expensive reads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scales well for celebrities&lt;/td&gt;
&lt;td&gt;Higher latency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage-efficient&lt;/td&gt;
&lt;td&gt;Harder to cache&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This model pushes complexity to &lt;strong&gt;query time&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Hybrid Fanout (The Real-World Solution)
&lt;/h2&gt;

&lt;p&gt;Almost no large platform uses &lt;em&gt;pure&lt;/em&gt; push or pull.&lt;/p&gt;

&lt;p&gt;They use &lt;strong&gt;hybrids&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;

&lt;p&gt;Because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not all users are equal&lt;/li&gt;
&lt;li&gt;Not all content deserves precomputation&lt;/li&gt;
&lt;li&gt;Not all reads need the same latency&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  5. How Major Social Media Platforms Solve Fanout
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Twitter (X)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Hybrid Fanout Strategy&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Push&lt;/strong&gt; for normal users&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pull&lt;/strong&gt; for celebrities&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The top ~0.01% of users generate extreme fanout&lt;/li&gt;
&lt;li&gt;Pushing their tweets would melt storage and queues&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Tweets from celebrities are &lt;strong&gt;not pushed&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;They’re fetched dynamically at read time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is called &lt;strong&gt;Selective Fanout&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Facebook
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Primarily Fanout-on-Write&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Posts are pushed into followers’ feeds&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Heavy use of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Precomputation&lt;/li&gt;
&lt;li&gt;Ranking models&lt;/li&gt;
&lt;li&gt;Feed materialization&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Why it works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Facebook prioritizes &lt;strong&gt;low-latency scrolling&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Heavy investment in storage and background processing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They mitigate costs with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Asynchronous workers&lt;/li&gt;
&lt;li&gt;Backpressure controls&lt;/li&gt;
&lt;li&gt;Partial fanout (not all posts go to all feeds)&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Instagram
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Push + Pull Hybrid&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Push for normal users&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pull for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Celebrities&lt;/li&gt;
&lt;li&gt;Suggested content&lt;/li&gt;
&lt;li&gt;Ads&lt;/li&gt;
&lt;li&gt;Reels&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Feed is composed from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Precomputed feed entries&lt;/li&gt;
&lt;li&gt;Dynamically fetched content&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  LinkedIn
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Mostly Fanout-on-Write&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Connections are limited&lt;/li&gt;
&lt;li&gt;Professional graph is smaller and denser&lt;/li&gt;
&lt;li&gt;Easier to precompute feeds&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  TikTok / YouTube Shorts
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Primarily Fanout-on-Read&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Feed is interest-based, not follower-based&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Content is pulled from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Recommendation pools&lt;/li&gt;
&lt;li&gt;ML-ranked candidate sets&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;This model would be impossible with push.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Fanout Beyond Social Media (Critical Non-Obvious Use Cases)
&lt;/h2&gt;

&lt;p&gt;Fanout strategies solve problems &lt;strong&gt;far beyond feeds&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  1. Notifications Systems
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Push Fanout&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Send alerts to millions of devices&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Message queues&lt;/li&gt;
&lt;li&gt;Topic-based pub/sub&lt;/li&gt;
&lt;li&gt;Rate limiting&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mobile push notifications&lt;/li&gt;
&lt;li&gt;Emergency alerts&lt;/li&gt;
&lt;li&gt;Trading alerts&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  2. Event-Driven Architectures
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Pull Fanout&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Consumers pull from Kafka partitions&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Enables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Backpressure&lt;/li&gt;
&lt;li&gt;Replayability&lt;/li&gt;
&lt;li&gt;Fault isolation&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Kafka is &lt;strong&gt;fanout-on-read by design&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. CDN Cache Invalidation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Push&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Purge or update cache globally&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Used for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Security patches&lt;/li&gt;
&lt;li&gt;Breaking content changes&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pull&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lazy fetching of rarely accessed assets&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  4. Observability &amp;amp; Metrics
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Prometheus&lt;/strong&gt;: Pull fanout (scraping)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Datadog&lt;/strong&gt;: Push fanout (agents)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Choice depends on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Control vs latency&lt;/li&gt;
&lt;li&gt;System stability during failures&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  5. Multiplayer Gaming
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Push state updates for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nearby players&lt;/li&gt;
&lt;li&gt;Active sessions&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Pull world state on reconnect&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Hybrid fanout prevents bandwidth explosion.&lt;/p&gt;




&lt;h3&gt;
  
  
  6. Financial Market Data
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Push&lt;/strong&gt; for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Price ticks&lt;/li&gt;
&lt;li&gt;Trade executions&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Pull&lt;/strong&gt; for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Historical data&lt;/li&gt;
&lt;li&gt;Analytics queries&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Latency requirements dictate fanout model.&lt;/p&gt;




&lt;h3&gt;
  
  
  7. Configuration &amp;amp; Feature Flags
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Push updates to services for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kill switches&lt;/li&gt;
&lt;li&gt;Emergency rollbacks&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Pull periodically for consistency&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  7. How to Choose the Right Fanout Strategy
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Use Fanout-on-Write (Push) When:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Read latency must be minimal&lt;/li&gt;
&lt;li&gt;Fanout size is bounded&lt;/li&gt;
&lt;li&gt;Storage is cheap&lt;/li&gt;
&lt;li&gt;Predictable performance is critical&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use Fanout-on-Read (Pull) When:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Fanout size is unbounded&lt;/li&gt;
&lt;li&gt;Writes must be cheap&lt;/li&gt;
&lt;li&gt;Consumers vary wildly in demand&lt;/li&gt;
&lt;li&gt;Backpressure is required&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use Hybrid When:
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;You want to survive real-world traffic 😄&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  8. Final Mental Model
&lt;/h2&gt;

&lt;p&gt;Think of fanout like logistics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Push&lt;/strong&gt; = Home delivery (fast, expensive, predictable)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pull&lt;/strong&gt; = Warehouse pickup (cheap, flexible, slower)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hybrid&lt;/strong&gt; = Amazon Prime 😉&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>systemdesign</category>
      <category>javascript</category>
      <category>distributedsystems</category>
    </item>
    <item>
      <title>Clustering in Node.js: Scaling Your Applications Like Never Before!</title>
      <dc:creator>Muhammad Ahsan Farooq </dc:creator>
      <pubDate>Sun, 29 Jun 2025 07:34:14 +0000</pubDate>
      <link>https://dev.to/ahsanfarooq210/clustering-in-nodejs-scaling-your-applications-like-never-before-9a9</link>
      <guid>https://dev.to/ahsanfarooq210/clustering-in-nodejs-scaling-your-applications-like-never-before-9a9</guid>
      <description>&lt;h1&gt;
  
  
  The Cluster Module: Architecture and Core Concepts - Comprehensive Guide
&lt;/h1&gt;

&lt;p&gt;The Node.js cluster module implements a sophisticated multi-process architecture that enables applications to scale across multiple CPU cores. This section provides an in-depth exploration of the fundamental concepts and mechanisms that power Node.js clustering.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Master-Worker Architecture&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The cluster module operates on a &lt;strong&gt;master-worker process model&lt;/strong&gt;, which forms the foundation of Node.js horizontal scaling. This architecture separates concerns between process management and application logic, creating a robust and scalable system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Master Process Responsibilities:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Process Lifecycle Management&lt;/strong&gt;: The master process acts as a supervisor, creating, monitoring, and restarting worker processes as needed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Load Distribution&lt;/strong&gt;: Manages incoming connections and distributes them among available workers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource Coordination&lt;/strong&gt;: Handles shared resources and coordinates communication between workers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Health Monitoring&lt;/strong&gt;: Continuously monitors worker health and performance metrics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Worker Process Characteristics:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Independent Execution&lt;/strong&gt;: Each worker runs as a completely separate process with its own memory space and event loop&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Application Logic&lt;/strong&gt;: Workers handle the actual business logic, HTTP requests, and application-specific operations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Isolated State&lt;/strong&gt;: Workers cannot directly share memory or variables, ensuring process isolation and stability&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Crash Resilience&lt;/strong&gt;: If one worker crashes, it doesn't affect other workers or the master process
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;javascriptconst&lt;/span&gt; &lt;span class="nx"&gt;cluster&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cluster&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;os&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;os&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isPrimary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Master &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; is running`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Master process responsibilities*&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;numWorkers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cpus&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;workers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Spawn workers with metadata tracking*&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;numWorkers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fork&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nx"&gt;workers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;startTime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="na"&gt;requestCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;lastHealthCheck&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Worker &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; spawned`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Monitor worker health*&lt;/span&gt;
    &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;workers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;workerInfo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Worker &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; - Uptime: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;workerInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startTime&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;ms`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Worker process - handles application logic*&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello from worker&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;uptime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;uptime&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Worker &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; listening on port 3000`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Process Lifecycle Management&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Process lifecycle management encompasses the creation, monitoring, and termination of worker processes throughout the application's runtime. This system ensures continuous availability and automatic recovery from failures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Worker Creation Process:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fork Operation&lt;/strong&gt;: The master uses &lt;code&gt;cluster.fork()&lt;/code&gt; to create new workers, which internally uses the &lt;code&gt;child_process.fork()&lt;/code&gt; method&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Environment Inheritance&lt;/strong&gt;: Workers inherit environment variables and configuration from the master process&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Port Sharing&lt;/strong&gt;: All workers automatically share the same server port without conflicts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Initialization Sequence&lt;/strong&gt;: Each worker goes through startup phases including module loading, event loop initialization, and application bootstrap&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Health Monitoring and Recovery:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Death Detection&lt;/strong&gt;: The master listens for worker exit events and automatically detects crashes or unexpected terminations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic Restart&lt;/strong&gt;: Failed workers are immediately replaced with new instances to maintain the desired worker count&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Graceful Shutdown&lt;/strong&gt;: Workers can be gracefully terminated during deployments or scaling operations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource Cleanup&lt;/strong&gt;: Proper cleanup of file descriptors, network connections, and memory when workers terminate
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;javascriptconst&lt;/span&gt; &lt;span class="nx"&gt;cluster&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cluster&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;os&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;os&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isPrimary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;maxRestarts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;restartWindow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;60000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// 1 minute*&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;workerRestarts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Enhanced worker spawning with restart tracking*&lt;/span&gt;
    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;spawnWorker&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fork&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Track worker lifecycle events*&lt;/span&gt;
        &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;online&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`✅ Worker &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; came online`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;listening&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`🎧 Worker &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; listening on &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;disconnect&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`🔌 Worker &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; disconnected`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`❌ Worker &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; error:`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Initial worker spawning*&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cpus&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;spawnWorker&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Enhanced exit handling with restart limits*&lt;/span&gt;
    &lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;exit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`💀 Worker &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; died (&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;signal&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Track restart attempts*&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;workerRestarts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;workerRestarts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;restarts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;workerRestarts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;restarts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Remove old restart records outside the window*&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;recentRestarts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;restarts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;time&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;restartWindow&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;workerRestarts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;recentRestarts&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Restart worker if under limit*&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;recentRestarts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;maxRestarts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`🔄 Restarting worker &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nf"&gt;spawnWorker&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`🚨 Worker &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; exceeded restart limit, not restarting`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Graceful shutdown handling*&lt;/span&gt;
    &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SIGTERM&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;📴 Master received SIGTERM, shutting down workers...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;workers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;workers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;kill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SIGTERM&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Force exit after 10 seconds*&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Inter-Process Communication (IPC)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Inter-Process Communication enables coordination and data exchange between the master and worker processes, as well as between workers through the master as a relay.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IPC Mechanisms:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Message Passing&lt;/strong&gt;: Processes communicate through JSON message objects sent via the built-in IPC channel&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Event-Driven Communication&lt;/strong&gt;: Both master and workers can emit and listen for custom events&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bidirectional Communication&lt;/strong&gt;: Messages can flow from master to workers and vice versa&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Asynchronous Operations&lt;/strong&gt;: All IPC operations are non-blocking and asynchronous&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Common IPC Use Cases:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Configuration Updates&lt;/strong&gt;: Dynamically updating worker configuration without restarts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shared State Synchronization&lt;/strong&gt;: Coordinating shared data across workers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance Metrics&lt;/strong&gt;: Collecting and aggregating performance data from workers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Graceful Operations&lt;/strong&gt;: Coordinating graceful shutdowns, deployments, and scaling operations
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;javascriptconst&lt;/span&gt; &lt;span class="nx"&gt;cluster&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cluster&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isPrimary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sharedState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;totalRequests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;activeUsers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="na"&gt;systemStatus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;healthy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Spawn workers*&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fork&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Listen for messages from workers*&lt;/span&gt;
        &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;handleWorkerMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleWorkerMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;request-count&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="nx"&gt;sharedState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;totalRequests&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Total requests: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;sharedState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;totalRequests&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user-login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="nx"&gt;sharedState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;activeUsers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Broadcast to all workers*&lt;/span&gt;
                &lt;span class="nf"&gt;broadcastToWorkers&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user-status-update&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;activeUserCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;sharedState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;activeUsers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;
                &lt;span class="p"&gt;});&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;request-shared-state&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;shared-state-response&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="na"&gt;totalRequests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;sharedState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;totalRequests&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="na"&gt;activeUsers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;sharedState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;activeUsers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="na"&gt;systemStatus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;sharedState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;systemStatus&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;});&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;broadcastToWorkers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;workers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;workers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Periodic system updates*&lt;/span&gt;
    &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;broadcastToWorkers&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;system-update&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="na"&gt;systemStatus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;sharedState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;systemStatus&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;30000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Worker process*&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;localRequestCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;systemInfo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Handle messages from master*&lt;/span&gt;
    &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;shared-state-response&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="nx"&gt;systemInfo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Worker &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; received shared state:`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;systemInfo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user-status-update&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Active users: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;activeUserCount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;system-update&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`System status: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;systemStatus&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; at &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Example routes that use IPC*&lt;/span&gt;
    &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;localRequestCount&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Send request count to master every 10 requests*&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;localRequestCount&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;request-count&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello from worker&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;localRequests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;localRequestCount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;systemInfo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;systemInfo&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Notify master of user login*&lt;/span&gt;
        &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user-login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Login successful&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/system-info&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Request latest shared state from master*&lt;/span&gt;
        &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;request-shared-state&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Return current known state (in production, you'd want to handle async properly)*&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;systemInfo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Load Balancing Mechanisms&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Node.js clustering incorporates sophisticated load balancing strategies to ensure optimal distribution of incoming connections across worker processes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Built-in Load Balancing Strategies:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Round-Robin (Default)&lt;/strong&gt;: Connections are distributed sequentially across workers in a circular fashion&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operating System Scheduling&lt;/strong&gt;: On some platforms, the OS kernel handles connection distribution&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom Load Balancing&lt;/strong&gt;: Developers can implement custom strategies based on specific requirements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Connection Distribution Process:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Master Process Listening&lt;/strong&gt;: The master process binds to the specified port and accepts incoming connections&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Worker Selection&lt;/strong&gt;: Based on the load balancing algorithm, the master selects an appropriate worker&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connection Handoff&lt;/strong&gt;: The connection is passed to the selected worker for processing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Load Monitoring&lt;/strong&gt;: The system continuously monitors worker loads to optimize distribution
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;javascriptconst&lt;/span&gt; &lt;span class="nx"&gt;cluster&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cluster&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;net&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;net&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isPrimary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;workers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;currentWorkerIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;workerStats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Create workers with stats tracking*&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fork&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nx"&gt;workers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;workerStats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;connections&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;cpuUsage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;memoryUsage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Track worker performance*&lt;/span&gt;
        &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;stats-update&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;workerStats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Custom load balancer implementation*&lt;/span&gt;
    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;selectWorker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;strategy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;round-robin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;strategy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;round-robin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;workers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;currentWorkerIndex&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
                &lt;span class="nx"&gt;currentWorkerIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentWorkerIndex&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;workers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;least-connections&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;workers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;least&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;leastStats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;workerStats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;least&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currentStats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;workerStats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;currentStats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;connections&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;leastStats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;connections&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;least&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;});&lt;/span&gt;

            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;least-cpu&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;workers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;least&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;leastStats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;workerStats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;least&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currentStats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;workerStats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;currentStats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cpuUsage&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;leastStats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cpuUsage&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;least&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;});&lt;/span&gt;

            &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;workers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Custom server with load balancing*&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;net&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createServer&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;pauseOnConnect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;selectedWorker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;selectWorker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;least-connections&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Pass connection to selected worker*&lt;/span&gt;
        &lt;span class="nx"&gt;selectedWorker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sticky-session:connection&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Update connection count*&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;workerStats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selectedWorker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;connections&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Master server listening on port 3000&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Performance monitoring*&lt;/span&gt;
    &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;=== Worker Performance Stats ===&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;workerStats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Worker &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Worker process*&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;connectionCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;requestCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Handle connections from master*&lt;/span&gt;
    &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sticky-session:connection&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Handle the connection*&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;net&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createServer&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;connectionCount&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

                &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;close&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nx"&gt;connectionCount&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;});&lt;/span&gt;

                &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Simple HTTP response*&lt;/span&gt;
                &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;HTTP/1.1 200 OK&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type: application/json&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                    &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello from worker&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;connections&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;connectionCount&lt;/span&gt;
                &lt;span class="p"&gt;}));&lt;/span&gt;
                &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;

            &lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;connection&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resume&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Regular stats reporting*&lt;/span&gt;
    &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cpuUsage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cpuUsage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;memoryUsage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;memoryUsage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;stats-update&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;connections&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;connectionCount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;requestCount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;cpuUsage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cpuUsage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;cpuUsage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;system&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;memoryUsage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;memoryUsage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;heapUsed&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Worker &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; started`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;javascriptconst&lt;/span&gt; &lt;span class="nx"&gt;cluster&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cluster&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;net&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;net&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isPrimary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;workers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;currentWorkerIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;workerStats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Create workers with stats tracking*&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fork&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nx"&gt;workers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;workerStats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;connections&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;cpuUsage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;memoryUsage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Track worker performance*&lt;/span&gt;
        &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;stats-update&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;workerStats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Custom load balancer implementation*&lt;/span&gt;
    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;selectWorker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;strategy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;round-robin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;strategy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;round-robin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;workers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;currentWorkerIndex&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
                &lt;span class="nx"&gt;currentWorkerIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentWorkerIndex&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;workers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;least-connections&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;workers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;least&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;leastStats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;workerStats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;least&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currentStats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;workerStats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;currentStats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;connections&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;leastStats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;connections&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;least&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;});&lt;/span&gt;

            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;least-cpu&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;workers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;least&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;leastStats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;workerStats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;least&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currentStats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;workerStats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;currentStats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cpuUsage&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;leastStats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cpuUsage&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;least&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;});&lt;/span&gt;

            &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;workers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Custom server with load balancing*&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;net&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createServer&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;pauseOnConnect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;selectedWorker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;selectWorker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;least-connections&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Pass connection to selected worker*&lt;/span&gt;
        &lt;span class="nx"&gt;selectedWorker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sticky-session:connection&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Update connection count*&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;workerStats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selectedWorker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;connections&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Master server listening on port 3000&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Performance monitoring*&lt;/span&gt;
    &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;=== Worker Performance Stats ===&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;workerStats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Worker &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Worker process*&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;connectionCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;requestCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Handle connections from master*&lt;/span&gt;
    &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sticky-session:connection&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Handle the connection*&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;net&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createServer&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;connectionCount&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

                &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;close&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nx"&gt;connectionCount&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;});&lt;/span&gt;

                &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Simple HTTP response*&lt;/span&gt;
                &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;HTTP/1.1 200 OK&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type: application/json&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                    &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello from worker&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;connections&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;connectionCount&lt;/span&gt;
                &lt;span class="p"&gt;}));&lt;/span&gt;
                &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;

            &lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;connection&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resume&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Regular stats reporting*&lt;/span&gt;
    &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cpuUsage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cpuUsage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;memoryUsage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;memoryUsage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;stats-update&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;connections&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;connectionCount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;requestCount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;cpuUsage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cpuUsage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;cpuUsage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;system&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;memoryUsage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;memoryUsage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;heapUsed&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Worker &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; started`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Key Components and APIs of the Cluster Module&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The cluster module provides a comprehensive set of APIs and properties that enable fine-grained control over the clustering behavior and worker management.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Core Properties and Methods:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;cluster.isPrimary&lt;/code&gt; / &lt;code&gt;cluster.isMaster&lt;/code&gt;:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Purpose&lt;/strong&gt;: Boolean property that determines if the current process is the master/primary process&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Usage&lt;/strong&gt;: Used to conditionally execute master-specific or worker-specific code&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Note&lt;/strong&gt;: &lt;code&gt;cluster.isMaster&lt;/code&gt; is deprecated in favor of &lt;code&gt;cluster.isPrimary&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;cluster.isWorker&lt;/code&gt;:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Purpose&lt;/strong&gt;: Boolean property indicating if the current process is a worker&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Usage&lt;/strong&gt;: Alternative to checking &lt;code&gt;!cluster.isPrimary&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;cluster.fork([env])&lt;/code&gt;:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Purpose&lt;/strong&gt;: Spawns a new worker process&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parameters&lt;/strong&gt;: Optional environment variables object to pass to the worker&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Returns&lt;/strong&gt;: Worker object representing the spawned process&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;cluster.workers&lt;/code&gt;:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Purpose&lt;/strong&gt;: Hash table containing all active worker objects, indexed by worker ID&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Usage&lt;/strong&gt;: Iterate over workers for management operations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;cluster.settings&lt;/code&gt;:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Purpose&lt;/strong&gt;: Configuration object containing cluster settings&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Properties&lt;/strong&gt;: Includes exec, args, silent, and other cluster configuration options
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;javascriptconst&lt;/span&gt; &lt;span class="nx"&gt;cluster&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cluster&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;os&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;os&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Comprehensive cluster management example*&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ClusterManager&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;maxWorkers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;maxWorkers&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cpus&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;restartDelay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;restartDelay&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;silent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;silent&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;workers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isShuttingDown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isPrimary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startMaster&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startWorker&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;startMaster&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`🚀 Master &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; starting with configuration:`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`   - Max Workers: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;maxWorkers&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`   - Restart Delay: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;restartDelay&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;ms`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`   - Silent Mode: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;silent&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Configure cluster settings*&lt;/span&gt;
        &lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setupMaster&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;silent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;silent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;stdio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;inherit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;inherit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;inherit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ipc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Spawn initial workers*&lt;/span&gt;
        &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;maxWorkers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;spawnWorker&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Handle worker events*&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setupEventHandlers&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Setup graceful shutdown*&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setupGracefulShutdown&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Worker health monitoring*&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startHealthMonitoring&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;spawnWorker&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isShuttingDown&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fork&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;WORKER_ID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="na"&gt;WORKER_START_TIME&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;workerInfo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;startTime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="na"&gt;restartCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;isHealthy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;lastResponse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;workers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;workerInfo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Worker-specific event handlers*&lt;/span&gt;
        &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;online&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`✅ Worker &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; (ID: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;) online`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;listening&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`🎧 Worker &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; listening on port &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;handleWorkerMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`❌ Worker &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; error:`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nx"&gt;workerInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isHealthy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;disconnect&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`🔌 Worker &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; disconnected`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;setupEventHandlers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;exit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;workerInfo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;workers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;workerInfo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`💀 Worker &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; (ID: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;) died: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;signal&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;workers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

                &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Restart worker after delay if not shutting down*&lt;/span&gt;
                &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isShuttingDown&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;spawnWorker&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;restartDelay&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fork&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`🍴 Worker &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; (ID: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;) forked`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;listening&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`📡 Worker &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; listening on &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;handleWorkerMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;workerId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;workerInfo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;workers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;workerId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;workerInfo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;health-check-response&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="nx"&gt;workerInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lastResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="nx"&gt;workerInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isHealthy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;healthy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;performance-stats&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`📊 Worker &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;workerInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; stats:`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error-report&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`🚨 Error from worker &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;workerInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;startHealthMonitoring&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;workers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;workerInfo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;workerId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Send health check*&lt;/span&gt;
                &lt;span class="nx"&gt;workerInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;health-check&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="p"&gt;});&lt;/span&gt;

                &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Check if worker is responsive*&lt;/span&gt;
                &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;timeSinceLastResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;workerInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lastResponse&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timeSinceLastResponse&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;30000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// 30 seconds*&lt;/span&gt;
                    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`⚠️ Worker &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;workerInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; appears unresponsive`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="nx"&gt;workerInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isHealthy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Every 10 seconds*&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;setupGracefulShutdown&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;gracefulShutdown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`\n🛑 Received &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, initiating graceful shutdown...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isShuttingDown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Disconnect all workers*&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;workers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;workerInfo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;workerInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;disconnect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;

            &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Force shutdown after timeout*&lt;/span&gt;
            &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;⚠️ Force shutdown due to timeout&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;30000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Wait for all workers to exit*&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;checkWorkersInterval&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;workers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nf"&gt;clearInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;checkWorkersInterval&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;✅ All workers stopped, master exiting&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SIGTERM&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;gracefulShutdown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SIGTERM&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SIGINT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;gracefulShutdown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SIGINT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;startWorker&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Worker health check handler*&lt;/span&gt;
        &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;health-check&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;health-check-response&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;healthy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                    &lt;span class="na"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;
                &lt;span class="p"&gt;});&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Performance monitoring*&lt;/span&gt;
        &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;memUsage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;memoryUsage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cpuUsage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cpuUsage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;performance-stats&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;memUsage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cpuUsage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;uptime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;uptime&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;30000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Sample application routes*&lt;/span&gt;
        &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello from clustered worker&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;workerId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;WORKER_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;uptime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;uptime&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`🏃 Worker &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; listening on port 3000`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// Usage*&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;clusterManager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ClusterManager&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;maxWorkers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;restartDelay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;silent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;clusterManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These comprehensive descriptions of the cluster module's architecture and core concepts provide a solid foundation for understanding how Node.js clustering works at a deep level. Each component plays a crucial role in creating scalable, fault-tolerant applications that can effectively utilize multi-core systems.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/48469493/0987034c-1b0b-4d03-bfcd-02bf1f646b35/paste.txt" rel="noopener noreferrer"&gt;https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/48469493/0987034c-1b0b-4d03-bfcd-02bf1f646b35/paste.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
  </channel>
</rss>
