<?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: aarthirs</title>
    <description>The latest articles on DEV Community by aarthirs (@aarthirs).</description>
    <link>https://dev.to/aarthirs</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1015238%2Fc025455d-255f-45ec-8261-584f71601b8d.jpeg</url>
      <title>DEV Community: aarthirs</title>
      <link>https://dev.to/aarthirs</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aarthirs"/>
    <language>en</language>
    <item>
      <title>From LeetCode to Production: What the Boyer-Moore Voting Algorithm Taught Me</title>
      <dc:creator>aarthirs</dc:creator>
      <pubDate>Tue, 14 Jul 2026 06:47:08 +0000</pubDate>
      <link>https://dev.to/aarthirs/from-leetcode-to-production-what-the-boyer-moore-voting-algorithm-taught-me-100i</link>
      <guid>https://dev.to/aarthirs/from-leetcode-to-production-what-the-boyer-moore-voting-algorithm-taught-me-100i</guid>
      <description>&lt;p&gt;Like many developers, I spend part of my free time solving LeetCode problems. Recently, I came across &lt;a href="https://leetcode.com/submissions/detail/2066868282/" rel="noopener noreferrer"&gt;Majority Element II&lt;/a&gt;, which asks us to find all elements that appear more than &lt;strong&gt;⌊n/3⌋&lt;/strong&gt; times.&lt;/p&gt;

&lt;p&gt;My first instinct was the obvious one—use an &lt;code&gt;unordered_map&lt;/code&gt; to count frequencies.&lt;/p&gt;

&lt;p&gt;It worked.&lt;/p&gt;

&lt;p&gt;It passed every test case.&lt;/p&gt;

&lt;p&gt;Then I noticed the follow-up:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Can you solve it in O(n) time using O(1) extra space?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That single constraint completely changed the way I looked at the problem.&lt;/p&gt;

&lt;p&gt;Instead of asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"How do I count frequencies?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I started asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"How can I identify frequent elements without storing every frequency?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That question led me to the &lt;strong&gt;Boyer-Moore Voting Algorithm&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🤯 The "Wait... How Does This Even Work?" Moment
&lt;/h2&gt;

&lt;p&gt;At first, the algorithm honestly felt like magic.&lt;/p&gt;

&lt;p&gt;How can you find the majority element without actually counting everything?&lt;/p&gt;

&lt;p&gt;The answer is surprisingly elegant.&lt;/p&gt;

&lt;p&gt;Instead of keeping track of every element, we maintain only a few &lt;strong&gt;potential candidates&lt;/strong&gt; along with their counters.&lt;/p&gt;

&lt;p&gt;Whenever we encounter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the same candidate → increase its vote&lt;/li&gt;
&lt;li&gt;a different number while a counter is available → make it the new candidate&lt;/li&gt;
&lt;li&gt;a completely different number while both candidates are active → decrease both counters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of counting frequencies, the algorithm lets different values &lt;strong&gt;cancel each other out&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Imagine every element casting a vote. Whenever two different values compete, they cancel each other's votes. By the end of the first pass, only the elements with enough "support" remain as potential candidates.&lt;/p&gt;

&lt;h3&gt;
  
  
  💡 Key Takeaway
&lt;/h3&gt;

&lt;p&gt;One of the most elegant properties of the Boyer-Moore Voting Algorithm is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;For a problem where an element must appear more than ⌊n/k⌋ times, you only need to track &lt;code&gt;k − 1&lt;/code&gt; candidates.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because there can never be &lt;strong&gt;k distinct elements&lt;/strong&gt;, each occurring more than &lt;strong&gt;⌊n/k⌋&lt;/strong&gt; times. Their combined occurrences would exceed &lt;strong&gt;n&lt;/strong&gt;, which is impossible.&lt;/p&gt;

&lt;p&gt;For &lt;strong&gt;Majority Element II&lt;/strong&gt;, the threshold is &lt;strong&gt;⌊n/3⌋&lt;/strong&gt;, so there can be &lt;strong&gt;at most two majority elements&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That's why we only maintain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;2 candidate buckets&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2 counters&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;instead of storing frequencies for every unique number.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 The Core Idea
&lt;/h2&gt;

&lt;p&gt;The heart of the algorithm looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;candidate1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;count1&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;candidate2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;count2&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count1&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;candidate1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;count1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;candidate2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;count2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;count1&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;count2&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that this &lt;strong&gt;doesn't guarantee&lt;/strong&gt; the candidates are actual majority elements.&lt;/p&gt;

&lt;p&gt;It simply identifies the &lt;strong&gt;most likely candidates&lt;/strong&gt; after all possible cancellations.&lt;/p&gt;

&lt;p&gt;That's why the algorithm performs a &lt;strong&gt;second pass&lt;/strong&gt; to verify whether these candidates actually occur more than &lt;strong&gt;⌊n/3⌋&lt;/strong&gt; times.&lt;/p&gt;

&lt;p&gt;This two-pass approach is what allows Boyer-Moore to achieve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Time Complexity:&lt;/strong&gt; &lt;code&gt;O(n)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Space Complexity:&lt;/strong&gt; &lt;code&gt;O(1)&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🚀 Then I Started Thinking Beyond LeetCode...
&lt;/h2&gt;

&lt;p&gt;Once I understood the algorithm, I realized something interesting.&lt;/p&gt;

&lt;p&gt;The optimization wasn't just about passing an interview.&lt;/p&gt;

&lt;p&gt;It was about &lt;strong&gt;thinking differently when memory is limited&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Imagine you're building a backend service processing &lt;strong&gt;millions of events every second&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You're monitoring:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API requests&lt;/li&gt;
&lt;li&gt;User IDs&lt;/li&gt;
&lt;li&gt;Search queries&lt;/li&gt;
&lt;li&gt;Clickstream events&lt;/li&gt;
&lt;li&gt;Network traffic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keeping a frequency map for every unique value isn't always practical.&lt;/p&gt;

&lt;p&gt;As the number of unique items grows, so does the memory required to store them.&lt;/p&gt;

&lt;p&gt;Instead, modern streaming systems rely on algorithms that summarize data while using a &lt;strong&gt;fixed amount of memory&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The Boyer-Moore Voting Algorithm is a perfect example of this mindset.&lt;/p&gt;

&lt;p&gt;Rather than remembering everything, it continuously filters out less significant data and preserves only the strongest candidates.&lt;/p&gt;

&lt;p&gt;That idea appears repeatedly in large-scale systems where memory is a precious resource.&lt;/p&gt;

&lt;p&gt;Whether it's identifying heavy hitters in a data stream, processing telemetry, or analyzing high-volume events, engineers often prefer algorithms that make intelligent trade-offs instead of storing every detail.&lt;/p&gt;




&lt;h2&gt;
  
  
  💭 What This Problem Actually Taught Me
&lt;/h2&gt;

&lt;p&gt;Before solving this problem, I viewed algorithms as interview questions.&lt;/p&gt;

&lt;p&gt;Now I see them as &lt;strong&gt;engineering decisions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The follow-up constraint wasn't there just to make the question harder.&lt;/p&gt;

&lt;p&gt;It was teaching an important design principle:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Sometimes the smartest solution isn't storing more information—it's figuring out what information you can safely discard.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That realization changed the way I think about optimization.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 My Takeaway
&lt;/h2&gt;

&lt;p&gt;If you're grinding LeetCode, don't stop once you get the green &lt;strong&gt;Accepted&lt;/strong&gt; badge.&lt;/p&gt;

&lt;p&gt;Instead, ask yourself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why does this optimization exist?&lt;/li&gt;
&lt;li&gt;What real-world limitation is it solving?&lt;/li&gt;
&lt;li&gt;Where would this idea actually be useful in production?&lt;/li&gt;
&lt;li&gt;What trade-offs is this algorithm making?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For me, the Boyer-Moore Voting Algorithm wasn't just another optimization problem.&lt;/p&gt;

&lt;p&gt;It became a reminder that great software engineering isn't about using more memory or writing more code.&lt;/p&gt;

&lt;p&gt;It's about building solutions that remain efficient even when the scale grows beyond what brute force can handle.&lt;/p&gt;

&lt;p&gt;Sometimes, one LeetCode problem can teach a system design lesson you'll carry throughout your engineering career.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Have you ever learned an interview algorithm that completely changed how you think about software engineering?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'd love to hear your story in the comments. 👇&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>dsa</category>
      <category>systemdesign</category>
      <category>programming</category>
    </item>
    <item>
      <title>Passion Journal AI - Weekend Challenge</title>
      <dc:creator>aarthirs</dc:creator>
      <pubDate>Sun, 12 Jul 2026 11:28:56 +0000</pubDate>
      <link>https://dev.to/aarthirs/passion-journal-ai-weekend-challenge-6ce</link>
      <guid>https://dev.to/aarthirs/passion-journal-ai-weekend-challenge-6ce</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for &lt;a href="https://dev.to/challenges/weekend-2026-07-09"&gt;Weekend Challenge: Passion Edition&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Passion Journal AI is an AI-powered journaling application that helps users reflect on what they're passionate about.&lt;/p&gt;

&lt;p&gt;Instead of simply storing journal entries, the application analyzes each reflection using Google Gemini AI to identify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Primary Passion&lt;/li&gt;
&lt;li&gt;Mood&lt;/li&gt;
&lt;li&gt;Passion Score&lt;/li&gt;
&lt;li&gt;AI Reflection&lt;/li&gt;
&lt;li&gt;Personalized Goal&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also tracks progress through a modern analytics dashboard with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Weekly trend charts&lt;/li&gt;
&lt;li&gt;Daily streaks&lt;/li&gt;
&lt;li&gt;Previous journal history&lt;/li&gt;
&lt;li&gt;Progress statistics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The idea came from the challenge theme &lt;strong&gt;"Passion."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Passion isn't only about sports or hobbies—it can also be about learning, building, reading, coding, exercising, or anything that motivates us to improve every day.&lt;/p&gt;

&lt;p&gt;I wanted to build an application that encourages users to reflect on those passions instead of letting them fade into everyday routines.&lt;/p&gt;




&lt;h3&gt;
  
  
  Demo
&lt;/h3&gt;

&lt;h2&gt;
  
  
  🌐 Live Application URL : &lt;a href="https://drive.google.com/file/d/184OB0MxEQSwGF6NpWRfj5B6dy2JSIqnH/view?usp=sharing" rel="noopener noreferrer"&gt; Passion_Journal_AI&lt;/a&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Code
&lt;/h3&gt;

&lt;p&gt;GitHub Repository : &lt;a href="https://github.com/aarthirs/PassionJournalAI" rel="noopener noreferrer"&gt;github&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;I built the project as a complete full-stack application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Frontend
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;li&gt;Vite&lt;/li&gt;
&lt;li&gt;Tailwind CSS&lt;/li&gt;
&lt;li&gt;Context API&lt;/li&gt;
&lt;li&gt;Custom Hooks&lt;/li&gt;
&lt;li&gt;Recharts&lt;/li&gt;
&lt;li&gt;Axios&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The dashboard was designed with reusable components to keep the UI modular and maintainable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Backend
&lt;/h3&gt;

&lt;p&gt;The backend uses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node.js&lt;/li&gt;
&lt;li&gt;Express.js&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The server exposes an API that receives journal entries and forwards them to Google Gemini AI.&lt;/p&gt;

&lt;h3&gt;
  
  
  AI Integration
&lt;/h3&gt;

&lt;p&gt;Google Gemini analyzes every journal and returns structured JSON containing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Passion&lt;/li&gt;
&lt;li&gt;Mood&lt;/li&gt;
&lt;li&gt;Passion Score&lt;/li&gt;
&lt;li&gt;Reflection&lt;/li&gt;
&lt;li&gt;Goal&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To make the application more reliable, I also implemented a &lt;strong&gt;rule-based fallback engine&lt;/strong&gt;. If the AI service is unavailable or returns invalid data, the application still generates meaningful insights using keyword analysis.&lt;/p&gt;

&lt;h3&gt;
  
  
  Architecture Decisions
&lt;/h3&gt;

&lt;p&gt;Some design decisions I focused on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Context API for centralized state management&lt;/li&gt;
&lt;li&gt;Reusable service layer for API communication&lt;/li&gt;
&lt;li&gt;Component-based UI architecture&lt;/li&gt;
&lt;li&gt;Local Storage persistence&lt;/li&gt;
&lt;li&gt;Validation before AI requests&lt;/li&gt;
&lt;li&gt;Responsive dashboard layout&lt;/li&gt;
&lt;li&gt;Clean separation between frontend and backend&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Challenges
&lt;/h2&gt;

&lt;p&gt;One interesting challenge was ensuring that AI responses were always usable.&lt;/p&gt;

&lt;p&gt;Large Language Models don't always return perfectly formatted JSON, so I added:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Response validation&lt;/li&gt;
&lt;li&gt;JSON cleanup&lt;/li&gt;
&lt;li&gt;Score normalization&lt;/li&gt;
&lt;li&gt;Fallback rule engine&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This made the application much more resilient.&lt;/p&gt;

&lt;p&gt;Another challenge was designing an interface that presents AI insights without overwhelming the user. I iterated on the layout to balance journaling, analytics, and reflection in a clean dashboard.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;This project helped me gain hands-on experience with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Google Gemini API&lt;/li&gt;
&lt;li&gt;Prompt engineering&lt;/li&gt;
&lt;li&gt;AI response validation&lt;/li&gt;
&lt;li&gt;React Context API&lt;/li&gt;
&lt;li&gt;Dashboard architecture&lt;/li&gt;
&lt;li&gt;Building production-style full-stack applications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More importantly, it reinforced how AI can support personal growth—not by replacing reflection, but by making it more meaningful.&lt;/p&gt;




&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;p&gt;🏆 Best Use of Google AI&lt;/p&gt;

&lt;p&gt;Google Gemini powers the core experience of Passion Journal AI by analyzing journal entries and generating structured insights, reflections, and goals. The application also includes validation and a fallback analysis engine to ensure a reliable user experience.&lt;/p&gt;




&lt;p&gt;Thank you to the DEV team for organizing this challenge. It was a great opportunity to combine AI, full-stack development, and a meaningful theme into one project.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
    <item>
      <title>MongoDB Indexes Finally Clicked for Me: Understanding Indexes, Compound Indexes &amp; the Prefix Rule 🚀</title>
      <dc:creator>aarthirs</dc:creator>
      <pubDate>Wed, 24 Jun 2026 09:34:53 +0000</pubDate>
      <link>https://dev.to/aarthirs/mongodb-indexes-finally-clicked-for-me-understanding-indexes-compound-indexes-the-prefix-rule-1f45</link>
      <guid>https://dev.to/aarthirs/mongodb-indexes-finally-clicked-for-me-understanding-indexes-compound-indexes-the-prefix-rule-1f45</guid>
      <description>&lt;p&gt;While working on a MERN project, I came across these indexes:&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;transactionSchema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;transactionSchema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;transactionSchema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My first reaction was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Why are we creating 3 different indexes for the same schema? Isn't one index enough?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At that time, my understanding was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Indexes help MongoDB find records faster."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Which is true, but it wasn't enough to explain why multiple indexes existed for the same collection.&lt;/p&gt;

&lt;p&gt;That simple doubt led me down a rabbit hole of learning about indexes, compound indexes, how MongoDB stores them, and the famous Prefix Rule.&lt;/p&gt;

&lt;p&gt;Here's what I learned.&lt;/p&gt;




&lt;h1&gt;
  
  
  What is an Index?
&lt;/h1&gt;

&lt;p&gt;Imagine a collection with millions of transactions.&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;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transactions&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;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Aarthi&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;Without an index, MongoDB may need to inspect every document until it finds the matching records.&lt;/p&gt;

&lt;p&gt;This is called a &lt;strong&gt;Collection Scan&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Think of it like searching for a chapter in a book without a table of contents. You'd have to flip through page after page until you find it.&lt;/p&gt;

&lt;p&gt;An index works like a book's table of contents.&lt;/p&gt;

&lt;p&gt;Instead of scanning every document, MongoDB can jump directly to the relevant records.&lt;/p&gt;

&lt;p&gt;Example:&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;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transactions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createIndex&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now MongoDB can quickly locate all transactions belonging to a specific user.&lt;/p&gt;




&lt;h1&gt;
  
  
  What is a Compound Index?
&lt;/h1&gt;

&lt;p&gt;A compound index contains multiple fields.&lt;/p&gt;

&lt;p&gt;Example:&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;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transactions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createIndex&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means MongoDB organizes the index by:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user
  └── date
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Conceptually, it looks something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Aarthi
   2025-08-10
   2025-08-09
   2025-08-08

John
   2025-08-10
   2025-08-05
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The data is first grouped by &lt;code&gt;user&lt;/code&gt;, and within each user, it is ordered by &lt;code&gt;date&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now queries like:&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;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transactions&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;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Aarthi&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;become very efficient.&lt;/p&gt;

&lt;p&gt;MongoDB can jump directly to Aarthi's records and retrieve them in date order.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Prefix Rule: The Concept That Finally Made It Click
&lt;/h1&gt;

&lt;p&gt;Consider this index:&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MongoDB can efficiently use it for:&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="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Aarthi&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;✅ Works&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="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Aarthi&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2025-08-10&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;✅ Works&lt;/p&gt;

&lt;p&gt;But:&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="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2025-08-10&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;❌ Not efficient&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because the index is organized by &lt;code&gt;user&lt;/code&gt; first and then by &lt;code&gt;date&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;MongoDB knows where each user's records start, but it doesn't know where a specific date begins without first navigating through the user groups.&lt;/p&gt;

&lt;p&gt;This behavior is known as the &lt;strong&gt;Prefix Rule&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A compound index can efficiently support queries that start from the leftmost fields of the index.&lt;/p&gt;

&lt;p&gt;For example:&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;can efficiently support:&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="nf"&gt;find&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="nf"&gt;find&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;date&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="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But not:&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="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;date&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="nx"&gt;type&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="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;because those queries do not start from the leftmost field.&lt;/p&gt;




&lt;h1&gt;
  
  
  Back to My Original Doubt
&lt;/h1&gt;

&lt;p&gt;I originally saw:&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;transactionSchema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;transactionSchema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;transactionSchema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now it makes sense.&lt;/p&gt;

&lt;h3&gt;
  
  
  Recent Transactions
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;find&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="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Uses:&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="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Filter By Transaction Type
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;find&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="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="s2"&gt;expense&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;Uses:&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="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Filter By Category
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;find&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="na"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;food&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;Uses:&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="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each index is optimized for a different query pattern.&lt;/p&gt;




&lt;h1&gt;
  
  
  Another Question I Had: Where Are Indexes Stored?
&lt;/h1&gt;

&lt;p&gt;Initially, I thought indexes somehow reorganized the actual documents.&lt;/p&gt;

&lt;p&gt;But that's not what happens.&lt;/p&gt;

&lt;p&gt;MongoDB stores documents and indexes separately.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Collection
-----------
Doc1
Doc2
Doc3
Doc4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And separately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Index(user,date)
----------------
Aarthi -&amp;gt; Doc5
Aarthi -&amp;gt; Doc2
Aarthi -&amp;gt; Doc1

Rosy -&amp;gt; Doc8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Index(user,type)
----------------
Aarthi -&amp;gt; expense -&amp;gt; Doc1
Aarthi -&amp;gt; income  -&amp;gt; Doc2

Rosy -&amp;gt; expense -&amp;gt; Doc8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Index(user,category)
--------------------
Aarthi -&amp;gt; food -&amp;gt; Doc1
Aarthi -&amp;gt; travel -&amp;gt; Doc2

Rosy -&amp;gt; food -&amp;gt; Doc8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The actual documents remain unchanged.&lt;/p&gt;

&lt;p&gt;Indexes are separate data structures that contain references to documents.&lt;/p&gt;




&lt;h1&gt;
  
  
  Then Why Do We Need &lt;code&gt;.sort()&lt;/code&gt; If the Index Is Already Sorted?
&lt;/h1&gt;

&lt;p&gt;This confused me too.&lt;/p&gt;

&lt;p&gt;Suppose we have:&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The index itself is sorted.&lt;/p&gt;

&lt;p&gt;However, MongoDB does not guarantee that results should be returned in date order unless we explicitly request it.&lt;/p&gt;

&lt;p&gt;For example:&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;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transactions&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;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Aarthi&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;This may use the index to locate records quickly.&lt;/p&gt;

&lt;p&gt;But:&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;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transactions&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;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Aarthi&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;tells MongoDB:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Return these records in descending date order."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Since the index is already sorted that way, MongoDB can use the index directly and avoid an expensive in-memory sort.&lt;/p&gt;

&lt;p&gt;That's one of the biggest performance benefits of compound indexes.&lt;/p&gt;




&lt;h1&gt;
  
  
  How Does MongoDB Handle Multiple Indexes?
&lt;/h1&gt;

&lt;p&gt;This was another question I had.&lt;/p&gt;

&lt;p&gt;Suppose we have:&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="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MongoDB creates three completely separate index structures.&lt;/p&gt;

&lt;p&gt;Think of them as three separate books:&lt;/p&gt;

&lt;h3&gt;
  
  
  Index 1
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Aarthi
  2025-08-10
  2025-08-09

Rosy
  2025-08-10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Index 2
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Aarthi
  expense
  income

Rosy
  expense
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Index 3
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Aarthi
  food
  travel

Rosy
  shopping
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a query arrives, MongoDB's query planner decides which index can answer the query most efficiently.&lt;/p&gt;

&lt;p&gt;Example:&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="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Aarthi&lt;/span&gt;&lt;span class="dl"&gt;"&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="s2"&gt;expense&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;MongoDB sees:&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="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and chooses that index.&lt;/p&gt;

&lt;p&gt;For:&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="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Aarthi&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MongoDB chooses:&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="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;because it perfectly matches the query.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why Not Create One Huge Index?
&lt;/h1&gt;

&lt;p&gt;I also wondered:&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wouldn't this solve everything?&lt;/p&gt;

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

&lt;p&gt;Because of the Prefix Rule.&lt;/p&gt;

&lt;p&gt;This index efficiently supports:&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="nf"&gt;find&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="nf"&gt;find&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;date&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="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But:&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="nf"&gt;find&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;category&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is not optimal because &lt;code&gt;date&lt;/code&gt; and &lt;code&gt;type&lt;/code&gt; appear before &lt;code&gt;category&lt;/code&gt; in the index definition.&lt;/p&gt;

&lt;p&gt;MongoDB cannot efficiently skip the middle fields.&lt;/p&gt;

&lt;p&gt;That's why index design should follow actual query patterns rather than simply including every field.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Trade-Off Most Beginners Miss
&lt;/h1&gt;

&lt;p&gt;Indexes speed up reads.&lt;/p&gt;

&lt;p&gt;But they are not free.&lt;/p&gt;

&lt;p&gt;Every insert, update, or delete must also update all related indexes.&lt;/p&gt;

&lt;p&gt;For example, when inserting:&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Aarthi&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2025-08-10&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;expense&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;food&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;MongoDB must update:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Index(user,date)

Index(user,type)

Index(user,category)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;every single time.&lt;/p&gt;

&lt;p&gt;So indexes improve read performance at the cost of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Additional storage&lt;/li&gt;
&lt;li&gt;Slower writes&lt;/li&gt;
&lt;li&gt;Extra maintenance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the classic database trade-off.&lt;/p&gt;




&lt;h1&gt;
  
  
  My Biggest Takeaway
&lt;/h1&gt;

&lt;p&gt;Before this, I thought:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Indexes make queries faster."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now I think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Indexes make specific query patterns faster."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Understanding compound indexes, how MongoDB stores them, and the Prefix Rule completely changed the way I think about database design.&lt;/p&gt;

&lt;p&gt;The best index is not the one with the most fields.&lt;/p&gt;

&lt;p&gt;The best index is the one that matches the queries your application runs most often.&lt;/p&gt;

&lt;p&gt;Sometimes a simple question like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Why do we have 3 indexes for the same schema?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;can lead to understanding an entire database concept.&lt;/p&gt;

&lt;p&gt;If you've had a similar "aha!" moment while learning databases, I'd love to hear it in the comments.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>mongodb</category>
      <category>backend</category>
      <category>database</category>
    </item>
    <item>
      <title>JavaScript Promises &amp; Async/Await Explained with a Real-Life Example 🍕</title>
      <dc:creator>aarthirs</dc:creator>
      <pubDate>Mon, 15 Jun 2026 16:15:42 +0000</pubDate>
      <link>https://dev.to/aarthirs/javascript-promises-asyncawait-explained-with-a-real-life-example-43bm</link>
      <guid>https://dev.to/aarthirs/javascript-promises-asyncawait-explained-with-a-real-life-example-43bm</guid>
      <description>&lt;p&gt;In my previous post, &lt;a href="https://dev.to/aarthirs/-javascript-async-explained-like-a-grocery-store-4men"&gt;&lt;strong&gt;"JavaScript Async Explained Like a Grocery Store 🛒"&lt;/strong&gt;&lt;/a&gt;, I covered how the Call Stack, Browser APIs, Event Loop, and Queues work together to handle asynchronous operations.&lt;/p&gt;

&lt;p&gt;In this post, we'll answer the next set of questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why do Promises exist?&lt;/li&gt;
&lt;li&gt;How does &lt;code&gt;fetch()&lt;/code&gt; return data if the API call takes time?&lt;/li&gt;
&lt;li&gt;What exactly does &lt;code&gt;.then()&lt;/code&gt; do?&lt;/li&gt;
&lt;li&gt;Why was &lt;code&gt;async/await&lt;/code&gt; introduced?&lt;/li&gt;
&lt;li&gt;Does &lt;code&gt;await&lt;/code&gt; block JavaScript?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's dive in.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem: Waiting Is Expensive
&lt;/h2&gt;

&lt;p&gt;Imagine ordering a pizza online.&lt;/p&gt;

&lt;p&gt;After placing the order, would you stand at the door doing absolutely nothing until the delivery arrives?&lt;/p&gt;

&lt;p&gt;Probably not.&lt;/p&gt;

&lt;p&gt;You would continue:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Watching YouTube&lt;/li&gt;
&lt;li&gt;Working&lt;/li&gt;
&lt;li&gt;Talking to friends&lt;/li&gt;
&lt;li&gt;Doing other tasks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When the pizza arrives, you'll handle it.&lt;/p&gt;

&lt;p&gt;JavaScript behaves the same way.&lt;/p&gt;

&lt;p&gt;Operations like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API requests&lt;/li&gt;
&lt;li&gt;Database calls&lt;/li&gt;
&lt;li&gt;File operations&lt;/li&gt;
&lt;li&gt;Timers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;can take seconds to complete.&lt;/p&gt;

&lt;p&gt;If JavaScript waited for each operation to finish, your application would freeze.&lt;/p&gt;

&lt;p&gt;Instead, JavaScript continues executing other code while waiting for the result.&lt;/p&gt;




&lt;h2&gt;
  
  
  Enter Promises
&lt;/h2&gt;

&lt;p&gt;A Promise represents a value that will be available sometime in the future.&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;promise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/users&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;At this moment, the user data isn't available yet.&lt;/p&gt;

&lt;p&gt;The Promise is basically saying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I don't have the result right now, but I'll let you know when it's ready."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A Promise can be in one of three states:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pending
   ↓
Fulfilled (Success)

OR

Rejected (Failure)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Where is &lt;code&gt;new Promise()&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;One question confused me when I first learned Promises.&lt;/p&gt;

&lt;p&gt;If Promises are important, why don't I see this everywhere?&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;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&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;// async work&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead, I often see:&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="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&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="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reason is simple:&lt;/p&gt;

&lt;p&gt;Most modern APIs already return Promises for us.&lt;/p&gt;

&lt;p&gt;For example:&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="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/users&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;already returns a Promise.&lt;/p&gt;

&lt;p&gt;Conceptually, it works something like this:&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;function&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&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;// Browser performs request&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;success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;reject&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="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser creates the Promise.&lt;/p&gt;

&lt;p&gt;We simply consume it.&lt;/p&gt;




&lt;h2&gt;
  
  
  So What Does &lt;code&gt;.then()&lt;/code&gt; Actually Do?
&lt;/h2&gt;

&lt;p&gt;Consider:&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="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&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="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="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;Many beginners think &lt;code&gt;.then()&lt;/code&gt; somehow retrieves the data.&lt;/p&gt;

&lt;p&gt;That's not really what's happening.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;.then()&lt;/code&gt; simply registers a callback function.&lt;/p&gt;

&lt;p&gt;You're telling JavaScript:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"When this Promise successfully finishes, run this function."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Think of it like a food delivery app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Order food
      ↓
Food arrives
      ↓
Call me
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;orderFood&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;eatFood&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The callback doesn't run immediately.&lt;/p&gt;

&lt;p&gt;It waits until the Promise resolves.&lt;/p&gt;




&lt;h2&gt;
  
  
  Promise Chaining
&lt;/h2&gt;

&lt;p&gt;Let's say we need:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User data&lt;/li&gt;
&lt;li&gt;User posts&lt;/li&gt;
&lt;li&gt;User comments&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A common approach is:&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="nf"&gt;fetchUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;fetchPosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;fetchComments&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;comments&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;comments&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;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="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;This works perfectly.&lt;/p&gt;

&lt;p&gt;But as applications grow, chains become harder to read and maintain.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Async/Await Was Introduced
&lt;/h2&gt;

&lt;p&gt;Async/Await solves the readability problem.&lt;/p&gt;

&lt;p&gt;Instead of:&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="nf"&gt;fetchUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;fetchPosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;posts&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;we can write:&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getData&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;user&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;fetchUser&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;posts&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;fetchPosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;posts&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 feels much closer to normal synchronous code.&lt;/p&gt;

&lt;p&gt;The logic becomes easier to follow.&lt;/p&gt;




&lt;h2&gt;
  
  
  Does &lt;code&gt;await&lt;/code&gt; Block JavaScript?
&lt;/h2&gt;

&lt;p&gt;One of the most common interview questions.&lt;/p&gt;

&lt;p&gt;Consider:&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;demo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;B&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;demo&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;C&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;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A
C
B
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Many developers initially expect:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A
B
C
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But that's not what happens.&lt;/p&gt;

&lt;p&gt;When JavaScript reaches:&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;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/users&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;it pauses only the current async function.&lt;/p&gt;

&lt;p&gt;The rest of the application keeps running.&lt;/p&gt;

&lt;p&gt;So the flow becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A
Pause async function
C
API finishes
Resume async function
B
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is why &lt;code&gt;await&lt;/code&gt; does &lt;strong&gt;not&lt;/strong&gt; block JavaScript.&lt;/p&gt;

&lt;p&gt;It only pauses that specific function.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Happens Under the Hood?
&lt;/h2&gt;

&lt;p&gt;This code:&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getData&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;data&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;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="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;is roughly equivalent to:&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;function&lt;/span&gt; &lt;span class="nf"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&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="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the key idea.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Async/Await is built on top of Promises.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The Promise mechanism still does all the work.&lt;/p&gt;

&lt;p&gt;Async/Await simply provides a cleaner syntax.&lt;/p&gt;




&lt;h2&gt;
  
  
  Mental Models That Help Me Remember
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Promise
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The food is on the way.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  fetch()
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Place an online order.
Returns a Promise immediately.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  .then()
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;When the food arrives,
call me.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  await
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I'll wait here for the food,
but everyone else can continue working.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  async function
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This function may contain waiting points.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Bonus: Quick Interview Answers !!
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is a Promise?
&lt;/h3&gt;

&lt;p&gt;A Promise is an object representing the eventual success or failure of an asynchronous operation.&lt;/p&gt;

&lt;h3&gt;
  
  
  What does &lt;code&gt;.then()&lt;/code&gt; do?
&lt;/h3&gt;

&lt;p&gt;It registers a callback that executes when a Promise resolves successfully.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why does &lt;code&gt;fetch()&lt;/code&gt; work with &lt;code&gt;.then()&lt;/code&gt;?
&lt;/h3&gt;

&lt;p&gt;Because &lt;code&gt;fetch()&lt;/code&gt; already returns a Promise.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does &lt;code&gt;await&lt;/code&gt; block JavaScript?
&lt;/h3&gt;

&lt;p&gt;No. It pauses only the current async function.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why was Async/Await introduced?
&lt;/h3&gt;

&lt;p&gt;To make asynchronous code easier to read and maintain compared to Promise chaining.&lt;/p&gt;

&lt;h3&gt;
  
  
  Async/Await vs Promises?
&lt;/h3&gt;

&lt;p&gt;Async/Await is syntactic sugar built on top of Promises.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Takeaway
&lt;/h2&gt;

&lt;p&gt;Whenever I think about asynchronous JavaScript, I remember this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Promise = Future Value

fetch() = Returns a Promise

.then() = Call me when ready

await = Pause this function, not JavaScript

async/await = Cleaner Promise syntax
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once these five ideas click, Promises and Async/Await become much easier to understand.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
    </item>
    <item>
      <title># JavaScript Async Explained Like a Grocery Store 🛒</title>
      <dc:creator>aarthirs</dc:creator>
      <pubDate>Sat, 13 Jun 2026 07:32:12 +0000</pubDate>
      <link>https://dev.to/aarthirs/-javascript-async-explained-like-a-grocery-store-4men</link>
      <guid>https://dev.to/aarthirs/-javascript-async-explained-like-a-grocery-store-4men</guid>
      <description>&lt;p&gt;When I first learned JavaScript's Event Loop, I kept reading explanations like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Asynchronous tasks are offloaded to Web APIs and their callbacks are placed into the Microtask Queue or Macrotask Queue."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I memorized the words.&lt;/p&gt;

&lt;p&gt;But I didn't actually understand what was happening.&lt;/p&gt;

&lt;p&gt;Then I started thinking about JavaScript like a grocery store.&lt;/p&gt;

&lt;h2&gt;
  
  
  JavaScript = One Cashier
&lt;/h2&gt;

&lt;p&gt;Imagine a store with only one cashier.&lt;/p&gt;

&lt;p&gt;The cashier can only serve one customer at a time.&lt;/p&gt;

&lt;p&gt;That's JavaScript.&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="s2"&gt;`console.log("A");
console.log("B");
console.log("C");`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A
B
C
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple. One task after another.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Now imagine a customer says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Wait 5 seconds before helping the next customer."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If the cashier literally waited 5 seconds, the entire store would stop moving.&lt;/p&gt;

&lt;p&gt;That's exactly what would happen if JavaScript handled timers itself.&lt;/p&gt;




&lt;h2&gt;
  
  
  Browser Web APIs = Helpers
&lt;/h2&gt;

&lt;p&gt;Instead, JavaScript asks a helper:&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="s2"&gt;`setTimeout(() =&amp;gt; {
  console.log("Hello");
}, 5000);`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;blockquote&gt;
&lt;p&gt;"Hey Browser, can you watch this timer for me?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The browser helper takes the job.&lt;/p&gt;

&lt;p&gt;JavaScript immediately continues working.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Start
End
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After 5 seconds, the helper comes back and says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The timer finished."&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Callback Queue = Waiting Line
&lt;/h2&gt;

&lt;p&gt;The browser cannot interrupt JavaScript directly.&lt;/p&gt;

&lt;p&gt;So it places the callback into a waiting line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser Helper
      ↓
Callback Queue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The callback waits until JavaScript is free.&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%2Flsousoazh9iw7uffqq40.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%2Flsousoazh9iw7uffqq40.png" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Event Loop = Store Manager
&lt;/h2&gt;

&lt;p&gt;The Event Loop is like a manager constantly checking:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Is the cashier busy?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If yes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Wait
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If no:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Take the next customer from the waiting line
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's all the Event Loop does.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Does Promise Run Before setTimeout?
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="s2"&gt;`console.log("Start");

setTimeout(() =&amp;gt; {
  console.log("Timeout");
}, 0);

Promise.resolve().then(() =&amp;gt; {
  console.log("Promise");
});

console.log("End");`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Start
End
Promise
Timeout
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because JavaScript has two waiting lines:&lt;/p&gt;

&lt;h3&gt;
  
  
  High Priority Line
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Promise.then()&lt;/li&gt;
&lt;li&gt;queueMicrotask()&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Normal Line
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;setTimeout()&lt;/li&gt;
&lt;li&gt;setInterval()&lt;/li&gt;
&lt;li&gt;DOM events&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Event Loop always clears the high-priority line first.&lt;/p&gt;

&lt;p&gt;That's why Promise executes before setTimeout.&lt;/p&gt;




&lt;h2&gt;
  
  
  What About fetch()?
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="s2"&gt;`fetch("/users")
  .then(res =&amp;gt; res.json())
  .then(data =&amp;gt; console.log(data));`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser handles the network request.&lt;/p&gt;

&lt;p&gt;JavaScript doesn't sit around waiting for the server.&lt;/p&gt;

&lt;p&gt;Once the response arrives, the callback gets added to the queue and runs when JavaScript is ready.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Do Web Workers Exist?
&lt;/h2&gt;

&lt;p&gt;Imagine the cashier receives a task that takes 10 minutes.&lt;/p&gt;

&lt;p&gt;Nobody else gets served.&lt;/p&gt;

&lt;p&gt;The store freezes.&lt;/p&gt;

&lt;p&gt;That's what happens when JavaScript performs heavy calculations on the main thread.&lt;/p&gt;

&lt;p&gt;Web Workers solve this by hiring another cashier.&lt;/p&gt;

&lt;p&gt;Heavy work runs on a separate thread while the main UI remains responsive.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Mental Model
&lt;/h2&gt;

&lt;p&gt;Whenever you see async JavaScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;JavaScript = Cashier

Browser Web APIs = Helpers

Callback Queue = Waiting Line

Event Loop = Manager

Web Workers = Extra Cashiers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once this model clicks, the Event Loop becomes much easier to understand than memorizing definitions.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title># The Turing Dial: A Solstice Cryptography Protocol</title>
      <dc:creator>aarthirs</dc:creator>
      <pubDate>Sun, 07 Jun 2026 15:19:26 +0000</pubDate>
      <link>https://dev.to/aarthirs/-the-turing-dial-a-solstice-cryptography-protocol-4na3</link>
      <guid>https://dev.to/aarthirs/-the-turing-dial-a-solstice-cryptography-protocol-4na3</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/june-game-jam-2026-06-03"&gt;June Solstice Game Jam&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fznimz7q8l3fn2lxj1kp1.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%2Fznimz7q8l3fn2lxj1kp1.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;How It Works (The Theme Connection)&lt;br&gt;
The game maps the physical passage of time during the Solstice to computational logic constraints. As the game clock cycles from day to night, your processing framework degrades across three environmental phases:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Sunrise (Unary):&lt;/strong&gt; Pure binary processing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High Noon (Boolean):&lt;/strong&gt; Advanced algebraic logic gates (&lt;code&gt;AND&lt;/code&gt;, &lt;code&gt;OR&lt;/code&gt;, &lt;code&gt;NOT&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Midnight (Enigma):&lt;/strong&gt; Hard cryptographic bit-parity challenges that honor Turing's codebreaking at Bletchley Park.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Behind the Curtain: Best Google AI Usage
&lt;/h2&gt;

&lt;p&gt;Instead of using the Gemini API as a simple chat box, &lt;strong&gt;Gemini 2.5 Flash acts as our automated Procedural Level Designer&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Every time the environment transitions, the system fires a background request to Google AI Studio. Gemini dynamically parses the current game state and feeds back:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A unique, context-aware matrix puzzle directive (&lt;code&gt;puzzleHint&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The dynamic numeric or parity solution ruleset (&lt;code&gt;solutionKey&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;A curated, inspiring quote reflecting Alan Turing's legacy, Juneteenth, or Pride Month (&lt;code&gt;historyQuote&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the network connection ever fails, a native hardware fallback loop steps in to ensure seamless offline gameplay.&lt;/p&gt;

&lt;h2&gt;
  
  
  Built With
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Pure HTML5 / CSS Grid (with a custom CRT scanline terminal effect)&lt;/li&gt;
&lt;li&gt;Modular Vanilla JavaScript&lt;/li&gt;
&lt;li&gt;Official &lt;code&gt;@google/genai&lt;/code&gt; SDK via CDN&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Play the Game
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Repository:&lt;/strong&gt; &lt;a href="https://github.com/aarthirs/TuningGame/tree/main" rel="noopener noreferrer"&gt;github&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Live Demo:&lt;/strong&gt;&lt;a href="https://drive.google.com/file/d/1SFsWIch1x5SUnw9MUWEV2DISnNCjnZUs/view?usp=sharing" rel="noopener noreferrer"&gt;vid demo&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>gamechallenge</category>
      <category>gamedev</category>
    </item>
  </channel>
</rss>
