<?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: Fahim Hasnain Fahad</title>
    <description>The latest articles on DEV Community by Fahim Hasnain Fahad (@fahim_hasnain_fahad).</description>
    <link>https://dev.to/fahim_hasnain_fahad</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2612155%2F7796571d-dfb1-4d20-8b49-0deb52a85b23.jpeg</url>
      <title>DEV Community: Fahim Hasnain Fahad</title>
      <link>https://dev.to/fahim_hasnain_fahad</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fahim_hasnain_fahad"/>
    <language>en</language>
    <item>
      <title>CAP Theorem Explained Like You’re Ordering Pizza</title>
      <dc:creator>Fahim Hasnain Fahad</dc:creator>
      <pubDate>Sun, 15 Jun 2025 14:54:05 +0000</pubDate>
      <link>https://dev.to/fahim_hasnain_fahad/cap-theorem-explained-like-youre-ordering-pizza-4p5n</link>
      <guid>https://dev.to/fahim_hasnain_fahad/cap-theorem-explained-like-youre-ordering-pizza-4p5n</guid>
      <description>&lt;h2&gt;
  
  
  What is the CAP Theorem? 🤔
&lt;/h2&gt;

&lt;p&gt;Imagine you're running a popular pizza restaurant chain 🍕 with multiple locations across the city. You want three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Consistency&lt;/strong&gt; - All locations have the same menu and prices&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Availability&lt;/strong&gt; - Every location is always open and serving customers
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Partition Tolerance&lt;/strong&gt; - Locations can still operate even if phone lines or internet go down&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The CAP Theorem tells us something surprising: &lt;strong&gt;you can only guarantee 2 out of these 3 at any given time!&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;This same principle applies to distributed databases and systems.&lt;/p&gt;




&lt;h2&gt;
  
  
  Breaking Down the CAP 📊
&lt;/h2&gt;

&lt;h3&gt;
  
  
  C - Consistency 🔄
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it means:&lt;/strong&gt; All nodes in your system show the same data at the same time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real-life example:&lt;/strong&gt; &lt;br&gt;
Think of your bank account 💳. When you check your balance on your phone, ATM, or online banking, you expect to see the &lt;strong&gt;exact same amount&lt;/strong&gt; everywhere. If you just deposited $100, that update should be visible across all platforms immediately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In tech terms:&lt;/strong&gt; Every read receives the most recent write or an error.&lt;/p&gt;

&lt;h3&gt;
  
  
  A - Availability 🟢
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it means:&lt;/strong&gt; Your system is always up and responding to requests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real-life example:&lt;/strong&gt;&lt;br&gt;
Amazon's website 🛒 during Black Friday. Even with millions of users shopping simultaneously, the site stays responsive. You can browse, add items to cart, and checkout without getting error messages like "Service Unavailable."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In tech terms:&lt;/strong&gt; Every request gets a response (success or failure) without guaranteeing the data is the latest.&lt;/p&gt;

&lt;h3&gt;
  
  
  P - Partition Tolerance 🌐
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it means:&lt;/strong&gt; The system continues working even when network connections fail between parts of the system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real-life example:&lt;/strong&gt;&lt;br&gt;
Imagine a library system 📚 with multiple branches. If the internet connection between branches goes down, each branch should still be able to check out books to customers using their local systems, even if they can't sync with other branches immediately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In tech terms:&lt;/strong&gt; The system continues operating despite network failures that prevent communication between nodes.&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.amazonaws.com%2Fuploads%2Farticles%2Fvze5el6nc0zqszn6c9ut.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.amazonaws.com%2Fuploads%2Farticles%2Fvze5el6nc0zqszn6c9ut.png" alt="CAP Theorem" width="800" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Hard Choice: Pick Two! ⚖️
&lt;/h2&gt;

&lt;p&gt;Here's where it gets interesting. According to CAP theorem, when network partitions happen (and they will!), you must choose between Consistency and Availability.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario 1: Choosing Consistency + Partition Tolerance (CP) 🔒
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; Banking systems during network issues&lt;br&gt;
When your bank's network has problems, they'll often make ATMs unavailable rather than risk showing incorrect account balances. Better to be temporarily unavailable than to accidentally let someone overdraw their account!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real tech example:&lt;/strong&gt; Traditional SQL databases like PostgreSQL&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario 2: Choosing Availability + Partition Tolerance (AP) 📱
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; Social media feeds during network issues&lt;br&gt;&lt;br&gt;
Facebook or Twitter will keep showing you posts even if some servers are disconnected. You might see slightly outdated content, but the app keeps working. They'll sync up the latest posts once the network is stable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real tech example:&lt;/strong&gt; NoSQL databases like MongoDB, Cassandra&lt;/p&gt;

&lt;h3&gt;
  
  
  What about CA (Consistency + Availability)? 🤷‍♂️
&lt;/h3&gt;

&lt;p&gt;This combination assumes no network partitions occur. In the real world of distributed systems, network issues are inevitable, so this isn't practical for multi-node systems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; Single-server databases can be CA, but they're not truly distributed.&lt;/p&gt;




&lt;h2&gt;
  
  
  Real-World CAP Decisions 🌍
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Netflix 🎬 - Chooses AP
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Why:&lt;/strong&gt; Users expect to watch movies anytime&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trade-off:&lt;/strong&gt; Your "Continue Watching" list might be slightly out of sync across devices&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Result:&lt;/strong&gt; You can always stream, even if some data is temporarily inconsistent&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Banking Apps 💰 - Choose CP
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Why:&lt;/strong&gt; Money accuracy is non-negotiable&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trade-off:&lt;/strong&gt; ATM might be temporarily unavailable during network issues&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Result:&lt;/strong&gt; When available, your balance is always accurate&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  WhatsApp 💬 - Chooses AP
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Why:&lt;/strong&gt; People expect messaging to always work&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trade-off:&lt;/strong&gt; Messages might arrive out of order during network issues&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Result:&lt;/strong&gt; You can always send messages, they'll sync up eventually&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Restaurant Chain Example 🍕
&lt;/h2&gt;

&lt;p&gt;Let's revisit our pizza chain to see CAP in action:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Normal Day (No Network Issues):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All locations sync prices and inventory ✅&lt;/li&gt;
&lt;li&gt;All locations serve customers ✅
&lt;/li&gt;
&lt;li&gt;Network is working fine ✅&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Network Goes Down Between Locations:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 1 - Choose Consistency:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Close all locations until network is fixed 🚫&lt;/li&gt;
&lt;li&gt;Ensures all locations have same prices when open&lt;/li&gt;
&lt;li&gt;Customers can't get pizza 😢&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Option 2 - Choose Availability:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep all locations open 🟢&lt;/li&gt;
&lt;li&gt;Let each location operate independently
&lt;/li&gt;
&lt;li&gt;Risk: One location might run out of ingredients or have different prices&lt;/li&gt;
&lt;li&gt;Customers can still get pizza 😊&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Practical Takeaways 👨‍💻
&lt;/h2&gt;

&lt;h3&gt;
  
  
  When to Choose CP:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Financial systems 💳&lt;/li&gt;
&lt;li&gt;Inventory management 📦&lt;/li&gt;
&lt;li&gt;Any system where incorrect data is worse than temporary downtime&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When to Choose AP:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Social media platforms 📱&lt;/li&gt;
&lt;li&gt;Content delivery networks 🌐&lt;/li&gt;
&lt;li&gt;Any system where user experience is prioritized over perfect data consistency&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Key Questions to Ask:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Can your business tolerate temporary inconsistency?&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Is downtime worse than showing slightly outdated data?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;How critical is real-time accuracy for your users?&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Common Misconceptions ❌
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Myth:&lt;/strong&gt; "CAP means you can only have 2 out of 3, ever!"&lt;br&gt;
&lt;strong&gt;Reality:&lt;/strong&gt; You can have all 3 during normal operations, but must choose 2 during network partitions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Myth:&lt;/strong&gt; "NoSQL is always AP, SQL is always CP"&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Reality:&lt;/strong&gt; It depends on configuration. MongoDB can be configured for stronger consistency, PostgreSQL can be set up for higher availability.&lt;/p&gt;

</description>
      <category>captheorem</category>
      <category>programming</category>
      <category>systemdesign</category>
      <category>database</category>
    </item>
    <item>
      <title>5 Hard Truths I Learned From The Boss I Hated Most</title>
      <dc:creator>Fahim Hasnain Fahad</dc:creator>
      <pubDate>Wed, 11 Jun 2025 21:09:16 +0000</pubDate>
      <link>https://dev.to/fahim_hasnain_fahad/5-hard-truths-i-learned-from-the-boss-i-hated-most-1mf</link>
      <guid>https://dev.to/fahim_hasnain_fahad/5-hard-truths-i-learned-from-the-boss-i-hated-most-1mf</guid>
      <description>&lt;p&gt;For over six years in the software industry — two onsite and four remote — I've written thousands of lines of code, deployed scalable systems, and architected features across stacks. But the biggest &lt;em&gt;merge conflicts&lt;/em&gt; weren’t in Git — they were with a boss who was sharp, relentless, and, honestly, hard to deal with.&lt;/p&gt;

&lt;p&gt;He wasn’t toxic. Just… tough. And here’s the surprising part: I’m grateful.&lt;/p&gt;

&lt;p&gt;Below are five life-changing lessons I learned from working under pressure, and how they transformed me technically and personally.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 1. “Don’t Bring Me Problems — Bring Me Options”
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt; I’d report issues like, “Hey, the deployment failed.”&lt;br&gt;
&lt;strong&gt;After:&lt;/strong&gt; I’d say, “The deployment failed due to X. We have three paths: rollback, hotfix, or isolate the failing module. I recommend rollback.”&lt;/p&gt;

&lt;h3&gt;
  
  
  💡 Why it matters:
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Without Solutions&lt;/th&gt;
&lt;th&gt;With Solutions&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Reactive&lt;/td&gt;
&lt;td&gt;Proactive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wastes time&lt;/td&gt;
&lt;td&gt;Saves time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Looks unprepared&lt;/td&gt;
&lt;td&gt;Shows leadership&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Engineering takeaway:&lt;/strong&gt;&lt;br&gt;
Learn to &lt;strong&gt;pre-diagnose&lt;/strong&gt;, research workarounds, and &lt;strong&gt;own&lt;/strong&gt; problems. It’s a muscle every senior dev needs to build.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ 2. “Build Like You Won’t Be Here Tomorrow”
&lt;/h2&gt;

&lt;p&gt;He once said this after I hardcoded a value and walked away.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔐 Key habits I developed:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Writing self-documenting, clean code 🧼&lt;/li&gt;
&lt;li&gt;Creating bulletproof onboarding docs 📄&lt;/li&gt;
&lt;li&gt;Avoiding tribal knowledge 🤐&lt;/li&gt;
&lt;li&gt;Making PRs that tell a story 🧵&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why it’s life-changing:&lt;/strong&gt;&lt;br&gt;
When you code as if someone else will maintain it — they’ll love you. Sometimes, that person is &lt;em&gt;future you&lt;/em&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚨 3. “Deadlines Aren’t Suggestions”
&lt;/h2&gt;

&lt;p&gt;At first, I thought he was overreacting when I missed a backend delivery by a day. His words stuck with me:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“If the backend is late, frontend stops. QA stops. The client waits. You don’t miss a sprint. You miss a chain.”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  📅 I learned to:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Break tasks into atomic commits 📦&lt;/li&gt;
&lt;li&gt;Time-box debugging ⏱️&lt;/li&gt;
&lt;li&gt;Communicate blockers early 🗣️&lt;/li&gt;
&lt;li&gt;Add 20% buffer to every estimate 📊&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Result?&lt;/strong&gt; Fewer late nights. More trust. Greater responsibility.&lt;/p&gt;




&lt;h2&gt;
  
  
  🌱 4. “Comfort Kills Growth”
&lt;/h2&gt;

&lt;p&gt;I once asked, “Why do you always assign me the toughest tickets?”&lt;br&gt;
He replied, &lt;em&gt;“Because you’re smart enough to figure them out.”&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🤯 That flipped my mindset:
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;th&gt;After&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Avoided unknowns&lt;/td&gt;
&lt;td&gt;Embraced the hard stuff 💪&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Focused on speed&lt;/td&gt;
&lt;td&gt;Focused on &lt;strong&gt;learning&lt;/strong&gt; 🧠&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Did just enough&lt;/td&gt;
&lt;td&gt;Delivered with intention 🎯&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Technically:&lt;/strong&gt; I grew from debugging UI to owning CI/CD pipelines, DevOps workflows, and designing RESTful APIs.&lt;/p&gt;




&lt;h2&gt;
  
  
  ❤️ 5. “Respect Is Earned in Reviews, Not Meetings”
&lt;/h2&gt;

&lt;p&gt;He was brutal in code reviews. But he always had a point. He wanted quality, not comfort.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔍 What I learned:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Every review is an opportunity to &lt;strong&gt;level up&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Defensive coding ≠ clean coding&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Feedback is a mirror&lt;/strong&gt;, not an attack&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, I seek out review-heavy teams — it’s where I grow the fastest.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏁 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;That boss wasn’t easy. But the lessons he hammered into me — responsibility, resilience, and ownership — made me more than a better engineer.&lt;/p&gt;

&lt;p&gt;He made me &lt;em&gt;indispensable&lt;/em&gt;.&lt;/p&gt;

</description>
      <category>ownership</category>
      <category>softwaredevelopment</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>10 Battle-Tested Node.js Microservice Patterns for 99.9% Uptime</title>
      <dc:creator>Fahim Hasnain Fahad</dc:creator>
      <pubDate>Fri, 06 Jun 2025 03:56:30 +0000</pubDate>
      <link>https://dev.to/fahim_hasnain_fahad/10-nodejs-microservice-patterns-for-999-uptime-a-guide-5ak5</link>
      <guid>https://dev.to/fahim_hasnain_fahad/10-nodejs-microservice-patterns-for-999-uptime-a-guide-5ak5</guid>
      <description>&lt;p&gt;Today, I'm sharing the &lt;strong&gt;10 battle-tested patterns&lt;/strong&gt; that took us from constant firefighting to 99.9% uptime.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pattern 1: The Circuit Breaker 🔌
&lt;/h2&gt;

&lt;p&gt;Remember playing musical chairs as a kid? The Circuit Breaker pattern works similarly! When a service starts failing, we stop sending it requests temporarily.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Simple circuit breaker with opossum&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;circuitBreaker&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;CircuitBreaker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callAPI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;failureThreshold&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prevents cascading failures across your entire system. When one service gets overwhelmed, it doesn't bring down everything else with it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pattern 2: Health Checks &amp;amp; Auto-healing 🩺
&lt;/h2&gt;

&lt;p&gt;Just like regular health check-ups prevent serious illness, implementing service health checks keeps your system robust.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&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;/health&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="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;isHealthy&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="mi"&gt;500&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Pattern 3: API Gateway Pattern 🚪
&lt;/h2&gt;

&lt;p&gt;Think of this as your system's receptionist. It directs traffic and keeps the chaos out of your internal services.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pattern 4: Service Discovery ️🔍
&lt;/h2&gt;

&lt;p&gt;Imagine trying to call a friend whose phone number keeps changing! That's what services feel like without service discovery.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pro Tip ⭐:&lt;/strong&gt; Use etcd or Consul with Node.js for lightweight service discovery instead of heavyweight solutions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pattern 5: Event-Driven Architecture 📬
&lt;/h2&gt;

&lt;p&gt;Services communicate through events, like colleagues using a message board instead of interrupting each other constantly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Publish event with Kafka&lt;/span&gt;
&lt;span class="nx"&gt;producer&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;topic&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-created&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;value&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="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Common Microservice Patterns Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pattern&lt;/th&gt;
&lt;th&gt;Complexity&lt;/th&gt;
&lt;th&gt;Best Used For&lt;/th&gt;
&lt;th&gt;Impact on Uptime&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Circuit Breaker&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Preventing cascading failures&lt;/td&gt;
&lt;td&gt;⬆️⬆️⬆️&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Health Checks&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Early detection of issues&lt;/td&gt;
&lt;td&gt;⬆️⬆️&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API Gateway&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Traffic management&lt;/td&gt;
&lt;td&gt;⬆️⬆️&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Service Discovery&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Dynamic environments&lt;/td&gt;
&lt;td&gt;⬆️⬆️&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Event-Driven&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Loose coupling&lt;/td&gt;
&lt;td&gt;⬆️⬆️⬆️&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Pattern 6: Bulkhead Pattern 🚢
&lt;/h2&gt;

&lt;p&gt;Named after ship compartments, this pattern isolates components so one failure doesn't sink the whole ship.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pattern 7: Retry with Exponential Backoff ⏱️
&lt;/h2&gt;

&lt;p&gt;Like a polite person who knocks louder each time if no one answers, this pattern increases wait time between retries.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pattern 8: Asynchronous Communication 📨
&lt;/h2&gt;

&lt;p&gt;Not everything needs an immediate response. Some tasks can happen in the background, just like you might send an email instead of calling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pattern 9: Database-per-Service 💾
&lt;/h2&gt;

&lt;p&gt;Each service gets its own database - no more fighting over the same resources!&lt;/p&gt;

&lt;h2&gt;
  
  
  Pattern 10: Monitoring &amp;amp; Observability 📊
&lt;/h2&gt;

&lt;p&gt;You can't fix what you can't see. Proper monitoring is like having security cameras throughout your building.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technology Stack Recommendations
&lt;/h2&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;Technology&lt;/th&gt;
&lt;th&gt;Why It Works&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;API Gateway&lt;/td&gt;
&lt;td&gt;Express Gateway&lt;/td&gt;
&lt;td&gt;Lightweight, Node.js native&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Service Mesh&lt;/td&gt;
&lt;td&gt;Istio/Linkerd&lt;/td&gt;
&lt;td&gt;Advanced traffic management&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Messaging&lt;/td&gt;
&lt;td&gt;Kafka/RabbitMQ&lt;/td&gt;
&lt;td&gt;Reliable async communication&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Databases&lt;/td&gt;
&lt;td&gt;MongoDB/PostgreSQL&lt;/td&gt;
&lt;td&gt;Flexible schemas or ACID compliance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Containerization&lt;/td&gt;
&lt;td&gt;Docker + Kubernetes&lt;/td&gt;
&lt;td&gt;Consistent environments, auto-scaling&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Key Takeaways 🔑
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🚀 Start with &lt;strong&gt;health checks&lt;/strong&gt; and &lt;strong&gt;circuit breakers&lt;/strong&gt; for quick wins&lt;/li&gt;
&lt;li&gt;🧩 &lt;strong&gt;Event-driven architecture&lt;/strong&gt; enables loose coupling between services&lt;/li&gt;
&lt;li&gt;📈 &lt;strong&gt;Monitoring&lt;/strong&gt; is not optional - it's essential for high uptime&lt;/li&gt;
&lt;li&gt;🔄 Implement &lt;strong&gt;graceful degradation&lt;/strong&gt; so failures in one area don't affect others&lt;/li&gt;
&lt;li&gt;💡 Microservices aren't just about splitting code - they're about resilience patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remember: perfect uptime is a journey, not a destination. Start small, measure everything, and keep improving! 💪&lt;/p&gt;

</description>
      <category>node</category>
      <category>microservices</category>
      <category>eventdriven</category>
    </item>
    <item>
      <title>Scaling to 10M Users with Event-Driven Architecture</title>
      <dc:creator>Fahim Hasnain Fahad</dc:creator>
      <pubDate>Wed, 04 Jun 2025 15:32:12 +0000</pubDate>
      <link>https://dev.to/fahim_hasnain_fahad/building-nodejs-apps-that-scale-to-10m-users-with-event-driven-architecture-gd2</link>
      <guid>https://dev.to/fahim_hasnain_fahad/building-nodejs-apps-that-scale-to-10m-users-with-event-driven-architecture-gd2</guid>
      <description>&lt;h2&gt;
  
  
  🌟 The Day Our Server Crashed 🌟
&lt;/h2&gt;

&lt;p&gt;Remember that feeling when your application suddenly crashes? That's exactly what happened to me last month. 😱&lt;/p&gt;

&lt;p&gt;I was sipping my morning coffee ☕ when my phone exploded with notifications. Our startup's Node.js app had completely crashed after a marketing campaign brought in 50,000 new users overnight. What should have been a celebration turned into a nightmare.&lt;/p&gt;

&lt;p&gt;"But I built this with Express! It should handle the load!" I remember telling my senior developer, Maria.&lt;/p&gt;

&lt;p&gt;She smiled knowingly. "Time to learn about event-driven architecture, my friend."&lt;/p&gt;

&lt;h2&gt;
  
  
  🔍 Understanding the Problem
&lt;/h2&gt;

&lt;p&gt;Our monolithic Express app was processing everything synchronously - user signups, email notifications, analytics tracking, and data processing were all happening in a single request-response cycle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&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;/signup&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="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="c1"&gt;// This does EVERYTHING in one request! 😵&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;createUser&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="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;sendWelcomeEmail&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="nx"&gt;email&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;trackSignupAnalytics&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="nx"&gt;res&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;success&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🧩 Enter Event-Driven Architecture
&lt;/h2&gt;

&lt;p&gt;Maria explained that event-driven architecture is like a relay race 🏃‍♀️ where each runner (service) does their part and passes the baton (event) to the next runner, rather than having one person run the entire race.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔥 The Core Concept
&lt;/h3&gt;

&lt;p&gt;Instead of doing everything at once, we:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Publish events&lt;/strong&gt; when something happens&lt;/li&gt;
&lt;li&gt;Let other parts of the system &lt;strong&gt;subscribe&lt;/strong&gt; to events they care about&lt;/li&gt;
&lt;li&gt;Process those events &lt;strong&gt;asynchronously&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  ⚡ Transforming Our App
&lt;/h2&gt;

&lt;p&gt;We refactored our code to use events:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Now we just publish an event! 🎉&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;/signup&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="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="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;createUser&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="nx"&gt;eventEmitter&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;user.created&lt;/span&gt;&lt;span class="dl"&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;body&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;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;success&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🎯 The Architecture Evolution
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Before&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;After&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Synchronous processing&lt;/td&gt;
&lt;td&gt;Asynchronous event handling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Single point of failure&lt;/td&gt;
&lt;td&gt;Distributed resilience&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tight coupling&lt;/td&gt;
&lt;td&gt;Loose coupling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Linear scaling&lt;/td&gt;
&lt;td&gt;Horizontal scaling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5-second response times&lt;/td&gt;
&lt;td&gt;200ms response times&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  📊 Results After 30 Days
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Metric&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Before&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;After&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Improvement&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Max concurrent users&lt;/td&gt;
&lt;td&gt;5,000&lt;/td&gt;
&lt;td&gt;250,000&lt;/td&gt;
&lt;td&gt;50x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Average response time&lt;/td&gt;
&lt;td&gt;2,500ms&lt;/td&gt;
&lt;td&gt;120ms&lt;/td&gt;
&lt;td&gt;20x faster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Server costs&lt;/td&gt;
&lt;td&gt;$1,200/mo&lt;/td&gt;
&lt;td&gt;$750/mo&lt;/td&gt;
&lt;td&gt;37% cheaper&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Uptime&lt;/td&gt;
&lt;td&gt;97.2%&lt;/td&gt;
&lt;td&gt;99.99%&lt;/td&gt;
&lt;td&gt;2.79% increase&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  🛠️ Implementation Steps
&lt;/h2&gt;

&lt;p&gt;Our journey to scaling involved these key steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Identify bottlenecks&lt;/strong&gt; in our monolithic app&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decouple components&lt;/strong&gt; using an event bus&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deploy microservices&lt;/strong&gt; for heavy processing tasks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implement circuit breakers&lt;/strong&gt; for resilience&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  🔧 Technology Stack We Used
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Node.js&lt;/strong&gt; + &lt;strong&gt;Express&lt;/strong&gt; for API services&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kafka&lt;/strong&gt; for event streaming at scale&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redis&lt;/strong&gt; for pub/sub in smaller services&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MongoDB&lt;/strong&gt; for document storage&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PostgreSQL&lt;/strong&gt; for relational data&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  💡 Pro Tip: Start Simple!
&lt;/h2&gt;

&lt;p&gt;You don't need Kafka right away! Begin with Node.js's built-in EventEmitter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;EventEmitter&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;events&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;eventBus&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;EventEmitter&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives you the event-driven pattern without the infrastructure complexity. Later, you can swap in more robust solutions without changing your core logic!&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Scaling to 10M Users
&lt;/h2&gt;

&lt;p&gt;The most beautiful part? The same architecture that handled 250,000 users scaled effortlessly to 10M when our app went viral six months later.&lt;/p&gt;

&lt;p&gt;Event-driven architecture gave us three superpowers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Elasticity&lt;/strong&gt;: Services scale independently based on event volume&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resilience&lt;/strong&gt;: System degraded gracefully under load, never crashed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintainability&lt;/strong&gt;: New team members could contribute to isolated services&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🌈 Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Start with events early&lt;/strong&gt; - retrofitting is much harder!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simple events first&lt;/strong&gt; - use Node's built-in EventEmitter before complex message brokers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Think in asynchronous flows&lt;/strong&gt; - design for eventual consistency&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decouple ruthlessly&lt;/strong&gt; - services should know as little as possible about each other&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitor everything&lt;/strong&gt; - events give amazing visibility into system performance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remember, scaling isn't just about handling more users—it's about building systems that can evolve with your business needs. By embracing event-driven architecture early, we set ourselves up for sustainable growth. 🚀&lt;/p&gt;

&lt;p&gt;What scaling challenges are you facing with your Node.js apps? I'd love to hear about them in the comments! 👇&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>10m</category>
    </item>
    <item>
      <title>Securing Node.js: 10 Auth Practices for 99.9% Protection</title>
      <dc:creator>Fahim Hasnain Fahad</dc:creator>
      <pubDate>Tue, 27 May 2025 15:04:48 +0000</pubDate>
      <link>https://dev.to/fahim_hasnain_fahad/securing-nodejs-10-auth-practices-for-999-protection-4aek</link>
      <guid>https://dev.to/fahim_hasnain_fahad/securing-nodejs-10-auth-practices-for-999-protection-4aek</guid>
      <description>&lt;h2&gt;
  
  
  The Night Everything Broke 🌙
&lt;/h2&gt;

&lt;p&gt;Remember that Tuesday night when I deployed our startup's new user dashboard? I was so proud! 🚀 Three months of work, finally live. I treated myself to pizza and fell asleep watching Netflix.&lt;/p&gt;

&lt;p&gt;At 3:27 AM, my phone exploded with notifications. 📱 Our database was being drained, user accounts compromised, and someone had changed our homepage to a dancing banana GIF. 🍌&lt;/p&gt;

&lt;p&gt;"But I implemented authentication!" I protested to our CTO, on our emergency Zoom call.&lt;/p&gt;

&lt;p&gt;"You implemented &lt;em&gt;something&lt;/em&gt;," she sighed. "Let's fix this properly."&lt;/p&gt;

&lt;h2&gt;
  
  
  The Authentication Journey Begins 🧭
&lt;/h2&gt;

&lt;p&gt;The next morning, our CTO sketched out a security roadmap. I realized my "authentication" was like using a paper lock on a bank vault. 😱&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Authentication isn't a feature, it's the foundation everything else stands on." - My wiser, post-incident self&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The 10 Practices That Saved My Career ⚔️
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Hash Those Passwords! 🧂
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;NEVER&lt;/strong&gt; store plain-text passwords. Ever! I had stored them with basic encryption (rookie mistake).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// DON'T do this&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;password&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;password&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// DO this instead&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;password&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;bcrypt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hash&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="nx"&gt;password&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. JWT: Your Digital ID Badge 🪪
&lt;/h3&gt;

&lt;p&gt;JSON Web Tokens became my new best friends. They're like digital ID badges that expire!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pro Tip:&lt;/strong&gt; 💡 Store JWTs in HttpOnly cookies, not localStorage, to protect against XSS attacks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cookie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;token&lt;/span&gt;&lt;span class="dl"&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="na"&gt;httpOnly&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;secure&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Embrace Environment Variables 🌍
&lt;/h3&gt;

&lt;p&gt;My database credentials were basically public before. Moving them to environment variables was like putting money in a safe instead of leaving it on the sidewalk.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Rate Limiting: The Digital Bouncer 💪
&lt;/h3&gt;

&lt;p&gt;Adding rate limiting was like hiring a bouncer for our API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&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="nf"&gt;rateLimit&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;windowMs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&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;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5-10: The Complete Protection Package 🛡️
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Practice&lt;/th&gt;
&lt;th&gt;What It Does&lt;/th&gt;
&lt;th&gt;Implementation Difficulty&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;🔒 2FA Authentication&lt;/td&gt;
&lt;td&gt;Adds a second verification layer&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🚫 CSRF Protection&lt;/td&gt;
&lt;td&gt;Prevents cross-site request forgery&lt;/td&gt;
&lt;td&gt;Easy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;👮 Input Validation&lt;/td&gt;
&lt;td&gt;Ensures data matches expected format&lt;/td&gt;
&lt;td&gt;Easy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;⏱️ Token Expiration&lt;/td&gt;
&lt;td&gt;Makes stolen tokens useless after time&lt;/td&gt;
&lt;td&gt;Easy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🔍 Audit Logging&lt;/td&gt;
&lt;td&gt;Records who did what, when&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🚪 Secure Password Reset&lt;/td&gt;
&lt;td&gt;Prevents account takeover via resets&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Security vs. Developer Experience ⚖️
&lt;/h2&gt;

&lt;p&gt;I worried implementing all this would make our codebase complex. Turns out, good security can be clean:&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;Security Level&lt;/th&gt;
&lt;th&gt;Developer Friendliness&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Manual Implementation&lt;/td&gt;
&lt;td&gt;🔴 Variable&lt;/td&gt;
&lt;td&gt;🟠 Complex&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Passport.js&lt;/td&gt;
&lt;td&gt;🟢 High&lt;/td&gt;
&lt;td&gt;🟢 Simple&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auth0/Firebase&lt;/td&gt;
&lt;td&gt;🟢 Very High&lt;/td&gt;
&lt;td&gt;🟢 Very Simple&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The Happy Ending 🌈
&lt;/h2&gt;

&lt;p&gt;Two weeks later, I deployed our properly secured application. That night, I slept peacefully. No alerts, no dancing bananas.&lt;/p&gt;

&lt;p&gt;When our startup got acquired six months later, the security audit passed with flying colors. The acquiring company's CISO actually said, "Whoever set up your auth system knew what they were doing." &lt;/p&gt;

&lt;p&gt;I may have teared up a little. 🥹&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Win: The One-Line Security Boost ⚡
&lt;/h2&gt;

&lt;p&gt;Add this single line to your Express app to prevent common attacks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&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="nf"&gt;helmet&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This one package adds 12 middleware security enhancements instantly!&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways 🎯
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🔐 Proper authentication is &lt;strong&gt;essential&lt;/strong&gt;, not optional&lt;/li&gt;
&lt;li&gt;🧂 Always hash passwords, never store them as plaintext&lt;/li&gt;
&lt;li&gt;🍪 Store JWTs in HttpOnly cookies for better security&lt;/li&gt;
&lt;li&gt;🔢 Implement 2FA for critical operations&lt;/li&gt;
&lt;li&gt;📝 Validate all inputs, no exceptions&lt;/li&gt;
&lt;li&gt;🕰️ Set appropriate token expiration times&lt;/li&gt;
&lt;li&gt;📊 Log authentication events for auditing&lt;/li&gt;
&lt;li&gt;🛡️ Use established libraries instead of rolling your own auth&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remember: Security isn't about being unhackable (nothing is); it's about making the effort required greater than the reward. Make your app the digital equivalent of a house with good locks, an alarm system, and no valuables visible from the windows! 🏠🔒&lt;/p&gt;

</description>
      <category>node</category>
      <category>authentication</category>
    </item>
    <item>
      <title>Mastering Node.js Error Handling: From Crashes to 99.9% Uptime</title>
      <dc:creator>Fahim Hasnain Fahad</dc:creator>
      <pubDate>Sat, 24 May 2025 07:16:04 +0000</pubDate>
      <link>https://dev.to/fahim_hasnain_fahad/mastering-nodejs-error-handling-from-crashes-to-999-uptime-1627</link>
      <guid>https://dev.to/fahim_hasnain_fahad/mastering-nodejs-error-handling-from-crashes-to-999-uptime-1627</guid>
      <description>&lt;h1&gt;
  
  
  Mastering Node.js Error Handling: From Crashes to 99.9% Uptime
&lt;/h1&gt;

&lt;h2&gt;
  
  
  The Great Server Meltdown of 2023 🔥
&lt;/h2&gt;

&lt;p&gt;It was 3 AM when my phone erupted with notifications. Our production server had crashed—again. 😱 As I groggily logged in, the dreaded &lt;code&gt;UnhandledPromiseRejection&lt;/code&gt; error greeted me like an old enemy.&lt;/p&gt;

&lt;p&gt;"Why didn't anyone catch this exception?" I muttered while frantically restarting services.&lt;/p&gt;

&lt;p&gt;Sound familiar? Six months ago, I was that junior developer whose Node.js applications resembled a house of cards—one unexpected error and everything came tumbling down. Today, our uptime is 99.9%, and I sleep through the night. Let me tell you how I turned things around! 🚀&lt;/p&gt;

&lt;h2&gt;
  
  
  The Error-Handling Journey 🗺️
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Phase 1: The Naive Days 🙈
&lt;/h3&gt;

&lt;p&gt;Like many developers, I started with the classic "hope nothing breaks" approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&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;/users&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;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;someRiskyOperation&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// What could go wrong?&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;data&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;One database hiccup later, and our entire API was down. Users were angry, managers were angrier.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 2: Try-Catch Everything! 🤔
&lt;/h3&gt;

&lt;p&gt;My first solution? Wrap EVERYTHING in try-catch blocks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// 500 lines of business logic&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;error&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;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Something went wrong&lt;/span&gt;&lt;span class="dl"&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better than nothing, but still missing the mark. It was like putting a single fire extinguisher in a skyscraper and calling it "fire safety."&lt;/p&gt;

&lt;h2&gt;
  
  
  The Error Handling Toolkit ⚒️
&lt;/h2&gt;

&lt;p&gt;As I learned more, I developed a systematic approach to handling errors in Node.js. Here's what changed everything:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Categorizing Errors 📊
&lt;/h3&gt;

&lt;p&gt;Not all errors are created equal!&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Error Type&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;How to Handle&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Operational Errors&lt;/td&gt;
&lt;td&gt;Expected problems during normal operation&lt;/td&gt;
&lt;td&gt;Network timeout, Invalid user input&lt;/td&gt;
&lt;td&gt;Catch and handle gracefully&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Programmer Errors&lt;/td&gt;
&lt;td&gt;Bugs in the code&lt;/td&gt;
&lt;td&gt;Trying to read property of undefined&lt;/td&gt;
&lt;td&gt;Fix the bug!&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unrecoverable Errors&lt;/td&gt;
&lt;td&gt;System-level failures&lt;/td&gt;
&lt;td&gt;Out of memory, Uncaught exceptions&lt;/td&gt;
&lt;td&gt;Crash and restart safely&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  2. The Error Handling Hierarchy 🏰
&lt;/h3&gt;

&lt;p&gt;I implemented a layered approach:&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;Responsibility&lt;/th&gt;
&lt;th&gt;Implementation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Function Level&lt;/td&gt;
&lt;td&gt;Handle known errors specific to function&lt;/td&gt;
&lt;td&gt;try/catch, return Result objects&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Module Level&lt;/td&gt;
&lt;td&gt;Handle domain-specific errors&lt;/td&gt;
&lt;td&gt;Custom error classes, error mappers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Process Level&lt;/td&gt;
&lt;td&gt;Catch uncaught exceptions&lt;/td&gt;
&lt;td&gt;Global handlers, graceful shutdown&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Infrastructure Level&lt;/td&gt;
&lt;td&gt;Ensure system resilience&lt;/td&gt;
&lt;td&gt;Process managers, health checks&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The Game-Changers ⚡
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Custom Error Classes 🔍
&lt;/h3&gt;

&lt;p&gt;Creating custom error types completely transformed our debugging experience:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DatabaseConnectionError&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Error&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;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;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Database connection failed: &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="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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Async/Await Error Handling 🧩
&lt;/h3&gt;

&lt;p&gt;Promise rejections were our #1 source of crashes until I discovered this pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&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;asyncOperation&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="o"&gt;=&amp;gt;&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="nx"&gt;err&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;result&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;return&lt;/span&gt; &lt;span class="nf"&gt;handleError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  💡 Pro Tip: Express Error Middleware
&lt;/h2&gt;

&lt;p&gt;The single biggest improvement came from centralizing error handling:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&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;err&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="nx"&gt;next&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;status&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;statusCode&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;500&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="nx"&gt;err&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This simple middleware saved us hours of debugging time and prevented countless crashes!&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Results 📈
&lt;/h2&gt;

&lt;p&gt;Before implementing these techniques, we had:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;2-3 production crashes weekly 😓&lt;/li&gt;
&lt;li&gt;Hours spent debugging cryptic errors&lt;/li&gt;
&lt;li&gt;Angry customers and stressed developers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;99.9% uptime for 6 months straight 🎉&lt;/li&gt;
&lt;li&gt;Clear error messages that point to root causes&lt;/li&gt;
&lt;li&gt;A team that sleeps through the night!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key Takeaways 🎯
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Don't just catch errors—categorize them&lt;/strong&gt; and handle each type appropriately&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build an error handling strategy&lt;/strong&gt; that works at multiple levels of your application&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use custom error classes&lt;/strong&gt; to make debugging faster and easier&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implement central error handling middleware&lt;/strong&gt; in Express applications&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Treat error handling as a first-class feature&lt;/strong&gt;, not an afterthought&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Log strategically&lt;/strong&gt;—too little information is useless, too much is noise&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remember: In Node.js, good error handling isn't just about preventing crashes—it's about building resilient systems that fail gracefully and recover automatically. Now go forth and catch those errors! 🦸‍♂️&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>programming</category>
      <category>backend</category>
    </item>
    <item>
      <title>10X Your NodeJS: Performance Tricks for 100ms Responses</title>
      <dc:creator>Fahim Hasnain Fahad</dc:creator>
      <pubDate>Mon, 19 May 2025 09:23:59 +0000</pubDate>
      <link>https://dev.to/fahim_hasnain_fahad/10x-your-nodejs-performance-tricks-for-100ms-responses-2plf</link>
      <guid>https://dev.to/fahim_hasnain_fahad/10x-your-nodejs-performance-tricks-for-100ms-responses-2plf</guid>
      <description>&lt;h2&gt;
  
  
  🚀 The Wake-Up Call
&lt;/h2&gt;

&lt;p&gt;It was 2 AM when my phone rang. The CEO's voice was tense. "The app is crawling. Users are complaining. Fix it." &lt;/p&gt;

&lt;p&gt;I still remember that night vividly. Our NodeJS app that handled customer orders was buckling under traffic. Response times had gone from snappy to sluggish—2-3 seconds per request. 😱 &lt;/p&gt;

&lt;p&gt;Sound familiar? If you're a junior developer working with NodeJS, you might have faced (or will face) this scenario. Let me share how I transformed our application from a tortoise to a cheetah! ⚡&lt;/p&gt;

&lt;h2&gt;
  
  
  🕵️ Diagnosing the Problem
&lt;/h2&gt;

&lt;p&gt;The next morning, bleary-eyed but determined, I started investigating. Our stack looked pretty standard:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;NodeJS/Express&lt;/td&gt;
&lt;td&gt;API server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MongoDB&lt;/td&gt;
&lt;td&gt;Database&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Redis&lt;/td&gt;
&lt;td&gt;Caching&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AWS EC2&lt;/td&gt;
&lt;td&gt;Hosting&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The app was structured like most Express applications, with routes handling requests and controllers processing business logic. But something was clearly wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔍 The Bottlenecks
&lt;/h2&gt;

&lt;p&gt;I discovered three main issues that were throttling our performance:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Database queries were inefficient&lt;/strong&gt; 🐢&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No caching strategy&lt;/strong&gt; 💾&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blocking operations in the event loop&lt;/strong&gt; ⛓️&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🛠️ The Transformation Journey
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Optimizing MongoDB Queries ⚡
&lt;/h3&gt;

&lt;p&gt;I found queries like this throughout our codebase:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;users&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;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;({});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This was loading &lt;strong&gt;ALL&lt;/strong&gt; users into memory before filtering on the application side! &lt;/p&gt;

&lt;p&gt;I replaced them with properly indexed, filtered queries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;users&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;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;active&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="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;limit&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Quick Win&lt;/strong&gt; 🏆: Adding appropriate indexes reduced query times by 80%!&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Query Type&lt;/th&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;th&gt;After&lt;/th&gt;
&lt;th&gt;Improvement&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;User Search&lt;/td&gt;
&lt;td&gt;1200ms&lt;/td&gt;
&lt;td&gt;95ms&lt;/td&gt;
&lt;td&gt;92% faster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Product Listing&lt;/td&gt;
&lt;td&gt;1800ms&lt;/td&gt;
&lt;td&gt;120ms&lt;/td&gt;
&lt;td&gt;93% faster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Order History&lt;/td&gt;
&lt;td&gt;2100ms&lt;/td&gt;
&lt;td&gt;150ms&lt;/td&gt;
&lt;td&gt;93% faster&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Step 2: Implementing Redis Caching 🚀
&lt;/h3&gt;

&lt;p&gt;For frequently accessed data that rarely changes (like product categories), I implemented Redis:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&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;redisClient&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;categories&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="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchAndCacheCategories&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This simple pattern eliminated repetitive database queries for common data. Think of Redis as your refrigerator - why go grocery shopping (query the database) every time you want a snack? 🍎&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Non-Blocking Operations 🔄
&lt;/h3&gt;

&lt;p&gt;I discovered we were reading files synchronously in some routes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Before: Blocking the event loop 😖&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./templates/email.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// After: Non-blocking 😊&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;template&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;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;promises&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./templates/email.html&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;Remember: NodeJS is like a single-lane highway. One slow truck (blocking operation) causes traffic for everyone!&lt;/p&gt;

&lt;h2&gt;
  
  
  🎯 The Memory Leak Mystery
&lt;/h2&gt;

&lt;p&gt;Our server would occasionally crash after running for a few days. Using &lt;code&gt;node --inspect&lt;/code&gt; and Chrome DevTools, I discovered we were accumulating references to large objects.&lt;/p&gt;

&lt;p&gt;The culprit? Event listeners that weren't being properly removed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Fixed by adding proper cleanup&lt;/span&gt;
&lt;span class="nx"&gt;emitter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ⚡ Pro Tip: Async/Await Patterns
&lt;/h2&gt;

&lt;p&gt;One pattern that significantly improved our code readability and performance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Use Promise.all for parallel operations&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;users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;categories&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="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="nf"&gt;fetchUsers&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="nf"&gt;fetchProducts&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="nf"&gt;fetchCategories&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 runs all three operations concurrently rather than sequentially, cutting response time by ~66%! &lt;/p&gt;

&lt;h2&gt;
  
  
  📊 The Results
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;th&gt;After&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Avg Response Time&lt;/td&gt;
&lt;td&gt;2300ms&lt;/td&gt;
&lt;td&gt;95ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Server Memory&lt;/td&gt;
&lt;td&gt;1.2GB&lt;/td&gt;
&lt;td&gt;450MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Crash Frequency&lt;/td&gt;
&lt;td&gt;Every 2-3 days&lt;/td&gt;
&lt;td&gt;None in 3 months&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  🎯 Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Index everything&lt;/strong&gt; that you query frequently in MongoDB 🔍&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache aggressively&lt;/strong&gt; with Redis for data that changes infrequently 💾&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid blocking the event loop&lt;/strong&gt; - use async operations wherever possible 🔄&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitor memory usage&lt;/strong&gt; to catch leaks before they become problems 📈&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Promise.all&lt;/strong&gt; for concurrent operations ⚡&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Profile regularly&lt;/strong&gt; - what's fast today might be slow tomorrow 🕒&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The CEO called me a week later: "Whatever you did, it worked. The app feels lightning fast." &lt;/p&gt;

&lt;p&gt;Sometimes the biggest performance gains come from the simplest changes. Happy optimizing! 🚀&lt;/p&gt;

</description>
      <category>node</category>
      <category>nextjs</category>
      <category>mongodb</category>
    </item>
    <item>
      <title>Scale to 10M Users: CQRS in NestJS for API Performance</title>
      <dc:creator>Fahim Hasnain Fahad</dc:creator>
      <pubDate>Sat, 17 May 2025 11:07:39 +0000</pubDate>
      <link>https://dev.to/fahim_hasnain_fahad/scale-to-10m-users-cqrs-in-nestjs-for-api-performance-3n14</link>
      <guid>https://dev.to/fahim_hasnain_fahad/scale-to-10m-users-cqrs-in-nestjs-for-api-performance-3n14</guid>
      <description>&lt;h2&gt;
  
  
  Scale to 10M Users: CQRS in NestJS for API Performance
&lt;/h2&gt;

&lt;p&gt;In today's digital landscape, building applications that can handle millions of users requires thoughtful architecture decisions. Command Query Responsibility Segregation (CQRS) is one such pattern that helps maintain performance at scale. Let's explore!&lt;/p&gt;

&lt;h2&gt;
  
  
  What is CQRS and Why Use It?
&lt;/h2&gt;

&lt;p&gt;CQRS splits your application into two models:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Command model&lt;/strong&gt;: Handles create, update, and delete operations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Query model&lt;/strong&gt;: Manages read operations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This separation addresses the reality that most applications have asymmetric read/write loads—typically with reads far outnumbering writes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up CQRS in NestJS
&lt;/h2&gt;

&lt;p&gt;First, install the required packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @nestjs/cqrs uuid kafkajs redis mongodb pg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Directory Structure
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
├── commands/
│   ├── handlers/
│   ├── impl/
├── queries/
│   ├── handlers/
│   ├── impl/
├── events/
├── models/
├── controllers/
└── app.module.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Basic Implementation
&lt;/h3&gt;

&lt;p&gt;Let's start with our &lt;code&gt;app.module.ts&lt;/code&gt;:&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;Module&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;@nestjs/common&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;CqrsModule&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;@nestjs/cqrs&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;MongooseModule&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;@nestjs/mongoose&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;TypeOrmModule&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;@nestjs/typeorm&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;CommandHandlers&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;./commands/handlers&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;QueryHandlers&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;./queries/handlers&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;EventHandlers&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;./events/handlers&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;Controllers&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;./controllers&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="nd"&gt;Module&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;CqrsModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;MongooseModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mongodb://localhost:27017/cqrs_read&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nx"&gt;TypeOrmModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forRoot&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;postgres&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;localhost&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5432&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;postgres&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cqrs_write&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;entities&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/**/*.entity{.ts,.js}&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;synchronize&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="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;controllers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;Controllers&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;providers&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;CommandHandlers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;QueryHandlers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;EventHandlers&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppModule&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's define a command:&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;// commands/impl/create-user.command.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CreateUserCommand&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="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;email&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="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;name&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="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;And its handler:&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;// commands/handlers/create-user.handler.ts&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;CommandHandler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ICommandHandler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;EventBus&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;@nestjs/cqrs&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;InjectRepository&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;@nestjs/typeorm&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;Repository&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;typeorm&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;CreateUserCommand&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;../impl/create-user.command&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;User&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;../../models/user.entity&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;UserCreatedEvent&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;../../events/impl/user-created.event&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="nd"&gt;CommandHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;CreateUserCommand&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CreateUserHandler&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;ICommandHandler&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CreateUserCommand&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;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;InjectRepository&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="k"&gt;private&lt;/span&gt; &lt;span class="na"&gt;userRepository&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Repository&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="k"&gt;private&lt;/span&gt; &lt;span class="na"&gt;eventBus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EventBus&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="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CreateUserCommand&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;command&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;new&lt;/span&gt; &lt;span class="nc"&gt;User&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;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;email&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;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&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;savedUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&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;userRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&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="c1"&gt;// Publish event for read model synchronization&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;eventBus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;publish&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;UserCreatedEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;savedUser&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;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&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;savedUser&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;
  
  
  Query Side with MongoDB
&lt;/h3&gt;

&lt;p&gt;For read operations, we'll use MongoDB for its superior query performance:&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;// queries/impl/get-user.query.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GetUserQuery&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="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&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="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// queries/handlers/get-user.handler.ts&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;QueryHandler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;IQueryHandler&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;@nestjs/cqrs&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;InjectModel&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;@nestjs/mongoose&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;Model&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;mongoose&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;GetUserQuery&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;../impl/get-user.query&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;UserReadModel&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;../../models/user.read-model&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="nd"&gt;QueryHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;GetUserQuery&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GetUserHandler&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;IQueryHandler&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;GetUserQuery&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;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;InjectModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;UserReadModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="na"&gt;userModel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;UserReadModel&lt;/span&gt;&lt;span class="o"&gt;&amp;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="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GetUserQuery&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;UserReadModel&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;return&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;userModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findOne&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;query&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;exec&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;
  
  
  Synchronizing Read/Write Models with Kafka
&lt;/h3&gt;

&lt;p&gt;To keep our read model updated, we'll use Kafka for event sourcing:&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;// events/handlers/user-created.handler.ts&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;EventsHandler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;IEventHandler&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;@nestjs/cqrs&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;Inject&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;@nestjs/common&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;ClientKafka&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;@nestjs/microservices&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;UserCreatedEvent&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;../impl/user-created.event&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="nd"&gt;EventsHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;UserCreatedEvent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserCreatedHandler&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;IEventHandler&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;UserCreatedEvent&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;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;KAFKA_SERVICE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="na"&gt;kafkaClient&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ClientKafka&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserCreatedEvent&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;kafkaClient&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;user-created&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="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;event&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="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&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="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="nf"&gt;toISOString&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;And our consumer service:&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;// services/read-model-sync.service.ts&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;Injectable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;OnModuleInit&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;@nestjs/common&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;InjectModel&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;@nestjs/mongoose&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;Model&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;mongoose&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;Consumer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Kafka&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;kafkajs&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;UserReadModel&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;../models/user.read-model&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="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ReadModelSyncService&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;OnModuleInit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;consumer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Consumer&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="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;InjectModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;UserReadModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;userModel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;UserReadModel&lt;/span&gt;&lt;span class="o"&gt;&amp;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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;kafka&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;Kafka&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;read-model-sync&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;brokers&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;localhost:9092&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;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;consumer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;kafka&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;consumer&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;groupId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;read-model-sync-group&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;async&lt;/span&gt; &lt;span class="nf"&gt;onModuleInit&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;consumer&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;await&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;consumer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;topic&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-created&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;fromBeginning&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="k"&gt;await&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;consumer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;eachMessage&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;topic&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;eventData&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;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&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;topic&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user-created&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;await&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;userModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;updateOne&lt;/span&gt;&lt;span class="p"&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;eventData&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="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;eventData&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="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;eventData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;eventData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;updatedAt&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="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;upsert&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="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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To further enhance read performance, we can add Redis Caching for Read Queries.&lt;/p&gt;

</description>
      <category>node</category>
      <category>nestjs</category>
      <category>cqrs</category>
    </item>
    <item>
      <title>Breaking the Scale Barrier: 1 Million Messages with NodeJS and Kafka</title>
      <dc:creator>Fahim Hasnain Fahad</dc:creator>
      <pubDate>Wed, 15 Jan 2025 15:17:24 +0000</pubDate>
      <link>https://dev.to/fahim_hasnain_fahad/breaking-the-scale-barrier-1-million-messages-with-nodejs-and-kafka-436e</link>
      <guid>https://dev.to/fahim_hasnain_fahad/breaking-the-scale-barrier-1-million-messages-with-nodejs-and-kafka-436e</guid>
      <description>&lt;p&gt;Apache Kafka is a distributed event streaming platform which can be used as a Pub-Sub broker in NodeJS microservices. Recently, I worked in a project where publisher needed to send messages to 1 million users and give the response back. Here, a cool thing can be done by Message Queue and we can send 1 million messages in a queue and it will send the messages to the users one by one. But, a pub-sub can broadcast to all instances of a consumer which are subscribed to a certain topic.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Magic of Message Queues vs. Pub-Sub in Kafka
&lt;/h2&gt;

&lt;p&gt;When faced with such a massive scale of messaging, two approaches often come to mind:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Message Queue: Send 1 million messages to a queue, where each message is processed one by one by consumers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pub-Sub: Broadcast a single message to all instances of consumers subscribed to a specific topic.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For our use case, Kafka’s flexibility in handling both patterns made it the ideal choice. Let’s dive into how to implement a Producer-Consumer microservice system with Kafka.&lt;/p&gt;

&lt;p&gt;Check out the demo code: &lt;a href="https://github.com/fahadfahim13/producer-consumer-kafka.git" rel="noopener noreferrer"&gt;https://github.com/fahadfahim13/producer-consumer-kafka.git&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&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.amazonaws.com%2Fuploads%2Farticles%2F1na1xqalioul7ogxszqf.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.amazonaws.com%2Fuploads%2Farticles%2F1na1xqalioul7ogxszqf.png" alt="NodeJS Microservice with Kafka" width="632" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Producer Microservice:
&lt;/h2&gt;

&lt;p&gt;Let's create a Producer microservice and a Consumer microservice.&lt;br&gt;
Code in &lt;code&gt;producer/index.js&lt;/code&gt; will be like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { Kafka } = require('kafkajs');

const kafka = new Kafka({
  clientId: 'my-producer',
  brokers: [process.env.KAFKA_BROKER],
});

const producer = kafka.producer();

(async () =&amp;gt; {
  await producer.connect();
  for (let i = 0; i &amp;lt; 1000000; i++) {
    await producer.send({
      topic: process.env.TOPIC_NAME,
      messages: [{ value: `Message ${i}` }],
    });
    console.log(`Sent message ${i}`);
  }
  await producer.disconnect();
})();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we can see the producer is producing 1 million messages and sending into a Kafka topic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Consumer Microservice
&lt;/h2&gt;

&lt;p&gt;Code in consumer microservice's &lt;code&gt;index.js&lt;/code&gt; file will be like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { Kafka } = require('kafkajs');

const kafka = new Kafka({
  clientId: 'my-consumer',
  brokers: [process.env.KAFKA_BROKER],
});

const consumer = kafka.consumer({ groupId: 'test-group' });

(async () =&amp;gt; {
  await consumer.connect();
  await consumer.subscribe({ topic: process.env.TOPIC_NAME, fromBeginning: true });

  await consumer.run({
    eachMessage: async ({ topic, partition, message }) =&amp;gt; {
      console.log(`Received message: ${message.value} in topic: ${topic} at partition: ${partition}`);
    },
  });
})();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The consumers will be subscribed to a Kafka topic and receive messages asynchronously and process those messages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker-compose File
&lt;/h2&gt;

&lt;p&gt;The docker-compose.yml file looks like this which will run zookeeper, kafka and producer &amp;amp; consumer services in different containers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: '3.8'
services:
  zookeeper:
    image: confluentinc/cp-zookeeper:latest
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_TICK_TIME: 2000
    ports:
      - "22181:2181"
    networks:
      - kafka-network
    volumes:
      - kafka_data:/var/lib/kafka/data

  kafka:
    image: confluentinc/cp-kafka:latest
    depends_on:
      - zookeeper
    ports:
      - "29092:29092"
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092,PLAINTEXT_HOST://localhost:29092
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
      KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
    networks:
      - kafka-network

  producer:
    build: 
      context: ./producer
      dockerfile: Dockerfile
    container_name: kafka-producer
    depends_on:
      - kafka
    networks:
      - kafka-network
    volumes:
      - ./producer:/app
    environment:
      KAFKA_BOOTSTRAP_SERVERS: kafka:9092
      KAFKA_BROKER: kafka:9092
      TOPIC_NAME: my-topic

  consumer:
    build: 
      context: ./consumer
      dockerfile: Dockerfile
    container_name: kafka-consumer
    depends_on:
      - kafka
    networks:
      - kafka-network
    volumes:
      - ./consumer:/app
    environment:
      KAFKA_BOOTSTRAP_SERVERS: kafka:9092
      KAFKA_BROKER: kafka:9092
      TOPIC_NAME: my-topic

networks:
  kafka-network:
    driver: bridge


volumes:
  kafka_data:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Optimizing Kafka Performance with Partitions
&lt;/h2&gt;

&lt;p&gt;To handle high throughput, it’s essential to increase the number of partitions in our Kafka topic. More partitions allow parallel processing, enabling producers and consumers to scale horizontally. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kafka-topics --create \
  --zookeeper localhost:2181 \
  --replication-factor 1 \
  --partitions 10 \
  --topic my-topic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each partition acts as a separate queue, distributing the load among consumers.&lt;/p&gt;

&lt;p&gt;Check out the demo code: &lt;a href="https://github.com/fahadfahim13/producer-consumer-kafka.git" rel="noopener noreferrer"&gt;https://github.com/fahadfahim13/producer-consumer-kafka.git&lt;/a&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>microservices</category>
      <category>pubsub</category>
      <category>kafka</category>
    </item>
    <item>
      <title>Full Stack in a Container: NodeJS, NextJS, and MongoDB with Docker</title>
      <dc:creator>Fahim Hasnain Fahad</dc:creator>
      <pubDate>Fri, 10 Jan 2025 20:20:15 +0000</pubDate>
      <link>https://dev.to/fahim_hasnain_fahad/full-stack-in-a-container-nodejs-nextjs-and-mongodb-with-docker-k50</link>
      <guid>https://dev.to/fahim_hasnain_fahad/full-stack-in-a-container-nodejs-nextjs-and-mongodb-with-docker-k50</guid>
      <description>&lt;p&gt;Recently, I had to create a NodeJS project for backend and a NextJS project for Frontend and connect MongoDB local database in NodeJS. &lt;br&gt;
I tried to run everything locally but using Docker gave me the most optimal way of running everything together inside different containers.&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.amazonaws.com%2Fuploads%2Farticles%2Fiscws9eoyj3gpodh633f.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.amazonaws.com%2Fuploads%2Farticles%2Fiscws9eoyj3gpodh633f.png" alt="NodeJS, NextJS and MongoDB meets in docker" width="716" height="558"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have run all the projects and DB inside different containers. The Frontend will run at 3000 port, Backend will run at 8000 port and DB will run at 27017 port of localhost.&lt;br&gt;
The Project structure was something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;project/
│
├── docker-compose.yml     # Where all the containers are declared
│
├── backend/                  
│   ├── package.json           
│   ├── Dockerfile            
│   └── index.js            # Where server runs
│
│
├── frontend/                  
│   ├── package.json           
│   ├── Dockerfile            
│   └── layout.jsx           # Where home page runs
│

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we need to run the frontend and declare the &lt;code&gt;Dockerfile&lt;/code&gt; for it. In order to run these setups in production as well, I've kept the build commands.&lt;br&gt;
Frontend/Dockerfile looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Use the official Node.js image as the base image
FROM node:20

# Set the working directory
WORKDIR /app

# Copy package.json and package-lock.json
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy the rest of the application code
COPY . .

# Build the application
RUN npm run build

# Expose the port the app runs on
EXPOSE 3000

# Start the application
CMD ["npm", "start"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly, the backend Dockerfile looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Dockerfile

# Use the official Node.js image as a base image
FROM node:18

# Set the working directory inside the container
WORKDIR /app

# Copy package.json and package-lock.json
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy the rest of the application code
COPY . .

# Build the application
RUN npm run build

# Expose the port that the app runs on
EXPOSE 8000

# Command to run the application
CMD ["npm", "start"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, In order to connect these containers with DB container, we need to create a docker-network and keep all the containers under the same network.&lt;/p&gt;

&lt;p&gt;The root project folder has the docker-compose.yml file which will define all the containers, DB volume and the docker network.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: '3.8'

services:
  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    ports:
      - "8000:8000"
    environment:
      - MONGODB_URI=mongodb://mongo:27017/db
      - PORT=8000
    depends_on:
      - mongo
    networks:
      - project-network

  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
    ports:
      - "3000:3000"
    environment:
      - NEXT_PUBLIC_WEBSOCKET_URL=http://localhost:8000
      - NEXT_PUBLIC_HTTP_URL=http://localhost:8000
    depends_on:
      - backend
    networks:
      - project-network

  mongo:
    image: mongo:latest
    ports:
      - "27017:27017"
    volumes:
      - mongo-data:/data/db
    networks:
      - project-network

networks:
  project-network:
    driver: bridge

volumes:
  mongo-data:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This config file has 3 containers: &lt;code&gt;frontend&lt;/code&gt;, &lt;code&gt;backend&lt;/code&gt; &amp;amp; &lt;code&gt;mongo&lt;/code&gt;. The &lt;code&gt;backend&lt;/code&gt; container depends on &lt;code&gt;mongo&lt;/code&gt; container, and the &lt;code&gt;frontend&lt;/code&gt; container depends on the &lt;code&gt;backend&lt;/code&gt; container. All 3 containers has connected into the &lt;code&gt;project-network&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Now if we run &lt;code&gt;docker-compose up -d&lt;/code&gt; in the root folder to run it in detached mode, in the Docker Desktop, we can see the logs for all containers. &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.amazonaws.com%2Fuploads%2Farticles%2Fkuu7h9i9blnmizlz9hxe.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.amazonaws.com%2Fuploads%2Farticles%2Fkuu7h9i9blnmizlz9hxe.png" alt="All containers running" width="568" height="270"&gt;&lt;/a&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.amazonaws.com%2Fuploads%2Farticles%2F5tfrnwnbg3n9i8u590cb.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.amazonaws.com%2Fuploads%2Farticles%2F5tfrnwnbg3n9i8u590cb.png" alt="Backend container" width="619" height="294"&gt;&lt;/a&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.amazonaws.com%2Fuploads%2Farticles%2F2yln0euwssm7et0lepec.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.amazonaws.com%2Fuploads%2Farticles%2F2yln0euwssm7et0lepec.png" alt="Frontend Container" width="672" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To see the full project code, visit now: &lt;a href="https://github.com/fahadfahim13/httpbin-monitor.git" rel="noopener noreferrer"&gt;https://github.com/fahadfahim13/httpbin-monitor.git&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Node.js Meets PostgreSQL and MongoDB in Docker: Docker Diaries</title>
      <dc:creator>Fahim Hasnain Fahad</dc:creator>
      <pubDate>Tue, 07 Jan 2025 20:36:33 +0000</pubDate>
      <link>https://dev.to/fahim_hasnain_fahad/nodejs-meets-postgresql-and-mongodb-in-docker-docker-diaries-4bk6</link>
      <guid>https://dev.to/fahim_hasnain_fahad/nodejs-meets-postgresql-and-mongodb-in-docker-docker-diaries-4bk6</guid>
      <description>&lt;p&gt;Recently, I had to create a NodeJS application where I had to connect to 2 different database in PostgreSQL and MongoDB. For application scaling, I had to use Docker and Kubernetes. Here's how I connected all these inside docker.&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.amazonaws.com%2Fuploads%2Farticles%2Feav9z76331mf0gzbkkfv.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.amazonaws.com%2Fuploads%2Farticles%2Feav9z76331mf0gzbkkfv.png" alt="NodeJS connects with PostgreSQL and MongoDB in Docker" width="716" height="558"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In order to run this whole thing using &lt;code&gt;docker-compose&lt;/code&gt;, visit this repo: &lt;a href="https://github.com/fahadfahim13/node-pg-mongo-docker.git" rel="noopener noreferrer"&gt;https://github.com/fahadfahim13/node-pg-mongo-docker.git&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Project Setup
&lt;/h2&gt;

&lt;p&gt;Run the following commands with your preferred project name:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir node-postgres-mongo
cd node-postgres-mongo
npm init -y

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The install these dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install express pg mongoose dotenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside this project, create an &lt;code&gt;index.js&lt;/code&gt; file and a &lt;code&gt;.env&lt;/code&gt; file.&lt;br&gt;
Also, create a &lt;code&gt;config&lt;/code&gt; folder, and inside this folder, create &lt;code&gt;mongodb.js&lt;/code&gt; and &lt;code&gt;postgres.js&lt;/code&gt; files for configuration.&lt;/p&gt;

&lt;p&gt;The index.js file should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express');
const pgPool = require('./config/postgres');
const connectMongoDB = require('./config/mongodb');
require('dotenv').config();

const app = express();
const port = process.env.PORT || 8088;

app.get('/', (req, res) =&amp;gt; {
    res.send('Hello World!');
});

app.listen(port, async () =&amp;gt; {
    try {
        // Initialize database connections
        await connectMongoDB();
        await pgPool.connect();
        console.log('PostgreSQL connected successfully');

        console.log(`Server is running at http://localhost:${port}`);
    } catch (error) {
        console.error('Error during startup:', error);
        process.exit(1);
    }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;config/postgres.js&lt;/code&gt; should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { Pool } = require('pg');
require('dotenv').config();

const pgPool = new Pool({
    host: process.env.POSTGRES_HOST || 'postgres-db', // PostgreSQL container name
    port: 5432,
    user: process.env.POSTGRES_USER || 'admin',
    password: process.env.POSTGRES_PASSWORD || 'admin123',
    database: process.env.POSTGRES_DB || 'testdb',
  });


module.exports = pgPool;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;config/mongodb.js&lt;/code&gt; should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const mongoose = require('mongoose');
require('dotenv').config();

const connectMongoDB = async () =&amp;gt; {
    try {
        const mongoURI = `mongodb://${process.env.MONGO_INITDB_ROOT_USERNAME || 'root'}:${process.env.MONGO_INITDB_ROOT_PASSWORD || 'root123'}@${process.env.MONGO_INITDB_ROOT_CONTAINER || 'mongo-container'}:27017/testdb?authSource=admin`;
        mongoose.connect(mongoURI, { useNewUrlParser: true, useUnifiedTopology: true })
        .then(() =&amp;gt; console.log('Connected to MongoDB'))
        .catch(err =&amp;gt; console.error('MongoDB connection error:', err));
        console.log('MongoDB connected successfully');
    } catch (error) {
        console.error('MongoDB connection error:', error);
        process.exit(1);
    }
};

module.exports = connectMongoDB;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Docker Setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Create Dockerfile
&lt;/h3&gt;

&lt;p&gt;Create a file named &lt;code&gt;Dockerfile&lt;/code&gt; inside root directory of the nodejs project and paste this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM node:18

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 8088

CMD ["npm", "start"]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Network creation
&lt;/h3&gt;

&lt;p&gt;In order to connect all containers, we need one docker network by which all containers can connect. Run the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker network create node-postgres-mongo # Creates a network named node-postgres-mongo

docker network ls # Lists all networks available in docker to check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  PostgreSQL container setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker pull postgres # Pulls image if not available in local
docker run --name postgres-db --network node-postgres-mongo -e POSTGRES_USER=admin -e POSTGRES_PASSWORD=admin123 -e POSTGRES_DB=testdb -p 5432:5432 -d postgres # Runs the DB in a container named postgres-db
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this, if you run &lt;code&gt;docker ps&lt;/code&gt;, you should see a container named &lt;code&gt;postgres-db&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.amazonaws.com%2Fuploads%2Farticles%2Fi4r0kq80rvwn8z9ujleu.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.amazonaws.com%2Fuploads%2Farticles%2Fi4r0kq80rvwn8z9ujleu.png" alt="PostgreSQL Container" width="800" height="61"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  MongoDB container setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker pull mongo # Pulls if image is not available in local
docker run --name mongo-db --network node-postgres-mongo -e MONGO_INITDB_ROOT_USERNAME=root -e MONGO_INITDB_ROOT_PASSWORD=root123 -p 27017:27017 -d mongo # Creates a container in the same network named mongo-db
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  NodeJS container run
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build -t node-pg-mongo . # Build the image with name node-pg-mongo in the root directory


docker run --name node-pg-mongo --network node-postgres-mongo -p 8088:8088 -d node-pg-mongo # Run the image into container named node-pg-mongo in the same network
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All Done! Now if we run &lt;code&gt;docker logs node-pg-mongo&lt;/code&gt;, we can see the logs of the running application and it can connect to both &lt;code&gt;mongodb&lt;/code&gt; and &lt;code&gt;postgres&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.amazonaws.com%2Fuploads%2Farticles%2Fi2o6kx9bacgyh369srch.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.amazonaws.com%2Fuploads%2Farticles%2Fi2o6kx9bacgyh369srch.png" alt="NodeJS Application Logs" width="769" height="150"&gt;&lt;/a&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.amazonaws.com%2Fuploads%2Farticles%2Fvddvkxb0ba5w4ffk6l8l.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.amazonaws.com%2Fuploads%2Farticles%2Fvddvkxb0ba5w4ffk6l8l.png" alt="NodeJS Application Running" width="607" height="184"&gt;&lt;/a&gt;&lt;br&gt;
In order to run this whole thing using &lt;code&gt;docker-compose&lt;/code&gt;, visit this repo: &lt;a href="https://github.com/fahadfahim13/node-pg-mongo-docker.git" rel="noopener noreferrer"&gt;https://github.com/fahadfahim13/node-pg-mongo-docker.git&lt;/a&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>docker</category>
      <category>postgres</category>
      <category>mongodb</category>
    </item>
    <item>
      <title>Scaling Node.js: Handling 1 Million Requests Like a Pro</title>
      <dc:creator>Fahim Hasnain Fahad</dc:creator>
      <pubDate>Fri, 03 Jan 2025 16:03:34 +0000</pubDate>
      <link>https://dev.to/fahim_hasnain_fahad/how-i-handled-1-million-requests-in-single-nodejs-server-36p9</link>
      <guid>https://dev.to/fahim_hasnain_fahad/how-i-handled-1-million-requests-in-single-nodejs-server-36p9</guid>
      <description>&lt;p&gt;JavaScript is a single threaded, synchronous language. This means when users request to a NodeJS server, it runs on one Core of CPU of the server and doesn't use other cores.&lt;br&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.amazonaws.com%2Fuploads%2Farticles%2Flselxk9en1lyo33sedro.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.amazonaws.com%2Fuploads%2Farticles%2Flselxk9en1lyo33sedro.png" alt="NodeJS Single threaded approach" width="800" height="524"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Requirements
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;Node application that can handle millions of requests in a very short time.&lt;/strong&gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;Each request's response time shouldn't go over a threshold of 500ms.&lt;/strong&gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;System must be fault tolerant.&lt;/strong&gt;&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I found lots of ways to handle this but found really a simple solution with NodeJS's own &lt;code&gt;Cluster module&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It uses all cores of the CPU of server and launches multiple instances of Node application in the same port. There is one main cluster which forks child processes (instances in other cores) and channels requests to the child processes. The child processes handles these requests as a standalone instance. &lt;/p&gt;
&lt;/blockquote&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.amazonaws.com%2Fuploads%2Farticles%2Fmh3wpq6sgjcbp821chxi.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.amazonaws.com%2Fuploads%2Farticles%2Fmh3wpq6sgjcbp821chxi.png" alt="NodeJS Cluster Module" width="800" height="260"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Code Implementation
&lt;/h2&gt;

&lt;p&gt;Create Express application and install dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd project-name
npm init -y 
npm i express mongoose nodemon dotenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  General Approach
&lt;/h3&gt;

&lt;p&gt;Then in the &lt;code&gt;index.js&lt;/code&gt; file, create an usual express application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require('dotenv').config();
const express = require('express');
const connectDB = require('./config/database');

const app = express();

app.use(express.json());

connectDB();

app.use("/api/items", require("./routes/items"));

app.get("/", (req, res) =&amp;gt; {
  res.json({ message: "Welcome to the API" });
});

const PORT = process.env.PORT || 8000;
app.listen(PORT, () =&amp;gt; {
  console.log(`Worker ${process.pid} started - Server running on port ${PORT}`);
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, run the application using &lt;code&gt;nodemon index.js&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;Then, install &lt;code&gt;loadtest&lt;/code&gt; package globally for load testing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g loadtest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now run the loadtest on the local server using this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;loadtest -n 1000000 --rps 10000 http://localhost:8000 #use your port number
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command creates 1M reuests with maximum 10K rps (request per second).&lt;/p&gt;

&lt;p&gt;This is the result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Target URL:          http://localhost:8000
Max requests:        1000000
Target rps:          10000
Concurrent clients:  3805
Running on cores:    6
Agent:               none

Completed requests:  1000000
Total errors:        43446
Total time:          539.523 s
Mean latency:        97.7 ms
Effective rps:       1853

Percentage of requests served within a certain time
  50%      10 ms
  90%      265 ms
  95%      543 ms
  99%      1450 ms
 100%      4509 ms (longest request)

   -1:   43446 errors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can see, almost 44K requests failed to respond.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cluster Module
&lt;/h2&gt;

&lt;p&gt;Let's use &lt;strong&gt;NodeJS Cluster&lt;/strong&gt; Now.&lt;/p&gt;

&lt;p&gt;In the index file, change the code in Cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require('dotenv').config();
const cluster = require('cluster');
const numCPUs = require('os').cpus().length;
const express = require('express');
const connectDB = require('./config/database');

if (cluster.isMaster) {
    console.log(`Master ${process.pid} is running`);
    console.log(`Number of CPUs: ${numCPUs}`);

    // Fork workers
    for (let i = 0; i &amp;lt; numCPUs; i++) {
        cluster.fork();
    }

    cluster.on('exit', (worker, code, signal) =&amp;gt; {
        console.log(`Worker ${worker.process.pid} died`);
        cluster.fork(); // Replace the dead worker
    });
} else {
    const app = express();

    // Middleware
    app.use(express.json());

    // Connect to MongoDB
    connectDB();

    // Routes
    app.use('/api/items', require('./routes/items'));

    // Basic route
    app.get('/', (req, res) =&amp;gt; {
        res.json({ message: 'Welcome to the API' });
    });

    const PORT = process.env.PORT || 8000;
    app.listen(PORT, () =&amp;gt; {
        console.log(`Worker ${process.pid} started - Server running on port ${PORT}`);
    });
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the main Cluster forks the child cluster and uses all available Cores of the CPU.&lt;br&gt;
When we run the application, we can see:&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.amazonaws.com%2Fuploads%2Farticles%2F3cftzz61xwst4wur8o0f.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.amazonaws.com%2Fuploads%2Farticles%2F3cftzz61xwst4wur8o0f.png" alt="NodeJS process run" width="447" height="657"&gt;&lt;/a&gt;&lt;br&gt;
We can see it uses all the cores of the server.&lt;/p&gt;

&lt;p&gt;Now, let's run the &lt;code&gt;loadtest&lt;/code&gt;. We'll see the result like this:&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.amazonaws.com%2Fuploads%2Farticles%2F0osg9gzwxzjdeh43y7de.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.amazonaws.com%2Fuploads%2Farticles%2F0osg9gzwxzjdeh43y7de.png" alt="Load test NodeJS Cluster" width="445" height="346"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see, it got &lt;strong&gt;&lt;em&gt;100% success rate&lt;/em&gt;&lt;/strong&gt; which is crazy! Also, the &lt;strong&gt;mean latency&lt;/strong&gt; came down &lt;strong&gt;&lt;em&gt;to 9.9ms from 97.7ms&lt;/em&gt;&lt;/strong&gt; which is another crazy efficiency. Also, &lt;strong&gt;99% of the requests&lt;/strong&gt; responded success &lt;strong&gt;&lt;em&gt;under 200ms&lt;/em&gt;&lt;/strong&gt; where it took &lt;strong&gt;&lt;em&gt;1.5s previously&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Find the whole codebase in this repo: &lt;code&gt;[https://github.com/fahadfahim13/node-scale.git](https://github.com/fahadfahim13/node-scale.git)&lt;/code&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>cluster</category>
      <category>systemdesign</category>
      <category>loadtesting</category>
    </item>
  </channel>
</rss>
