<?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: Tanu Priya</title>
    <description>The latest articles on DEV Community by Tanu Priya (@tanu_priya).</description>
    <link>https://dev.to/tanu_priya</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%2F4073510%2F9e5a8f12-290d-4fb5-b80e-0b5e53c01a70.png</url>
      <title>DEV Community: Tanu Priya</title>
      <link>https://dev.to/tanu_priya</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tanu_priya"/>
    <language>en</language>
    <item>
      <title>What Really Happens When You Search Something on Google?</title>
      <dc:creator>Tanu Priya</dc:creator>
      <pubDate>Mon, 21 Sep 2026 06:33:32 +0000</pubDate>
      <link>https://dev.to/tanu_priya/what-really-happens-when-you-search-something-on-google-1m88</link>
      <guid>https://dev.to/tanu_priya/what-really-happens-when-you-search-something-on-google-1m88</guid>
      <description>&lt;p&gt;You type:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“How does Netflix recommend movies?”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You press &lt;strong&gt;Enter&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Within a fraction of a second, Google shows millions of possible results, advertisements, images, videos, maps, and sometimes an AI-generated answer.&lt;/p&gt;

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

&lt;p&gt;But a lot happens between pressing &lt;strong&gt;Enter&lt;/strong&gt; and seeing that results page.&lt;/p&gt;

&lt;p&gt;Your request has to travel across the internet, reach Google's infrastructure, be interpreted, matched against an enormous search index, ranked, filtered, and finally turned into a response.&lt;/p&gt;

&lt;p&gt;So, what actually happens when you search something on Google?&lt;/p&gt;

&lt;p&gt;Let's follow the journey.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Big Picture
&lt;/h2&gt;

&lt;p&gt;At a high level, a Google search looks 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;You type a query
       ↓
Browser sends request
       ↓
DNS + Network
       ↓
Google receives request
       ↓
Query understanding
       ↓
Search index lookup
       ↓
Candidate retrieval
       ↓
Ranking
       ↓
Personalization &amp;amp; context
       ↓
Search result generation
       ↓
Response sent to browser
       ↓
You see the results
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And importantly, Google isn't searching the entire internet at that moment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It is searching its index of the web.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That's one of the most important concepts to understand.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. You Type a Search Query
&lt;/h2&gt;

&lt;p&gt;Suppose you search:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;how does netflix recommendation system work
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your browser needs to send that query to Google's servers.&lt;/p&gt;

&lt;p&gt;But before the request can even reach Google, your computer has to figure out where Google's servers are located.&lt;/p&gt;

&lt;p&gt;That's where &lt;strong&gt;DNS&lt;/strong&gt; comes in.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. DNS Finds Google
&lt;/h2&gt;

&lt;p&gt;Your browser needs an IP address to communicate with Google's infrastructure.&lt;/p&gt;

&lt;p&gt;You entered:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;google.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But computers communicate using IP addresses.&lt;/p&gt;

&lt;p&gt;So your system asks DNS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What IP address should I use for google.com?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The DNS resolution process may involve:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser cache
      ↓
Operating system cache
      ↓
Router / DNS resolver
      ↓
DNS infrastructure
      ↓
Google's IP address
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once an appropriate IP address is available, your browser can establish a connection.&lt;/p&gt;

&lt;p&gt;This is similar to looking up someone's phone number before calling them.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Your Request Travels Across the Internet
&lt;/h2&gt;

&lt;p&gt;Your search request now needs to travel from your device to Google's infrastructure.&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;Your Computer
     ↓
Wi-Fi / Ethernet
     ↓
Router
     ↓
ISP
     ↓
Internet
     ↓
Google Infrastructure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The request isn't necessarily traveling through one fixed path.&lt;/p&gt;

&lt;p&gt;Internet routing systems dynamically determine how packets should move through networks.&lt;/p&gt;

&lt;p&gt;Your query might travel through multiple routers and networks before reaching Google's infrastructure.&lt;/p&gt;

&lt;p&gt;And all of this happens extremely quickly.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. HTTPS Protects the Connection
&lt;/h2&gt;

&lt;p&gt;Modern Google Search uses HTTPS.&lt;/p&gt;

&lt;p&gt;Instead of sending the request as plain text, the connection is encrypted using &lt;strong&gt;TLS&lt;/strong&gt;.&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;Browser
   │
   │ Encrypted HTTPS
   ▼
Google
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This helps protect data while it travels between your browser and Google's servers.&lt;/p&gt;

&lt;p&gt;An important distinction:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Encryption protects the communication channel.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It doesn't mean Google doesn't know what you searched for. Google needs to process the query in order to return search results.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Google's Frontend Receives Your Request
&lt;/h2&gt;

&lt;p&gt;Your request reaches Google's infrastructure.&lt;/p&gt;

&lt;p&gt;But Google isn't running everything from one giant server.&lt;/p&gt;

&lt;p&gt;Instead, Google operates enormous distributed infrastructure across many locations.&lt;/p&gt;

&lt;p&gt;A simplified architecture might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                Google
                   │
            Load Balancing
                   │
        ┌──────────┼──────────┐
        ↓          ↓          ↓
      Server     Server     Server
        │          │          │
        └──────────┼──────────┘
                   ↓
          Search Infrastructure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The request can be routed to an appropriate Google server or cluster.&lt;/p&gt;

&lt;p&gt;This is one reason large-scale systems rely heavily on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Load balancing&lt;/li&gt;
&lt;li&gt;Distributed systems&lt;/li&gt;
&lt;li&gt;Caching&lt;/li&gt;
&lt;li&gt;Replication&lt;/li&gt;
&lt;li&gt;Geographic distribution&lt;/li&gt;
&lt;li&gt;Fault tolerance&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  6. Google Has Already Crawled the Web
&lt;/h2&gt;

&lt;p&gt;Here's where things get interesting.&lt;/p&gt;

&lt;p&gt;When you search Google, Google usually isn't visiting websites one by one at that exact moment.&lt;/p&gt;

&lt;p&gt;Instead, Google maintains a massive &lt;strong&gt;search index&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Think about the difference between these two approaches.&lt;/p&gt;

&lt;h3&gt;
  
  
  Approach 1: Search the internet live
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Search
  ↓
Visit website 1
  ↓
Visit website 2
  ↓
Visit website 3
  ↓
...
  ↓
Return results
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This would be incredibly slow.&lt;/p&gt;

&lt;h3&gt;
  
  
  Approach 2: Search an index
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Internet
   ↓
Crawlers
   ↓
Processed documents
   ↓
Search Index
   ↓
Your Query
   ↓
Results
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is dramatically faster.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Googlebot Crawls Websites
&lt;/h2&gt;

&lt;p&gt;Google uses automated crawlers to discover and revisit web pages.&lt;/p&gt;

&lt;p&gt;One well-known crawler is &lt;strong&gt;Googlebot&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The crawler can discover pages through:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Links
Sitemaps
Previously known URLs
Other discovery mechanisms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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;example.com
      │
      ├── /blog
      │
      ├── /products
      │
      └── /about
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Google's crawlers can discover these pages and retrieve their content.&lt;/p&gt;

&lt;p&gt;But crawling isn't the same thing as ranking.&lt;/p&gt;

&lt;p&gt;That's an important distinction.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Crawling
   ↓
Discover content

Indexing
   ↓
Understand and store content

Ranking
   ↓
Determine which results are useful for a query
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  8. Google Builds a Search Index
&lt;/h2&gt;

&lt;p&gt;Imagine trying to search through the entire internet every time someone enters a query.&lt;/p&gt;

&lt;p&gt;That wouldn't scale.&lt;/p&gt;

&lt;p&gt;Instead, Google builds and maintains an enormous index.&lt;/p&gt;

&lt;p&gt;A simplified representation might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"react"
   ↓
Document A
Document B
Document C
Document D

"next.js"
   ↓
Document B
Document E
Document F

"server components"
   ↓
Document A
Document E
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This resembles the idea of an &lt;strong&gt;inverted index&lt;/strong&gt;.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Which words exist inside this document?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The search system can efficiently answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Which documents contain these words?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This dramatically reduces the amount of work needed during a search.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. Your Query Gets Understood
&lt;/h2&gt;

&lt;p&gt;Now Google has your query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;how does netflix recommendation system work
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The system doesn't simply treat this as five independent words.&lt;/p&gt;

&lt;p&gt;It tries to understand the &lt;strong&gt;meaning and intent&lt;/strong&gt; behind the query.&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 plaintext"&gt;&lt;code&gt;how does netflix recommendation system work
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;could be interpreted as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Topic:
Netflix recommendation systems

Intent:
Learn / understand

Expected content:
Technical explanation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Search systems use sophisticated language understanding techniques to interpret queries.&lt;/p&gt;

&lt;p&gt;This is especially important for natural-language searches.&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 plaintext"&gt;&lt;code&gt;"best laptop for programming"

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

&lt;/div&gt;



&lt;p&gt;is very different from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"laptop programming error"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even though they share some words, the intent is different.&lt;/p&gt;




&lt;h2&gt;
  
  
  10. Query Rewriting Can Happen
&lt;/h2&gt;

&lt;p&gt;Search engines may also transform or expand the query internally.&lt;/p&gt;

&lt;p&gt;For example, a user might search:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;how fast is js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The system may understand that:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;and interpret the query accordingly.&lt;/p&gt;

&lt;p&gt;Similarly, spelling mistakes, synonyms, entities, and related concepts can influence how a query is processed.&lt;/p&gt;

&lt;p&gt;The goal is not simply:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Find pages containing these exact words.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The goal is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Find information that best satisfies what the user is trying to find.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  11. Google Searches the Index
&lt;/h2&gt;

&lt;p&gt;Now the search system needs to find potentially relevant documents.&lt;/p&gt;

&lt;p&gt;Suppose Google's index contains billions of documents.&lt;/p&gt;

&lt;p&gt;It doesn't want to rank every document individually for every query.&lt;/p&gt;

&lt;p&gt;That would be computationally expensive.&lt;/p&gt;

&lt;p&gt;Instead, search systems typically use a multi-stage process.&lt;/p&gt;

&lt;p&gt;A simplified model looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Query
  ↓
Candidate Retrieval
  ↓
Thousands of Candidates
  ↓
Ranking
  ↓
Top Candidates
  ↓
Final Result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first stage finds potentially relevant documents.&lt;/p&gt;

&lt;p&gt;The next stages determine which ones deserve higher placement.&lt;/p&gt;




&lt;h2&gt;
  
  
  12. Candidate Retrieval
&lt;/h2&gt;

&lt;p&gt;Imagine your query is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;how does a CDN work
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The search system may quickly identify a large set of potentially relevant documents.&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 plaintext"&gt;&lt;code&gt;10,000 potentially relevant documents
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The system then narrows this down.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10,000
   ↓
1,000
   ↓
100
   ↓
20
   ↓
10 results
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These numbers are only illustrative.&lt;/p&gt;

&lt;p&gt;The important concept is &lt;strong&gt;retrieval before final ranking&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This architecture allows large-scale search systems to operate efficiently.&lt;/p&gt;




&lt;h2&gt;
  
  
  13. Ranking Determines the Order
&lt;/h2&gt;

&lt;p&gt;Finding relevant documents isn't enough.&lt;/p&gt;

&lt;p&gt;Google also needs to decide:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Which results should appear first?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is the ranking problem.&lt;/p&gt;

&lt;p&gt;Many signals can influence ranking, depending on the query and search context.&lt;/p&gt;

&lt;p&gt;Examples can include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Relevance&lt;/li&gt;
&lt;li&gt;Content quality&lt;/li&gt;
&lt;li&gt;Page experience&lt;/li&gt;
&lt;li&gt;Freshness&lt;/li&gt;
&lt;li&gt;Authority&lt;/li&gt;
&lt;li&gt;Language&lt;/li&gt;
&lt;li&gt;Location&lt;/li&gt;
&lt;li&gt;Query intent&lt;/li&gt;
&lt;li&gt;Search context&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Google has many ranking systems rather than one simple formula.&lt;/p&gt;

&lt;p&gt;A useful mental model is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Query
  +
Content
  +
Context
  +
Many ranking signals
       ↓
Ranking systems
       ↓
Ordered results
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact weighting and implementation of ranking systems are not publicly disclosed in full.&lt;/p&gt;




&lt;h2&gt;
  
  
  14. Relevance Matters More Than Keyword Matching
&lt;/h2&gt;

&lt;p&gt;Early search engines relied heavily on matching words.&lt;/p&gt;

&lt;p&gt;Modern search is much more sophisticated.&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 plaintext"&gt;&lt;code&gt;"why does my phone battery drain overnight"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A useful result might not contain exactly that sentence.&lt;/p&gt;

&lt;p&gt;It might instead discuss:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;background processes
battery health
location services
push notifications
sleep settings
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The search engine needs to understand that these concepts are related to the user's underlying problem.&lt;/p&gt;

&lt;p&gt;This is where modern information retrieval and machine learning become important.&lt;/p&gt;




&lt;h2&gt;
  
  
  15. Freshness Can Matter
&lt;/h2&gt;

&lt;p&gt;Some queries require recent information.&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 plaintext"&gt;&lt;code&gt;Apple stock price
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

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

&lt;/div&gt;



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

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

&lt;/div&gt;



&lt;p&gt;For these searches, older information may be less useful.&lt;/p&gt;

&lt;p&gt;Compare that with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;what is recursion
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A tutorial written years ago can still be perfectly useful.&lt;/p&gt;

&lt;p&gt;So search systems need to understand when &lt;strong&gt;freshness&lt;/strong&gt; matters.&lt;/p&gt;




&lt;h2&gt;
  
  
  16. Location Can Matter
&lt;/h2&gt;

&lt;p&gt;Search results can also depend on location.&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 plaintext"&gt;&lt;code&gt;pizza near me
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A result from another country isn't useful.&lt;/p&gt;

&lt;p&gt;Google can use location-related context to provide geographically relevant results.&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;Query
  +
Location
  +
Search intent
       ↓
Local results
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is why two people searching for the same local query may not necessarily see identical results.&lt;/p&gt;




&lt;h2&gt;
  
  
  17. Google May Use Your Search Context
&lt;/h2&gt;

&lt;p&gt;Search results can sometimes be influenced by context associated with the search experience.&lt;/p&gt;

&lt;p&gt;Depending on the situation, this can include things such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Language&lt;/li&gt;
&lt;li&gt;Approximate location&lt;/li&gt;
&lt;li&gt;Device context&lt;/li&gt;
&lt;li&gt;Previous interactions with Google services&lt;/li&gt;
&lt;li&gt;Search settings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Personalization isn't necessarily applied identically to every query.&lt;/p&gt;

&lt;p&gt;The exact behavior depends on Google's systems and the user's settings.&lt;/p&gt;




&lt;h2&gt;
  
  
  18. Special Search Features Are Generated
&lt;/h2&gt;

&lt;p&gt;Google Search isn't limited to ten blue links.&lt;/p&gt;

&lt;p&gt;Depending on the query, the results page can contain different types of features.&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 plaintext"&gt;&lt;code&gt;Search Query
     │
     ├── Web results
     ├── Images
     ├── Videos
     ├── News
     ├── Maps
     ├── Knowledge panels
     ├── Featured snippets
     ├── Shopping results
     └── Other search features
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The system determines which features are relevant to the query.&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 plaintext"&gt;&lt;code&gt;"weather in Chennai"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;might produce a weather result.&lt;/p&gt;

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

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

&lt;/div&gt;



&lt;p&gt;may produce entity-related information alongside web results.&lt;/p&gt;




&lt;h2&gt;
  
  
  19. Ads Are a Separate Part of the Search Experience
&lt;/h2&gt;

&lt;p&gt;You may also see advertisements above or around organic search results.&lt;/p&gt;

&lt;p&gt;These aren't simply pages that won the organic ranking algorithm.&lt;/p&gt;

&lt;p&gt;Google operates a separate advertising system.&lt;/p&gt;

&lt;p&gt;A simplified view is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Search Query
      │
      ├───────────────┐
      ↓               ↓
Organic Search     Ads System
      │               │
      ↓               ↓
Organic Results    Ad Results
      │               │
      └───────┬───────┘
              ↓
        Search Results Page
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This distinction is important:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advertising placement and organic search ranking are different systems.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  20. Google Generates the Search Results Page
&lt;/h2&gt;

&lt;p&gt;Once the relevant information has been selected, Google's systems need to construct the response.&lt;/p&gt;

&lt;p&gt;The response might include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Title
URL
Snippet
Images
Videos
Knowledge information
Ads
Related searches
Other features
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser receives the necessary response data.&lt;/p&gt;




&lt;h2&gt;
  
  
  21. Your Browser Renders the Page
&lt;/h2&gt;

&lt;p&gt;Now the request has completed its journey back to your device.&lt;/p&gt;

&lt;p&gt;Your browser receives the response and begins rendering the interface.&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;Google Server
      ↓
HTTP Response
      ↓
Browser
      ↓
HTML / CSS / JavaScript
      ↓
DOM
      ↓
Layout
      ↓
Painting
      ↓
Search Results
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser then displays the page you see.&lt;/p&gt;

&lt;p&gt;And the entire experience feels almost instantaneous.&lt;/p&gt;




&lt;h2&gt;
  
  
  22. But Google Doesn't Always Start From Scratch
&lt;/h2&gt;

&lt;p&gt;Another important concept is &lt;strong&gt;caching&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Large-scale systems use caches extensively.&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 plaintext"&gt;&lt;code&gt;Popular Query
     ↓
Cached / Reusable Data
     ↓
Faster Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Caching can reduce repeated computation and improve response time.&lt;/p&gt;

&lt;p&gt;This is one of the fundamental techniques used by large internet systems.&lt;/p&gt;

&lt;p&gt;The exact caching architecture Google uses internally is complex and not fully public, but caching is a standard principle in large-scale distributed systems.&lt;/p&gt;




&lt;h2&gt;
  
  
  23. What Happens If Millions of People Search at Once?
&lt;/h2&gt;

&lt;p&gt;Imagine millions of people searching simultaneously:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"World Cup"
"weather"
"Bitcoin"
"Taylor Swift"
"JavaScript"
"Google"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Google needs to handle enormous amounts of traffic.&lt;/p&gt;

&lt;p&gt;This requires distributed infrastructure.&lt;/p&gt;

&lt;p&gt;A simplified architecture could look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 Users
                   │
          ┌────────┴────────┐
          ↓                 ↓
       Region A          Region B
          │                 │
     Load Balancers    Load Balancers
          │                 │
       Servers            Servers
          │                 │
          └────────┬────────┘
                   ↓
          Search Infrastructure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of depending on one machine, workloads are distributed across many machines and locations.&lt;/p&gt;




&lt;h2&gt;
  
  
  24. What If One Server Fails?
&lt;/h2&gt;

&lt;p&gt;Large systems are designed with redundancy.&lt;/p&gt;

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

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

&lt;/div&gt;



&lt;p&gt;The system shouldn't simply stop working.&lt;/p&gt;

&lt;p&gt;Instead, traffic can potentially be handled by other infrastructure.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;              Request
                 │
          Load Balancing
          /      |      \
         ↓       ↓       ↓
       A ❌      B       C
                ✓       ✓
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is one of the fundamental ideas behind &lt;strong&gt;fault-tolerant distributed systems&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  25. Why Is Google Search So Fast?
&lt;/h2&gt;

&lt;p&gt;Several technologies and engineering techniques contribute to the speed.&lt;/p&gt;

&lt;p&gt;At a high level:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Precomputed Index
       +
Efficient Retrieval
       +
Distributed Infrastructure
       +
Caching
       +
Load Balancing
       +
Optimized Ranking
       +
Fast Networks
       ↓
Fast Search
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key idea is that Google does a huge amount of work &lt;strong&gt;before you search&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Crawling and indexing happen ahead of time.&lt;/p&gt;

&lt;p&gt;When you finally enter a query, Google can focus on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Understand
   ↓
Retrieve
   ↓
Rank
   ↓
Generate
   ↓
Respond
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;instead of crawling the entire internet from scratch.&lt;/p&gt;




&lt;h2&gt;
  
  
  26. A Simplified End-to-End Architecture
&lt;/h2&gt;

&lt;p&gt;Putting everything together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                YOU
                 │
                 ▼
          Search Query
                 │
                 ▼
              Browser
                 │
                 ▼
          DNS Resolution
                 │
                 ▼
             Internet
                 │
                 ▼
        Google Infrastructure
                 │
                 ▼
          Load Balancing
                 │
                 ▼
        Query Understanding
                 │
                 ▼
        Search Index Lookup
                 │
                 ▼
       Candidate Retrieval
                 │
                 ▼
             Ranking
                 │
        ┌────────┴────────┐
        │                 │
        ▼                 ▼
   Organic Results      Ads
        │                 │
        └────────┬────────┘
                 ▼
       Search Page Generation
                 │
                 ▼
              Browser
                 │
                 ▼
         Results on Screen
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And all of this can happen in a remarkably short amount of time.&lt;/p&gt;




&lt;h2&gt;
  
  
  27. The Most Important Insight
&lt;/h2&gt;

&lt;p&gt;When you search Google, &lt;strong&gt;Google isn't searching the entire internet in real time&lt;/strong&gt;.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Internet
   ↓
Crawling
   ↓
Processing
   ↓
Indexing
   ↓
Search Index
   ↓
Your Query
   ↓
Retrieval
   ↓
Ranking
   ↓
Results
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is one of the most important concepts in understanding how modern search engines work.&lt;/p&gt;




&lt;h2&gt;
  
  
  28. How This Connects to System Design
&lt;/h2&gt;

&lt;p&gt;Google Search is a great example of large-scale system design because it combines many concepts we've already discussed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Distributed Systems
&lt;/h3&gt;

&lt;p&gt;Millions of requests need to be processed simultaneously.&lt;/p&gt;

&lt;h3&gt;
  
  
  Caching
&lt;/h3&gt;

&lt;p&gt;Frequently accessed information can be served efficiently.&lt;/p&gt;

&lt;h3&gt;
  
  
  Load Balancing
&lt;/h3&gt;

&lt;p&gt;Traffic is distributed across infrastructure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Database / Indexing
&lt;/h3&gt;

&lt;p&gt;Huge amounts of information need to be organized for fast retrieval.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ranking Systems
&lt;/h3&gt;

&lt;p&gt;Potentially relevant results need to be ordered.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fault Tolerance
&lt;/h3&gt;

&lt;p&gt;Individual machines and components can fail without taking down the entire system.&lt;/p&gt;

&lt;h3&gt;
  
  
  Networking
&lt;/h3&gt;

&lt;p&gt;Requests need to travel quickly across global infrastructure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Processing
&lt;/h3&gt;

&lt;p&gt;Web pages need to be crawled, processed, analyzed, and indexed.&lt;/p&gt;

&lt;p&gt;That's why Google Search is much more than a search box.&lt;/p&gt;

&lt;p&gt;It's a &lt;strong&gt;massive distributed information-retrieval system&lt;/strong&gt;.&lt;/p&gt;




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

&lt;p&gt;The next time you type something into Google, remember that you're not simply asking a computer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Find me this webpage."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You're interacting with a massive distributed system.&lt;/p&gt;

&lt;p&gt;Your query travels through the network, reaches Google's infrastructure, gets interpreted, and is matched against a huge pre-built index.&lt;/p&gt;

&lt;p&gt;Potentially relevant documents are retrieved, ranking systems determine their order, other search features may be generated, and the final response is sent back to your browser.&lt;/p&gt;

&lt;p&gt;The simplified journey is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Search Query
     ↓
DNS
     ↓
Internet
     ↓
Google Infrastructure
     ↓
Query Understanding
     ↓
Search Index
     ↓
Candidate Retrieval
     ↓
Ranking
     ↓
Search Features
     ↓
Browser
     ↓
You
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>What Really Happens When You Open Google.com in a Browser?</title>
      <dc:creator>Tanu Priya</dc:creator>
      <pubDate>Sun, 20 Sep 2026 06:31:32 +0000</pubDate>
      <link>https://dev.to/tanu_priya/what-really-happens-when-you-open-googlecom-in-a-browser-4oc6</link>
      <guid>https://dev.to/tanu_priya/what-really-happens-when-you-open-googlecom-in-a-browser-4oc6</guid>
      <description>&lt;p&gt;You type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://www.google.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You press &lt;strong&gt;Enter&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A fraction of a second later, Google appears on your screen.&lt;/p&gt;

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

&lt;p&gt;But behind that single action, your browser may perform &lt;strong&gt;DNS resolution, connection establishment, TLS negotiation, HTTP communication, server-side processing, HTML parsing, CSS processing, JavaScript execution, layout calculation, painting, and compositing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And all of this happens while you are simply waiting to see a webpage.&lt;/p&gt;

&lt;p&gt;So what &lt;em&gt;actually&lt;/em&gt; happens when you open &lt;code&gt;google.com&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;Let's follow the request from your keyboard all the way to the pixels on your screen.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Complete Journey
&lt;/h2&gt;

&lt;p&gt;At a high level, the journey 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;You type google.com
        ↓
Browser interprets the URL
        ↓
Check browser / OS caches
        ↓
DNS Resolution
        ↓
IP Address discovered
        ↓
Connection established
        ↓
TLS Handshake
        ↓
HTTP Request
        ↓
Google's infrastructure
        ↓
HTTP Response
        ↓
Browser receives HTML
        ↓
HTML → DOM
CSS → CSSOM
        ↓
Render Tree
        ↓
Layout
        ↓
Paint
        ↓
Compositing
        ↓
Pixels appear on screen
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But each of these steps contains a lot more interesting engineering.&lt;/p&gt;

&lt;p&gt;Let's start from the beginning.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. You Type &lt;code&gt;google.com&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;You open Chrome, Firefox, Safari, or another browser and type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;google.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser doesn't immediately send those characters to Google.&lt;/p&gt;

&lt;p&gt;First, it needs to understand what you entered.&lt;/p&gt;

&lt;p&gt;The browser's UI process determines whether the input is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a URL&lt;/li&gt;
&lt;li&gt;a search query&lt;/li&gt;
&lt;li&gt;or something else&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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;google.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;looks like a domain name, while:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;best laptops for programming
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;looks more like a search query.&lt;/p&gt;

&lt;p&gt;Modern browsers perform this processing before navigation begins.&lt;/p&gt;

&lt;p&gt;In Chromium-based browsers, navigation involves the browser process, networking components, and a renderer process that eventually handles the webpage.&lt;/p&gt;

&lt;p&gt;Once the browser determines that you're navigating to a website, the real journey begins.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. The Browser Needs an IP Address
&lt;/h2&gt;

&lt;p&gt;Computers communicate across networks using IP addresses.&lt;/p&gt;

&lt;p&gt;Humans prefer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;google.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Machines ultimately need 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;&amp;lt;IP address&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the browser needs to answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Which IP address belongs to google.com?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is where &lt;strong&gt;DNS&lt;/strong&gt; comes in.&lt;/p&gt;

&lt;p&gt;DNS stands for:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Domain Name System&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can think of DNS as the internet's distributed phone book.&lt;/p&gt;

&lt;p&gt;Instead of remembering:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;142.x.x.x
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you remember:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;google.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;DNS maps the human-readable domain name to an IP address.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. DNS Resolution
&lt;/h2&gt;

&lt;p&gt;The browser doesn't necessarily perform a complete DNS lookup every time.&lt;/p&gt;

&lt;p&gt;There can be multiple layers of caching.&lt;/p&gt;

&lt;p&gt;A simplified flow looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser
   ↓
OS / DNS cache
   ↓
DNS Resolver
   ↓
Root DNS Servers
   ↓
.com TLD Servers
   ↓
Google's Authoritative DNS
   ↓
IP Address
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, if a cached DNS result is still valid, some of these steps can be avoided.&lt;/p&gt;

&lt;p&gt;This is one reason why repeated visits to websites can behave differently from the first visit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why caching matters
&lt;/h3&gt;

&lt;p&gt;Imagine if every webpage visit required starting from the root DNS infrastructure.&lt;/p&gt;

&lt;p&gt;That would add unnecessary latency.&lt;/p&gt;

&lt;p&gt;Instead, DNS responses have a &lt;strong&gt;TTL (Time To Live)&lt;/strong&gt; that allows results to be cached for a period of time.&lt;/p&gt;

&lt;p&gt;So the browser may effectively say:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"I already know where google.com is."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and skip much of the lookup process.&lt;/p&gt;

&lt;p&gt;Modern DNS can also use encrypted transports such as &lt;strong&gt;DNS over HTTPS (DoH)&lt;/strong&gt; or &lt;strong&gt;DNS over TLS (DoT)&lt;/strong&gt;, depending on the system and browser configuration.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. DNS Gives Us an IP Address
&lt;/h2&gt;

&lt;p&gt;Eventually, the system obtains an address for the destination.&lt;/p&gt;

&lt;p&gt;Now the browser knows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;google.com
       ↓
IP address
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But knowing where to send the request isn't enough.&lt;/p&gt;

&lt;p&gt;The browser still needs to establish communication with the server.&lt;/p&gt;

&lt;p&gt;And this is where networking begins.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Establishing the Connection
&lt;/h2&gt;

&lt;p&gt;For traditional HTTPS over TCP, the browser establishes a TCP connection to the destination.&lt;/p&gt;

&lt;p&gt;TCP provides reliable, ordered delivery of data.&lt;/p&gt;

&lt;p&gt;A simplified TCP handshake looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client                         Server

  SYN  ------------------------&amp;gt;

       &amp;lt;------------------- SYN-ACK

  ACK  ------------------------&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is commonly called the &lt;strong&gt;three-way handshake&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The goal is to establish the connection and synchronize the communication state between both sides.&lt;/p&gt;

&lt;p&gt;Only after the connection is established can the browser proceed with the next stage.&lt;/p&gt;

&lt;p&gt;But there's another important requirement.&lt;/p&gt;

&lt;p&gt;We're visiting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://google.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://google.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the communication needs to be encrypted.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. The TLS Handshake
&lt;/h2&gt;

&lt;p&gt;HTTPS uses &lt;strong&gt;TLS (Transport Layer Security)&lt;/strong&gt; to protect the connection.&lt;/p&gt;

&lt;p&gt;TLS provides important security properties including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Encryption&lt;/li&gt;
&lt;li&gt;Integrity&lt;/li&gt;
&lt;li&gt;Server authentication&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The browser needs to establish cryptographic keys that can be used to securely communicate with the server.&lt;/p&gt;

&lt;p&gt;A simplified TLS flow looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser                         Server

ClientHello --------------------&amp;gt;

             &amp;lt;---------------- ServerHello
             &amp;lt;---------------- Certificate
             &amp;lt;---------------- Key Exchange

Certificate verification

Key establishment

Finished ----------------------&amp;gt;

             &amp;lt;---------------- Finished
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The actual modern TLS handshake is more nuanced, but conceptually the browser and server are establishing a secure communication channel.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why does the certificate matter?
&lt;/h3&gt;

&lt;p&gt;Suppose you typed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://google.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You don't want an attacker pretending to be Google.&lt;/p&gt;

&lt;p&gt;The server provides a certificate that allows the browser to verify that the server is authorized for the requested domain.&lt;/p&gt;

&lt;p&gt;If certificate validation fails, the browser can display a security warning instead of silently trusting the connection.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Now We Can Send an HTTP Request
&lt;/h2&gt;

&lt;p&gt;DNS told us &lt;strong&gt;where&lt;/strong&gt; to go.&lt;/p&gt;

&lt;p&gt;TCP established &lt;strong&gt;reliable communication&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;TLS established &lt;strong&gt;secure communication&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now HTTP can finally do its job.&lt;/p&gt;

&lt;p&gt;The browser sends an HTTP request.&lt;/p&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 http"&gt;&lt;code&gt;&lt;span class="nf"&gt;GET&lt;/span&gt; &lt;span class="nn"&gt;/&lt;/span&gt; &lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
&lt;span class="na"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;www.google.com&lt;/span&gt;
&lt;span class="na"&gt;User-Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;
&lt;span class="na"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;text/html&lt;/span&gt;
&lt;span class="na"&gt;Accept-Language&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;en-US&lt;/span&gt;
&lt;span class="na"&gt;Cookie&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The actual request headers and protocol details vary depending on the browser, connection, cookies, HTTP version, and other factors.&lt;/p&gt;

&lt;p&gt;The important part is:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;The browser is essentially saying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Give me the resource at the root path."&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  8. Your Request Travels Across the Internet
&lt;/h2&gt;

&lt;p&gt;The request doesn't magically teleport from your laptop to Google.&lt;/p&gt;

&lt;p&gt;It travels through a network.&lt;/p&gt;

&lt;p&gt;A simplified model might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your Browser
     ↓
Your Device
     ↓
Wi-Fi Router
     ↓
ISP
     ↓
Internet Routers
     ↓
Google's Network
     ↓
Google Infrastructure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every packet can travel through multiple network devices before reaching its destination.&lt;/p&gt;

&lt;p&gt;Routers examine addressing information and determine where packets should go next.&lt;/p&gt;

&lt;p&gt;This is one of the fascinating things about the internet:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your browser doesn't need to know the entire route to Google's servers.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The network infrastructure handles routing.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. The Request Reaches Google's Infrastructure
&lt;/h2&gt;

&lt;p&gt;This is where the story gets much more interesting.&lt;/p&gt;

&lt;p&gt;A request to a massive service isn't simply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Internet → One Server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Large-scale systems typically have layers of infrastructure designed to handle enormous amounts of traffic.&lt;/p&gt;

&lt;p&gt;A conceptual architecture could look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 Internet
                    ↓
              Edge Network
                    ↓
             Load Balancing
                    ↓
          Frontend / Web Servers
                    ↓
          Application Services
                    ↓
        Internal Services / Storage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact architecture of Google's production systems is complex and not something we can reduce to one simple diagram.&lt;/p&gt;

&lt;p&gt;But the important distributed-systems lesson is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A large website is usually an ecosystem of services, not one giant computer.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  10. The Server Processes the Request
&lt;/h2&gt;

&lt;p&gt;Once the request reaches the appropriate service, the server determines what response should be returned.&lt;/p&gt;

&lt;p&gt;Depending on the website, this might involve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authentication&lt;/li&gt;
&lt;li&gt;Cookies&lt;/li&gt;
&lt;li&gt;Request routing&lt;/li&gt;
&lt;li&gt;Feature flags&lt;/li&gt;
&lt;li&gt;Personalization&lt;/li&gt;
&lt;li&gt;Application logic&lt;/li&gt;
&lt;li&gt;Cache lookup&lt;/li&gt;
&lt;li&gt;Database access&lt;/li&gt;
&lt;li&gt;Internal APIs&lt;/li&gt;
&lt;li&gt;Other services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a simple static website, the server might be able to return cached content almost immediately.&lt;/p&gt;

&lt;p&gt;For a dynamic application, the request may trigger much more work.&lt;/p&gt;

&lt;p&gt;This is why backend architecture matters.&lt;/p&gt;

&lt;p&gt;The user sees:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Google loaded.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But the backend may have performed many operations before the browser receives the response.&lt;/p&gt;




&lt;h2&gt;
  
  
  11. The Server Sends an HTTP Response
&lt;/h2&gt;

&lt;p&gt;Eventually, the browser receives an HTTP response.&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 http"&gt;&lt;code&gt;&lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;text/html&lt;/span&gt;
&lt;span class="na"&gt;Content-Encoding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;
&lt;span class="na"&gt;Cache-Control&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;followed by the response body.&lt;/p&gt;

&lt;p&gt;The response body could contain HTML such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    ...
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    ...
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser now has something important:&lt;/p&gt;

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

&lt;p&gt;But the page isn't "finished" yet.&lt;/p&gt;

&lt;p&gt;This is where browser rendering begins.&lt;/p&gt;




&lt;h2&gt;
  
  
  12. The Browser Starts Parsing HTML
&lt;/h2&gt;

&lt;p&gt;The browser's rendering engine receives the HTML.&lt;/p&gt;

&lt;p&gt;It doesn't simply wait for the entire document and then process everything at once.&lt;/p&gt;

&lt;p&gt;HTML can be processed progressively as data arrives.&lt;/p&gt;

&lt;p&gt;Modern browsers can parse streamed HTML incrementally, allowing rendering work to begin before the entire response has arrived.&lt;/p&gt;

&lt;p&gt;The HTML parser turns markup into a structure called the:&lt;/p&gt;

&lt;h1&gt;
  
  
  DOM
&lt;/h1&gt;

&lt;p&gt;DOM stands for:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Document Object Model&lt;/strong&gt;&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 html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Hello&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Welcome!&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;can be represented conceptually as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Document
   |
   └── body
        |
        ├── h1
        |    └── "Hello"
        |
        └── p
             └── "Welcome!"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tree structure allows JavaScript and browser APIs to interact with the document.&lt;/p&gt;




&lt;h2&gt;
  
  
  13. HTML Isn't Enough
&lt;/h2&gt;

&lt;p&gt;HTML tells the browser:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What elements exist?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But it doesn't fully describe how those elements should look.&lt;/p&gt;

&lt;p&gt;That's the job of CSS.&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 css"&gt;&lt;code&gt;&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;40px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&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 needs to download and process the CSS.&lt;/p&gt;

&lt;p&gt;It constructs another representation called the:&lt;/p&gt;

&lt;h1&gt;
  
  
  CSSOM
&lt;/h1&gt;

&lt;p&gt;CSSOM stands for:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CSS Object Model&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So now we have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTML
 ↓
DOM

CSS
 ↓
CSSOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  14. DOM + CSSOM
&lt;/h2&gt;

&lt;p&gt;The browser combines information from the DOM and CSSOM to determine what should actually be rendered.&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;              HTML
                ↓
               DOM
                \
                 \
                  → Render information
                 /
                /
              CSSOM
                ↑
                CSS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This produces the information needed for rendering.&lt;/p&gt;

&lt;p&gt;A simplified representation is often called the &lt;strong&gt;render tree&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The render tree contains the visual information necessary for the browser to determine what appears on the screen.&lt;/p&gt;




&lt;h2&gt;
  
  
  15. Then Comes Layout
&lt;/h2&gt;

&lt;p&gt;The browser now needs to answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Where exactly should every element appear?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Suppose you have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Hello&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;This is a paragraph.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser needs to calculate things such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;h1:
x = 40
y = 20
width = 300
height = 50

p:
x = 40
y = 90
width = 500
height = 80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This process is called:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layout&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;or sometimes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reflow&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The browser calculates the geometry of visible elements.&lt;/p&gt;

&lt;p&gt;This includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Position&lt;/li&gt;
&lt;li&gt;Width&lt;/li&gt;
&lt;li&gt;Height&lt;/li&gt;
&lt;li&gt;Margins&lt;/li&gt;
&lt;li&gt;Padding&lt;/li&gt;
&lt;li&gt;Line wrapping&lt;/li&gt;
&lt;li&gt;Font metrics&lt;/li&gt;
&lt;li&gt;Relationships between elements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And this can become computationally expensive on complex pages.&lt;/p&gt;




&lt;h2&gt;
  
  
  16. Painting the Page
&lt;/h2&gt;

&lt;p&gt;Once the browser knows where everything goes, it needs to determine what should actually be drawn.&lt;/p&gt;

&lt;p&gt;This stage is called:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Paint&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The browser creates drawing instructions for things such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Text&lt;/li&gt;
&lt;li&gt;Backgrounds&lt;/li&gt;
&lt;li&gt;Borders&lt;/li&gt;
&lt;li&gt;Shadows&lt;/li&gt;
&lt;li&gt;Images&lt;/li&gt;
&lt;li&gt;Gradients&lt;/li&gt;
&lt;/ul&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;DOM + CSS
    ↓
Layout
    ↓
Paint instructions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But we're still not quite done.&lt;/p&gt;




&lt;h2&gt;
  
  
  17. Compositing
&lt;/h2&gt;

&lt;p&gt;Modern browsers don't necessarily draw the entire webpage as one giant image.&lt;/p&gt;

&lt;p&gt;Different parts of a page can be handled as separate compositing layers.&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 plaintext"&gt;&lt;code&gt;Layer 1 → Background
Layer 2 → Main content
Layer 3 → Fixed header
Layer 4 → Animation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser can then composite these layers together.&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;Painted Layers
      ↓
Compositor
      ↓
GPU / Display Pipeline
      ↓
Screen
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is one reason certain CSS operations can be significantly cheaper to animate than operations that repeatedly trigger expensive layout work.&lt;/p&gt;




&lt;h2&gt;
  
  
  18. JavaScript Enters the Picture
&lt;/h2&gt;

&lt;p&gt;Modern websites aren't just HTML and CSS.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Modify the DOM&lt;/li&gt;
&lt;li&gt;Respond to user interactions&lt;/li&gt;
&lt;li&gt;Fetch APIs&lt;/li&gt;
&lt;li&gt;Track state&lt;/li&gt;
&lt;li&gt;Update the UI&lt;/li&gt;
&lt;li&gt;Start animations&lt;/li&gt;
&lt;li&gt;Load additional resources&lt;/li&gt;
&lt;li&gt;Communicate with servers&lt;/li&gt;
&lt;/ul&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;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Clicked!&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When JavaScript changes the page, the browser may need to perform additional rendering work.&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 plaintext"&gt;&lt;code&gt;JavaScript
    ↓
DOM change
    ↓
Style calculation
    ↓
Layout
    ↓
Paint
    ↓
Composite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not every JavaScript operation triggers every stage, but expensive DOM and style changes can cause significant work.&lt;/p&gt;




&lt;h2&gt;
  
  
  19. One Page Can Trigger Many Requests
&lt;/h2&gt;

&lt;p&gt;Here's an important realization.&lt;/p&gt;

&lt;p&gt;You didn't just request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;google.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The initial HTML can reference many additional resources.&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 plaintext"&gt;&lt;code&gt;HTML
 ├── CSS
 ├── JavaScript
 ├── Images
 ├── Fonts
 ├── API requests
 └── Other resources
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser discovers these resources while processing the document and requests them as needed.&lt;/p&gt;

&lt;p&gt;This means a webpage is often not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1 request → 1 response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is closer to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Navigation request
       ↓
HTML
       ↓
 ┌─────┼─────┬─────┐
 ↓     ↓     ↓     ↓
CSS   JS   Images Fonts
       ↓
   API Requests
       ↓
   More Data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's why network waterfalls in Chrome DevTools can become surprisingly large.&lt;/p&gt;




&lt;h2&gt;
  
  
  20. HTTP/2 and HTTP/3 Make This More Efficient
&lt;/h2&gt;

&lt;p&gt;Modern web communication isn't limited to the old HTTP/1.1 model.&lt;/p&gt;

&lt;p&gt;HTTP/2 introduced features such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multiplexing&lt;/li&gt;
&lt;li&gt;Header compression&lt;/li&gt;
&lt;li&gt;Stream prioritization mechanisms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This allows multiple requests and responses to share a connection more efficiently.&lt;/p&gt;

&lt;p&gt;HTTP/3 goes further by using &lt;strong&gt;QUIC&lt;/strong&gt;, which runs over UDP and incorporates transport and TLS functionality into the protocol stack.&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;Older model:

HTTP
 ↓
TCP
 ↓
IP


HTTP/2:

HTTP/2
  ↓
 TCP
  ↓
 IP


HTTP/3:

HTTP/3
  ↓
 QUIC
  ↓
 UDP
  ↓
 IP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important point is that the web's transport layer has evolved significantly to reduce latency and improve performance.&lt;/p&gt;




&lt;h2&gt;
  
  
  21. Caching Can Change Everything
&lt;/h2&gt;

&lt;p&gt;Now imagine you've already visited Google.&lt;/p&gt;

&lt;p&gt;The browser may already have cached some resources.&lt;/p&gt;

&lt;p&gt;Instead of downloading everything again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser
   ↓
"Do I already have this?"
   ↓
YES
   ↓
Use cached resource
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Caching can exist at multiple layers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser Cache
      ↓
Operating System / Network Cache
      ↓
CDN / Edge Cache
      ↓
Server Cache
      ↓
Database / Storage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A good caching strategy can dramatically reduce:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Network requests&lt;/li&gt;
&lt;li&gt;Server work&lt;/li&gt;
&lt;li&gt;Latency&lt;/li&gt;
&lt;li&gt;Bandwidth usage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is one of the most important performance principles in web development.&lt;/p&gt;




&lt;h2&gt;
  
  
  22. The Browser Finally Shows You the Page
&lt;/h2&gt;

&lt;p&gt;After all this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DNS
 ↓
Connection
 ↓
TLS
 ↓
HTTP
 ↓
Server
 ↓
HTML
 ↓
DOM
 ↓
CSSOM
 ↓
Render Tree
 ↓
Layout
 ↓
Paint
 ↓
Composite
 ↓
Pixels
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you finally see the webpage.&lt;/p&gt;

&lt;p&gt;To you, it looked like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Type → Enter → Website
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But internally, an enormous amount of work happened.&lt;/p&gt;




&lt;h2&gt;
  
  
  23. What Happens When You Click Something?
&lt;/h2&gt;

&lt;p&gt;The process doesn't end when the page appears.&lt;/p&gt;

&lt;p&gt;Suppose you click a button.&lt;/p&gt;

&lt;p&gt;The browser might perform:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Mouse Event
     ↓
JavaScript Event Handler
     ↓
State Change
     ↓
DOM Update
     ↓
Style Calculation
     ↓
Layout
     ↓
Paint
     ↓
Composite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or perhaps the button triggers an API request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Click
  ↓
JavaScript
  ↓
fetch("/api/data")
  ↓
HTTP Request
  ↓
Server
  ↓
Database / Service
  ↓
HTTP Response
  ↓
JavaScript
  ↓
UI Update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the same concepts repeat throughout the lifetime of the application.&lt;/p&gt;




&lt;h2&gt;
  
  
  24. Where Performance Problems Come From
&lt;/h2&gt;

&lt;p&gt;Now the entire process becomes useful from an engineering perspective.&lt;/p&gt;

&lt;p&gt;A webpage can be slow for completely different reasons.&lt;/p&gt;

&lt;h3&gt;
  
  
  DNS is slow
&lt;/h3&gt;

&lt;p&gt;The browser spends more time resolving the domain.&lt;/p&gt;

&lt;h3&gt;
  
  
  Connection establishment is slow
&lt;/h3&gt;

&lt;p&gt;Network latency or connection setup adds delay.&lt;/p&gt;

&lt;h3&gt;
  
  
  Server response is slow
&lt;/h3&gt;

&lt;p&gt;The backend takes too long to generate the response.&lt;/p&gt;

&lt;h3&gt;
  
  
  HTML is large
&lt;/h3&gt;

&lt;p&gt;The browser has more data to download and parse.&lt;/p&gt;

&lt;h3&gt;
  
  
  JavaScript is expensive
&lt;/h3&gt;

&lt;p&gt;The main thread can become blocked.&lt;/p&gt;

&lt;h3&gt;
  
  
  CSS is expensive
&lt;/h3&gt;

&lt;p&gt;Style calculation and layout can become costly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Images are huge
&lt;/h3&gt;

&lt;p&gt;Downloading and decoding them takes time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Too many requests
&lt;/h3&gt;

&lt;p&gt;The browser has more network work to coordinate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Third-party scripts are expensive
&lt;/h3&gt;

&lt;p&gt;Analytics, ads, widgets, and other external code compete for network and CPU resources.&lt;/p&gt;

&lt;p&gt;This is why web performance isn't simply:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Make your JavaScript faster."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Performance is an &lt;strong&gt;end-to-end problem&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  25. The Browser Is Doing Multiple Things at Once
&lt;/h1&gt;

&lt;p&gt;One of the biggest misconceptions about browsers is thinking they execute the webpage as one simple sequence.&lt;/p&gt;

&lt;p&gt;Modern browsers are complex, multi-process systems.&lt;/p&gt;

&lt;p&gt;A simplified architecture might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 Browser
                    |
        ┌───────────┼───────────┐
        ↓           ↓           ↓
   Browser       Network      Storage
   Process        Work         Work
        |
        ↓
   Renderer Process
        |
   ┌────┼────┐
   ↓    ↓    ↓
 HTML  CSS   JS
   |
   ↓
 Rendering Pipeline
   |
   ↓
   GPU
   |
   ↓
 Screen
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Chromium's architecture separates browser-level responsibilities from renderer responsibilities, with communication between processes handled through IPC.&lt;/p&gt;

&lt;p&gt;This architecture provides important isolation and allows browsers to manage complex web applications more safely and efficiently.&lt;/p&gt;




&lt;h2&gt;
  
  
  26. The Entire Journey in One Diagram
&lt;/h2&gt;

&lt;p&gt;Here's the complete mental model I use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 USER
                  │
                  ▼
          Types google.com
                  │
                  ▼
           Browser UI
                  │
                  ▼
          URL Interpretation
                  │
                  ▼
           DNS Resolution
                  │
                  ▼
             IP Address
                  │
                  ▼
        Connection Establishment
                  │
                  ▼
            TLS Handshake
                  │
                  ▼
           HTTP Request
                  │
                  ▼
        ┌───────────────────┐
        │ Google's Network  │
        │                   │
        │ Edge / Routing     │
        │ Load Balancing     │
        │ Application Logic  │
        │ Internal Services  │
        └───────────────────┘
                  │
                  ▼
          HTTP Response
                  │
                  ▼
             HTML
                  │
          ┌───────┴────────┐
          ▼                ▼
        DOM              CSSOM
          │                │
          └───────┬────────┘
                  ▼
             Render Tree
                  │
                  ▼
                Layout
                  │
                  ▼
                Paint
                  │
                  ▼
             Compositing
                  │
                  ▼
                 GPU
                  │
                  ▼
              SCREEN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that entire pipeline happens incredibly quickly.&lt;/p&gt;




&lt;h1&gt;
  
  
  27. The Most Important Mental Model
&lt;/h1&gt;

&lt;p&gt;If you're preparing for frontend, backend, or system-design interviews, don't memorize a list of terms.&lt;/p&gt;

&lt;p&gt;Understand the dependency chain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DNS
 ↓
Where is the server?

Connection
 ↓
How do I communicate with it?

TLS
 ↓
Can I communicate securely?

HTTP
 ↓
What resource do I want?

Server
 ↓
How should the request be processed?

HTML
 ↓
What exists on the page?

CSS
 ↓
How should it look?

JavaScript
 ↓
How should it behave?

Layout
 ↓
Where does everything go?

Paint
 ↓
What should be drawn?

Compositing
 ↓
How should the layers be combined?

GPU / Display
 ↓
How do those instructions become pixels?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you understand this chain, many seemingly unrelated web-development concepts start making sense.&lt;/p&gt;




&lt;h1&gt;
  
  
  28. Why This Question Is So Important
&lt;/h1&gt;

&lt;p&gt;"What happens when you open Google.com?" sounds like a beginner question.&lt;/p&gt;

&lt;p&gt;It isn't.&lt;/p&gt;

&lt;p&gt;A strong answer can touch almost every major area of web development:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Frontend
   ├── HTML
   ├── CSS
   ├── JavaScript
   └── Rendering

Networking
   ├── DNS
   ├── TCP
   ├── TLS
   ├── HTTP
   └── IP

Backend
   ├── Servers
   ├── APIs
   ├── Caching
   └── Databases

System Design
   ├── Load Balancing
   ├── Distributed Systems
   ├── CDNs
   └── Scalability

Performance
   ├── Latency
   ├── TTFB
   ├── Rendering
   └── Network Optimization

Security
   ├── HTTPS
   ├── TLS
   ├── Certificates
   └── Origin Isolation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One URL can therefore become a tour through almost the entire web stack.&lt;/p&gt;




&lt;h1&gt;
  
  
  Final Takeaway
&lt;/h1&gt;

&lt;p&gt;The next time you type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;google.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;don't think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The website opens."&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;URL
 ↓
DNS
 ↓
IP
 ↓
Connection
 ↓
TLS
 ↓
HTTP
 ↓
Server Infrastructure
 ↓
HTML
 ↓
DOM
 ↓
CSSOM
 ↓
JavaScript
 ↓
Layout
 ↓
Paint
 ↓
Compositing
 ↓
Pixels
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What looks like a single action to the user is actually a coordinated interaction between &lt;strong&gt;your browser, operating system, DNS infrastructure, network, security protocols, servers, application services, and rendering engine&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And that is one of the most beautiful things about the web:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A few characters typed into an address bar can trigger an entire distributed system.&lt;/strong&gt;&lt;/p&gt;




</description>
      <category>computerscience</category>
      <category>networking</category>
      <category>web</category>
    </item>
    <item>
      <title>How Do Big Backend Applications Scale?</title>
      <dc:creator>Tanu Priya</dc:creator>
      <pubDate>Sat, 19 Sep 2026 10:23:04 +0000</pubDate>
      <link>https://dev.to/tanu_priya/how-do-big-backend-applications-scale-20d2</link>
      <guid>https://dev.to/tanu_priya/how-do-big-backend-applications-scale-20d2</guid>
      <description>&lt;p&gt;A backend rarely starts as a complicated distributed system.&lt;/p&gt;

&lt;p&gt;It usually starts with something much simpler:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User → API Server → Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few users send requests. The server processes them. The database stores the data. Everything is easy to understand.&lt;/p&gt;

&lt;p&gt;Then the application becomes popular.&lt;/p&gt;

&lt;p&gt;The number of users increases. Requests arrive faster. Some database queries become expensive. Large files need processing. Emails and notifications have to be sent. One server starts running out of capacity.&lt;/p&gt;

&lt;p&gt;So you add another server.&lt;/p&gt;

&lt;p&gt;Then another.&lt;/p&gt;

&lt;p&gt;Then a cache.&lt;/p&gt;

&lt;p&gt;Then a queue.&lt;/p&gt;

&lt;p&gt;Then database replicas.&lt;/p&gt;

&lt;p&gt;Eventually, you might have dozens or hundreds of machines working together.&lt;/p&gt;

&lt;p&gt;This raises a fundamental question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;How does a simple backend gradually evolve into a system capable of serving millions of requests?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The answer isn't simply "add more servers."&lt;/p&gt;

&lt;p&gt;Backend scaling is a process of identifying bottlenecks, separating workloads, distributing work, and accepting carefully chosen trade-offs.&lt;/p&gt;

&lt;p&gt;The architecture becomes more complicated &lt;strong&gt;because the problems become more complicated&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Does It Actually Mean to Scale?
&lt;/h2&gt;

&lt;p&gt;Before looking at specific technologies, it helps to define what we're trying to improve.&lt;/p&gt;

&lt;p&gt;A backend typically has several important characteristics.&lt;/p&gt;

&lt;h3&gt;
  
  
  Latency
&lt;/h3&gt;

&lt;p&gt;How long does one request take?&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 plaintext"&gt;&lt;code&gt;GET /products/123
→ 80 ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lower latency generally means the individual request completes faster.&lt;/p&gt;

&lt;h3&gt;
  
  
  Throughput
&lt;/h3&gt;

&lt;p&gt;How much work can the system handle over a period of time?&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 plaintext"&gt;&lt;code&gt;10,000 requests / second
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Throughput is about the amount of work the system can process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Concurrency
&lt;/h3&gt;

&lt;p&gt;How many operations are happening at the same time?&lt;/p&gt;

&lt;p&gt;A server might have thousands of active connections even if only a fraction of them are actively consuming CPU at a particular moment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Availability
&lt;/h3&gt;

&lt;p&gt;How often is the system operational and able to serve requests?&lt;/p&gt;

&lt;p&gt;A system that works extremely quickly but frequently goes offline isn't very useful.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scalability
&lt;/h3&gt;

&lt;p&gt;Scalability is about how well the system continues to handle increasing workload as demand grows.&lt;/p&gt;

&lt;p&gt;These concepts are related, but they aren't the same.&lt;/p&gt;

&lt;p&gt;You can improve latency without increasing throughput.&lt;/p&gt;

&lt;p&gt;You can increase throughput while making individual requests slower.&lt;/p&gt;

&lt;p&gt;You can increase capacity while accidentally making the system harder to operate.&lt;/p&gt;

&lt;p&gt;That's why system design is fundamentally about trade-offs.&lt;/p&gt;




&lt;h2&gt;
  
  
  The First Version: Keep It Simple
&lt;/h2&gt;

&lt;p&gt;Imagine you're building a small e-commerce application.&lt;/p&gt;

&lt;p&gt;The first version might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Users
  ↓
API Server
  ↓
Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The API server might handle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authentication&lt;/li&gt;
&lt;li&gt;Validation&lt;/li&gt;
&lt;li&gt;Business logic&lt;/li&gt;
&lt;li&gt;Database queries&lt;/li&gt;
&lt;li&gt;API responses&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The database handles persistent state.&lt;/p&gt;

&lt;p&gt;For a small application, this architecture can work extremely well.&lt;/p&gt;

&lt;p&gt;There is a tendency in system design discussions to jump immediately to technologies such as Kubernetes, Kafka, Redis, microservices, and distributed databases.&lt;/p&gt;

&lt;p&gt;But complexity has a cost.&lt;/p&gt;

&lt;p&gt;Every additional component means another system that must be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deployed&lt;/li&gt;
&lt;li&gt;Monitored&lt;/li&gt;
&lt;li&gt;Secured&lt;/li&gt;
&lt;li&gt;Debugged&lt;/li&gt;
&lt;li&gt;Upgraded&lt;/li&gt;
&lt;li&gt;Paid for&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your application has 100 users, introducing twenty distributed components probably creates more problems than it solves.&lt;/p&gt;

&lt;p&gt;So the first scaling principle is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Start with the simplest architecture that satisfies the current requirements.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The architecture should evolve when the workload demands it.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Happens When Traffic Increases?
&lt;/h2&gt;

&lt;p&gt;Suppose the application becomes popular.&lt;/p&gt;

&lt;p&gt;More users mean more requests.&lt;/p&gt;

&lt;p&gt;Initially, the server may handle everything comfortably.&lt;/p&gt;

&lt;p&gt;Eventually, resources begin to approach their limits.&lt;/p&gt;

&lt;p&gt;You might observe:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CPU       → 90%
Memory    → 85%
Database  → High load
Latency   → Increasing
Errors    → Increasing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But these numbers don't tell you what to change.&lt;/p&gt;

&lt;p&gt;A server can be slow because of CPU-intensive work.&lt;/p&gt;

&lt;p&gt;Or because it is waiting for the database.&lt;/p&gt;

&lt;p&gt;Or because it is making too many network calls.&lt;/p&gt;

&lt;p&gt;Or because a particular query is poorly optimized.&lt;/p&gt;

&lt;p&gt;Or because a downstream service is slow.&lt;/p&gt;

&lt;p&gt;This is why scaling should begin with &lt;strong&gt;measurement&lt;/strong&gt;, not infrastructure.&lt;/p&gt;

&lt;p&gt;You want to answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Where is the time and capacity actually going?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That leads to one of the most important ideas in system design:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Don't scale everything. Scale the bottleneck.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 1: Optimize Before You Scale
&lt;/h2&gt;

&lt;p&gt;Imagine one endpoint is taking 2 seconds to respond.&lt;/p&gt;

&lt;p&gt;The first instinct might be:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"We need more servers."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But suppose the request contains a database query that scans millions of rows.&lt;/p&gt;

&lt;p&gt;Adding more API servers won't fix that query.&lt;/p&gt;

&lt;p&gt;You might instead need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A better index&lt;/li&gt;
&lt;li&gt;A more efficient query&lt;/li&gt;
&lt;li&gt;Pagination&lt;/li&gt;
&lt;li&gt;Smaller result sets&lt;/li&gt;
&lt;li&gt;Connection pooling&lt;/li&gt;
&lt;li&gt;Reduced database round trips&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is an important distinction.&lt;/p&gt;

&lt;p&gt;There are two broad ways to handle more workload:&lt;/p&gt;

&lt;h3&gt;
  
  
  Do less work
&lt;/h3&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cache repeated results&lt;/li&gt;
&lt;li&gt;Optimize database queries&lt;/li&gt;
&lt;li&gt;Avoid unnecessary computation&lt;/li&gt;
&lt;li&gt;Reduce payload sizes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Do more work in parallel
&lt;/h3&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add application servers&lt;/li&gt;
&lt;li&gt;Add database replicas&lt;/li&gt;
&lt;li&gt;Add workers&lt;/li&gt;
&lt;li&gt;Partition workloads&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Good architectures often use both.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: Add Caching
&lt;/h2&gt;

&lt;p&gt;One of the most common forms of unnecessary work is repeatedly calculating or retrieving the same information.&lt;/p&gt;

&lt;p&gt;Imagine a product page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /api/products/123
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Suppose thousands of users request the same product.&lt;/p&gt;

&lt;p&gt;Without caching, every request may reach the database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request
   ↓
API
   ↓
Database
   ↓
Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the product doesn't change frequently, doing this thousands of times is wasteful.&lt;/p&gt;

&lt;p&gt;A cache allows frequently accessed data to be stored temporarily.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request
   ↓
Cache
   ↓
Database if needed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the data exists in the cache, that's a &lt;strong&gt;cache hit&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If it doesn't, that's a &lt;strong&gt;cache miss&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A common approach is called &lt;strong&gt;cache-aside&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Application checks the cache.&lt;/li&gt;
&lt;li&gt;If data exists, return it.&lt;/li&gt;
&lt;li&gt;Otherwise, query the database.&lt;/li&gt;
&lt;li&gt;Store the result in the cache.&lt;/li&gt;
&lt;li&gt;Return the result.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Redis is commonly used for this type of workload.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Is Caching So Powerful?
&lt;/h2&gt;

&lt;p&gt;Imagine a database receives 100,000 identical reads.&lt;/p&gt;

&lt;p&gt;If 90,000 of those requests can be served from a cache, the database only needs to handle a fraction of the original workload.&lt;/p&gt;

&lt;p&gt;That can improve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Database capacity&lt;/li&gt;
&lt;li&gt;Response latency&lt;/li&gt;
&lt;li&gt;Application throughput&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But caching introduces a difficult problem:&lt;/p&gt;

&lt;h2&gt;
  
  
  Stale Data
&lt;/h2&gt;

&lt;p&gt;Suppose the database says:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Price = ₹999
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;while the cache still contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Price = ₹899
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which value should the user receive?&lt;/p&gt;

&lt;p&gt;This is why cache design involves concepts such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TTL&lt;/li&gt;
&lt;li&gt;Cache invalidation&lt;/li&gt;
&lt;li&gt;Cache-aside&lt;/li&gt;
&lt;li&gt;Write-through caching&lt;/li&gt;
&lt;li&gt;Cache consistency&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Caching is therefore not simply a performance feature.&lt;/p&gt;

&lt;p&gt;It is also a &lt;strong&gt;data-consistency decision&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And this is a recurring pattern in system design:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Performance improvements often introduce consistency or operational trade-offs.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 3: One Server Is No Longer Enough
&lt;/h2&gt;

&lt;p&gt;Eventually, the application server itself may become the bottleneck.&lt;/p&gt;

&lt;p&gt;Perhaps CPU usage is consistently high.&lt;/p&gt;

&lt;p&gt;Perhaps memory usage is approaching the machine's limit.&lt;/p&gt;

&lt;p&gt;Perhaps there are simply too many concurrent requests.&lt;/p&gt;

&lt;p&gt;At this point, horizontal scaling becomes useful.&lt;/p&gt;

&lt;p&gt;Instead of one server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Users
  ↓
Server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;we run multiple instances:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Users
  ↓
Load Balancer
  ↓
+--------+--------+
|        |        |
Server   Server   Server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The load balancer distributes requests among the available instances.&lt;/p&gt;

&lt;p&gt;Now the application can increase capacity by adding instances.&lt;/p&gt;

&lt;p&gt;This is horizontal scaling.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Stateless Servers Matter
&lt;/h2&gt;

&lt;p&gt;Multiple servers create an important question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Where does application state live?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Suppose Server 1 stores a user's session in its local memory.&lt;/p&gt;

&lt;p&gt;The user's next request goes to Server 3.&lt;/p&gt;

&lt;p&gt;Server 3 doesn't have that session.&lt;/p&gt;

&lt;p&gt;Now the system has a problem.&lt;/p&gt;

&lt;p&gt;This is why scalable application servers are generally designed to be &lt;strong&gt;stateless&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of keeping important shared state only in local memory, that state can be stored in an external system.&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 plaintext"&gt;&lt;code&gt;Server 1 ─┐
Server 2 ─┼──→ Shared State
Server 3 ─┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The shared system might be a database, Redis, or another appropriate storage mechanism.&lt;/p&gt;

&lt;p&gt;Now any application instance can process the request.&lt;/p&gt;

&lt;p&gt;This has an important operational benefit.&lt;/p&gt;

&lt;p&gt;If a server disappears, another server can replace it without losing application state.&lt;/p&gt;

&lt;p&gt;Servers become relatively disposable compute units.&lt;/p&gt;

&lt;p&gt;That property is extremely useful in horizontally scaled environments.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4: The Database Becomes the Bottleneck
&lt;/h2&gt;

&lt;p&gt;Now imagine we have five application servers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Users
  ↓
Load Balancer
  ↓
Server Server Server Server Server
  ↓
Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application layer has scaled.&lt;/p&gt;

&lt;p&gt;But there is still one database.&lt;/p&gt;

&lt;p&gt;Every server is sending queries to it.&lt;/p&gt;

&lt;p&gt;Eventually, the database may become the limiting component.&lt;/p&gt;

&lt;p&gt;Before introducing database replication or sharding, investigate the fundamentals.&lt;/p&gt;

&lt;h3&gt;
  
  
  Indexes
&lt;/h3&gt;

&lt;p&gt;Indexes can dramatically reduce the amount of data a database needs to inspect for supported query patterns.&lt;/p&gt;

&lt;h3&gt;
  
  
  Query Optimization
&lt;/h3&gt;

&lt;p&gt;A query that scans unnecessary rows or performs expensive joins can consume significant resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  Connection Pooling
&lt;/h3&gt;

&lt;p&gt;Creating database connections repeatedly can be expensive.&lt;/p&gt;

&lt;p&gt;Connection pools allow applications to reuse connections.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pagination
&lt;/h3&gt;

&lt;p&gt;Returning 1 million rows when the user only needs 20 is unnecessary work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Avoiding N+1 Queries
&lt;/h3&gt;

&lt;p&gt;Fetching one record and then performing another query for every related record can create hundreds or thousands of database calls.&lt;/p&gt;

&lt;p&gt;These optimizations are often more valuable than immediately adding infrastructure.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A slow database query is still a slow query after you add more API servers.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 5: Database Replication
&lt;/h2&gt;

&lt;p&gt;After optimizing the database, the workload may still be too large.&lt;/p&gt;

&lt;p&gt;Many applications have a read-heavy workload.&lt;/p&gt;

&lt;p&gt;Think about an online store.&lt;/p&gt;

&lt;p&gt;A product might be viewed thousands of times while its price or description changes relatively infrequently.&lt;/p&gt;

&lt;p&gt;In such cases, database replication can distribute read traffic.&lt;/p&gt;

&lt;p&gt;A simplified architecture looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             Application
                 |
          +------+------+
          |             |
          ↓             ↓
       Primary      Read Replica
       Writes          Reads
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The primary handles writes.&lt;/p&gt;

&lt;p&gt;Replicas can serve appropriate read queries.&lt;/p&gt;

&lt;p&gt;This can reduce pressure on the primary database.&lt;/p&gt;

&lt;p&gt;But there is an important trade-off.&lt;/p&gt;

&lt;h2&gt;
  
  
  Replication Lag
&lt;/h2&gt;

&lt;p&gt;Suppose a user updates their profile.&lt;/p&gt;

&lt;p&gt;The write reaches the primary database immediately.&lt;/p&gt;

&lt;p&gt;The replica may receive that change slightly later.&lt;/p&gt;

&lt;p&gt;If the next request reads from the replica, the user might temporarily see the old information.&lt;/p&gt;

&lt;p&gt;This creates a consistency question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Does this operation require the latest data, or is slightly stale data acceptable?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For some applications, a small amount of replication lag is acceptable.&lt;/p&gt;

&lt;p&gt;For others, it may not be.&lt;/p&gt;

&lt;p&gt;Therefore, replication isn't simply about making a database faster.&lt;/p&gt;

&lt;p&gt;It also requires designing how reads and writes interact.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6: Move Slow Work Out of the Request
&lt;/h2&gt;

&lt;p&gt;Now consider a different problem.&lt;/p&gt;

&lt;p&gt;Suppose a user requests a report.&lt;/p&gt;

&lt;p&gt;Generating that report requires:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Querying millions of records&lt;/li&gt;
&lt;li&gt;Processing the data&lt;/li&gt;
&lt;li&gt;Creating a file&lt;/li&gt;
&lt;li&gt;Uploading the file&lt;/li&gt;
&lt;li&gt;Sending an email&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If all of this happens inside the HTTP request, the user may be waiting for a very long time.&lt;/p&gt;

&lt;p&gt;Instead, the API can create a background job.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User
 ↓
API
 ↓
Queue
 ↓
Worker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The API can respond quickly while the worker performs the expensive operation asynchronously.&lt;/p&gt;

&lt;p&gt;This pattern is useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Email sending&lt;/li&gt;
&lt;li&gt;Video processing&lt;/li&gt;
&lt;li&gt;Image processing&lt;/li&gt;
&lt;li&gt;Report generation&lt;/li&gt;
&lt;li&gt;Notifications&lt;/li&gt;
&lt;li&gt;Data exports&lt;/li&gt;
&lt;li&gt;Scheduled processing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The queue creates a boundary between &lt;strong&gt;request processing&lt;/strong&gt; and &lt;strong&gt;background processing&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Queues Help During Traffic Spikes
&lt;/h2&gt;

&lt;p&gt;Queues are particularly useful when work arrives in bursts.&lt;/p&gt;

&lt;p&gt;Imagine a system normally receives:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;100 jobs/minute
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then a marketing campaign causes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10,000 jobs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the system tries to process all 10,000 immediately, downstream resources may become overwhelmed.&lt;/p&gt;

&lt;p&gt;A queue lets the system absorb the burst.&lt;/p&gt;

&lt;p&gt;Workers can process jobs at a sustainable rate.&lt;/p&gt;

&lt;p&gt;This is closely related to &lt;strong&gt;backpressure&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of forcing every component to operate at the speed of the fastest producer, the queue provides a buffer.&lt;/p&gt;

&lt;p&gt;But now we have another set of engineering problems.&lt;/p&gt;

&lt;p&gt;What if a worker crashes halfway through a job?&lt;/p&gt;

&lt;p&gt;What if the job is delivered twice?&lt;/p&gt;

&lt;p&gt;What if the job keeps failing?&lt;/p&gt;

&lt;p&gt;These lead to concepts such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Retries&lt;/li&gt;
&lt;li&gt;Acknowledgements&lt;/li&gt;
&lt;li&gt;Idempotency&lt;/li&gt;
&lt;li&gt;Dead-letter queues&lt;/li&gt;
&lt;li&gt;Visibility timeouts&lt;/li&gt;
&lt;li&gt;Retry backoff&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Idempotency: An Important Property of Background Jobs
&lt;/h2&gt;

&lt;p&gt;Suppose a worker processes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Send ₹1,000 payment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The worker completes the payment but crashes before acknowledging the message.&lt;/p&gt;

&lt;p&gt;The queue may deliver the same job again.&lt;/p&gt;

&lt;p&gt;If processing the job twice creates two payments, you have a serious problem.&lt;/p&gt;

&lt;p&gt;An &lt;strong&gt;idempotent operation&lt;/strong&gt; can safely be repeated without producing an incorrect additional effect.&lt;/p&gt;

&lt;p&gt;For example, instead of blindly creating a payment every time, the system might associate the operation with a unique transaction ID and ensure that the same transaction cannot be applied twice.&lt;/p&gt;

&lt;p&gt;This is an example of why distributed systems require more than just adding components.&lt;/p&gt;

&lt;p&gt;Once work can be retried, duplicated, delayed, or reordered, the application has to account for those possibilities.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 7: Scale Workers Independently
&lt;/h2&gt;

&lt;p&gt;Once background processing has been separated from API requests, the two workloads can scale independently.&lt;/p&gt;

&lt;p&gt;Suppose you have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10 API servers
3 workers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Later, video processing becomes much more popular.&lt;/p&gt;

&lt;p&gt;You might need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10 API servers
30 video workers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is no reason to increase API capacity simply because video processing became expensive.&lt;/p&gt;

&lt;p&gt;Different workloads have different resource requirements.&lt;/p&gt;

&lt;p&gt;An API may be mostly network and database bound.&lt;/p&gt;

&lt;p&gt;A video encoder may be CPU intensive.&lt;/p&gt;

&lt;p&gt;A machine-learning worker may require large amounts of memory or specialized hardware.&lt;/p&gt;

&lt;p&gt;Independent scaling allows each workload to receive the resources it actually needs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 8: When Does a Monolith Become a Problem?
&lt;/h2&gt;

&lt;p&gt;As the application grows, another kind of scaling problem can appear.&lt;/p&gt;

&lt;p&gt;The problem isn't necessarily CPU or memory.&lt;/p&gt;

&lt;p&gt;It is &lt;strong&gt;organizational and architectural complexity&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Imagine one huge application containing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Users
Orders
Payments
Search
Notifications
Analytics
Files
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application may still run perfectly well.&lt;/p&gt;

&lt;p&gt;But as the codebase grows, different teams may need to deploy different areas independently.&lt;/p&gt;

&lt;p&gt;One module may require very different scaling characteristics from another.&lt;/p&gt;

&lt;p&gt;This is where modular architecture becomes important.&lt;/p&gt;

&lt;p&gt;A good first step is often a &lt;strong&gt;modular monolith&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Keep the application as one deployable unit, but clearly separate its internal domains.&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 plaintext"&gt;&lt;code&gt;Application
├── Users
├── Orders
├── Payments
├── Search
└── Notifications
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives the codebase clear boundaries without immediately introducing distributed-system complexity.&lt;/p&gt;

&lt;p&gt;Only when those boundaries need independent deployment, scaling, ownership, or infrastructure should you consider separating them into services.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 9: Microservices and Their Cost
&lt;/h2&gt;

&lt;p&gt;A microservices architecture might eventually look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 API Gateway
                      |
        +-------------+-------------+
        |             |             |
      Users         Orders       Payments
      Service       Service       Service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each service can potentially have its own:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deployment lifecycle&lt;/li&gt;
&lt;li&gt;Scaling strategy&lt;/li&gt;
&lt;li&gt;Team ownership&lt;/li&gt;
&lt;li&gt;Data storage&lt;/li&gt;
&lt;li&gt;Technology choices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This can be useful.&lt;/p&gt;

&lt;p&gt;But there is a major trade-off.&lt;/p&gt;

&lt;p&gt;Inside a monolith:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Orders → Payment Module
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;might be a local function call.&lt;/p&gt;

&lt;p&gt;With microservices:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Orders Service
      ↓
Network
      ↓
Payment Service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you have network latency, timeouts, retries, authentication, serialization, and partial failures.&lt;/p&gt;

&lt;p&gt;The system can fail in ways that never existed inside the monolith.&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 plaintext"&gt;&lt;code&gt;Orders Service → Working
Payment Service → Working
Network → Failed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both services are healthy, but the request still fails.&lt;/p&gt;

&lt;p&gt;This is the fundamental cost of distribution.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Microservices don't remove complexity. They move complexity into the network and operations.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's why microservices should solve a specific problem rather than being treated as the default architecture for every large application.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 10: Observability Becomes Essential
&lt;/h2&gt;

&lt;p&gt;As the architecture becomes distributed, debugging becomes harder.&lt;/p&gt;

&lt;p&gt;Imagine a request travels through:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Load Balancer
      ↓
API
      ↓
Cache
      ↓
Orders Service
      ↓
Payment Service
      ↓
Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The request takes 4 seconds.&lt;/p&gt;

&lt;p&gt;Where did the delay happen?&lt;/p&gt;

&lt;p&gt;Was the cache slow?&lt;/p&gt;

&lt;p&gt;Was the database slow?&lt;/p&gt;

&lt;p&gt;Did the payment service take 3 seconds?&lt;/p&gt;

&lt;p&gt;Did a network request time out and retry?&lt;/p&gt;

&lt;p&gt;Without observability, answering these questions becomes difficult.&lt;/p&gt;

&lt;p&gt;This is why larger systems rely heavily on:&lt;/p&gt;

&lt;h3&gt;
  
  
  Logs
&lt;/h3&gt;

&lt;p&gt;Detailed records of events.&lt;/p&gt;

&lt;h3&gt;
  
  
  Metrics
&lt;/h3&gt;

&lt;p&gt;Numerical measurements such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Request rate&lt;/li&gt;
&lt;li&gt;Error rate&lt;/li&gt;
&lt;li&gt;CPU&lt;/li&gt;
&lt;li&gt;Memory&lt;/li&gt;
&lt;li&gt;Latency&lt;/li&gt;
&lt;li&gt;Database connections&lt;/li&gt;
&lt;li&gt;Queue depth&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Traces
&lt;/h3&gt;

&lt;p&gt;A way to follow one request as it moves through multiple components.&lt;/p&gt;

&lt;p&gt;Observability is therefore not just something added after the system is built.&lt;/p&gt;

&lt;p&gt;For distributed systems, it becomes part of the system itself.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 11: Design for Failure
&lt;/h2&gt;

&lt;p&gt;A system with one server has a relatively small number of failure modes.&lt;/p&gt;

&lt;p&gt;A distributed system has many more.&lt;/p&gt;

&lt;p&gt;A cache can fail.&lt;/p&gt;

&lt;p&gt;A database replica can fall behind.&lt;/p&gt;

&lt;p&gt;A queue can become full.&lt;/p&gt;

&lt;p&gt;A worker can crash.&lt;/p&gt;

&lt;p&gt;A service can time out.&lt;/p&gt;

&lt;p&gt;A network connection can fail.&lt;/p&gt;

&lt;p&gt;A deployment can introduce an error.&lt;/p&gt;

&lt;p&gt;So as the architecture grows, a new question becomes increasingly important:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What happens when something fails?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Consider a cache.&lt;/p&gt;

&lt;p&gt;If the cache disappears, can the application still read from the database?&lt;/p&gt;

&lt;p&gt;Consider a worker.&lt;/p&gt;

&lt;p&gt;If it crashes halfway through a job, can another worker safely retry it?&lt;/p&gt;

&lt;p&gt;Consider a database replica.&lt;/p&gt;

&lt;p&gt;If it becomes unavailable, can the application temporarily route reads elsewhere?&lt;/p&gt;

&lt;p&gt;Consider a service.&lt;/p&gt;

&lt;p&gt;If it becomes slow, should the caller wait indefinitely?&lt;/p&gt;

&lt;p&gt;These questions lead to concepts such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Timeouts&lt;/li&gt;
&lt;li&gt;Retries&lt;/li&gt;
&lt;li&gt;Circuit breakers&lt;/li&gt;
&lt;li&gt;Failover&lt;/li&gt;
&lt;li&gt;Health checks&lt;/li&gt;
&lt;li&gt;Rate limiting&lt;/li&gt;
&lt;li&gt;Graceful degradation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Reliability is not the absence of failure.&lt;/p&gt;

&lt;p&gt;It is the ability of the system to behave sensibly when failures occur.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Realistic Scaling Journey
&lt;/h2&gt;

&lt;p&gt;Let's put everything together with an e-commerce example.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stage 1: Small Application
&lt;/h3&gt;

&lt;p&gt;You start with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Users
 ↓
API
 ↓
Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple, inexpensive, easy to operate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stage 2: Repeated Reads
&lt;/h3&gt;

&lt;p&gt;Product pages become popular.&lt;/p&gt;

&lt;p&gt;The database receives the same reads repeatedly.&lt;/p&gt;

&lt;p&gt;You introduce caching.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Users
 ↓
API
 ↓
Cache
 ↓
Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Stage 3: More Traffic
&lt;/h3&gt;

&lt;p&gt;The API server becomes overloaded.&lt;/p&gt;

&lt;p&gt;You add multiple instances behind a load balancer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Users
 ↓
Load Balancer
 ↓
API API API
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Stage 4: Database Pressure
&lt;/h3&gt;

&lt;p&gt;The database becomes the next bottleneck.&lt;/p&gt;

&lt;p&gt;You optimize queries, add indexes, and improve connection management.&lt;/p&gt;

&lt;p&gt;If read traffic is still high, you introduce replicas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stage 5: Background Work
&lt;/h3&gt;

&lt;p&gt;The application starts generating invoices, processing images, and sending notifications.&lt;/p&gt;

&lt;p&gt;You move those tasks into a queue.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;API
 ↓
Queue
 ↓
Workers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Stage 6: Independent Workloads
&lt;/h3&gt;

&lt;p&gt;Image processing becomes much heavier than normal API traffic.&lt;/p&gt;

&lt;p&gt;You scale image workers independently.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stage 7: Organizational Growth
&lt;/h3&gt;

&lt;p&gt;The engineering organization becomes larger.&lt;/p&gt;

&lt;p&gt;Payments, orders, search, and notifications have different requirements.&lt;/p&gt;

&lt;p&gt;You introduce stronger module boundaries.&lt;/p&gt;

&lt;p&gt;Some modules may eventually become independent services.&lt;/p&gt;

&lt;p&gt;Notice what happened.&lt;/p&gt;

&lt;p&gt;The final architecture wasn't designed on day one.&lt;/p&gt;

&lt;p&gt;It evolved because each new problem required a different solution.&lt;/p&gt;

&lt;p&gt;That is how many real systems grow.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Architecture Is a Set of Trade-Offs
&lt;/h2&gt;

&lt;p&gt;There is no architecture that is simultaneously:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cheapest&lt;/li&gt;
&lt;li&gt;Fastest&lt;/li&gt;
&lt;li&gt;Simplest&lt;/li&gt;
&lt;li&gt;Most available&lt;/li&gt;
&lt;li&gt;Most consistent&lt;/li&gt;
&lt;li&gt;Most scalable&lt;/li&gt;
&lt;li&gt;Easiest to operate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every decision changes something else.&lt;/p&gt;

&lt;p&gt;Caching can improve latency but introduce stale data.&lt;/p&gt;

&lt;p&gt;Replication can increase read capacity but introduce replication lag.&lt;/p&gt;

&lt;p&gt;Queues can protect the API from expensive background work but introduce asynchronous behavior.&lt;/p&gt;

&lt;p&gt;Microservices can provide independent deployment and scaling but introduce distributed-system complexity.&lt;/p&gt;

&lt;p&gt;Horizontal scaling can increase capacity but requires stateless application design and shared infrastructure.&lt;/p&gt;

&lt;p&gt;This is why system design is fundamentally about trade-offs.&lt;/p&gt;

&lt;p&gt;You aren't searching for the perfect architecture.&lt;/p&gt;

&lt;p&gt;You're choosing the architecture whose trade-offs make sense for the problem.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Better Way to Think About Scaling
&lt;/h2&gt;

&lt;p&gt;Instead of memorizing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Caching
Load Balancer
Replication
Queue
Microservices
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;think in terms of the problems they solve.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Problem&lt;/th&gt;
&lt;th&gt;Possible Solution&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Repeated expensive reads&lt;/td&gt;
&lt;td&gt;Caching&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;One server cannot handle traffic&lt;/td&gt;
&lt;td&gt;Horizontal scaling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Requests depend on local state&lt;/td&gt;
&lt;td&gt;Externalize shared state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database queries are slow&lt;/td&gt;
&lt;td&gt;Indexing and query optimization&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Too many database reads&lt;/td&gt;
&lt;td&gt;Replication / caching&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Long-running requests&lt;/td&gt;
&lt;td&gt;Asynchronous processing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Background workload increases&lt;/td&gt;
&lt;td&gt;Worker scaling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Large codebase becomes difficult to manage&lt;/td&gt;
&lt;td&gt;Modular architecture&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Independent deployment is required&lt;/td&gt;
&lt;td&gt;Service boundaries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Distributed system is difficult to debug&lt;/td&gt;
&lt;td&gt;Observability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Components fail independently&lt;/td&gt;
&lt;td&gt;Resilience mechanisms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is much more useful than memorizing architecture diagrams.&lt;/p&gt;

&lt;p&gt;When you encounter a new system-design problem, ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What is the bottleneck?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What is the smallest architectural change that can remove it?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The Complete Mental Model
&lt;/h2&gt;

&lt;p&gt;A mature backend might eventually look 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;                         Users
                           |
                           v
                     Load Balancer
                           |
                  +--------+--------+
                  |        |        |
                  v        v        v
               Server   Server   Server
                  |
             +----+----+
             |         |
             v         v
           Cache    Database
                       |
                 +-----+-----+
                 |           |
                 v           v
              Primary    Read Replica

                       |
                       v
                     Queue
                    / | \
                   /  |  \
                  v   v   v
              Worker Worker Worker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And parts of the application may eventually become independent services.&lt;/p&gt;

&lt;p&gt;But this diagram is &lt;strong&gt;not a blueprint&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It is a collection of patterns.&lt;/p&gt;

&lt;p&gt;You might use only three of them.&lt;/p&gt;

&lt;p&gt;You might use ten.&lt;/p&gt;

&lt;p&gt;You might replace some entirely.&lt;/p&gt;

&lt;p&gt;The right architecture depends on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Traffic&lt;/li&gt;
&lt;li&gt;Data volume&lt;/li&gt;
&lt;li&gt;Latency requirements&lt;/li&gt;
&lt;li&gt;Consistency requirements&lt;/li&gt;
&lt;li&gt;Availability requirements&lt;/li&gt;
&lt;li&gt;Team structure&lt;/li&gt;
&lt;li&gt;Budget&lt;/li&gt;
&lt;li&gt;Operational maturity&lt;/li&gt;
&lt;li&gt;Failure tolerance&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Most Important Lesson
&lt;/h2&gt;

&lt;p&gt;The biggest mistake in system design is thinking that a large architecture is automatically a better architecture.&lt;/p&gt;

&lt;p&gt;It isn't.&lt;/p&gt;

&lt;p&gt;A simple architecture that reliably handles 10,000 users is better than an unnecessarily complicated architecture that creates operational problems.&lt;/p&gt;

&lt;p&gt;And a simple architecture that works today may not be sufficient tomorrow.&lt;/p&gt;

&lt;p&gt;That's okay.&lt;/p&gt;

&lt;p&gt;Architecture is allowed to evolve.&lt;/p&gt;

&lt;p&gt;The goal isn't to predict the future perfectly.&lt;/p&gt;

&lt;p&gt;The goal is to build a system that can evolve when the future arrives.&lt;/p&gt;

&lt;p&gt;So the backend scaling journey can be summarized as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;More Users
     ↓
More Work
     ↓
Measure
     ↓
Find the Bottleneck
     ↓
Reduce Work OR Add Capacity
     ↓
Measure Again
     ↓
Repeat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sometimes reducing work means caching.&lt;/p&gt;

&lt;p&gt;Sometimes it means optimizing a query.&lt;/p&gt;

&lt;p&gt;Sometimes adding capacity means more servers.&lt;/p&gt;

&lt;p&gt;Sometimes it means read replicas.&lt;/p&gt;

&lt;p&gt;Sometimes it means more workers.&lt;/p&gt;

&lt;p&gt;And sometimes the problem isn't performance at all—it is code ownership or organizational complexity.&lt;/p&gt;

&lt;p&gt;That's when modularity and service boundaries become important.&lt;/p&gt;




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

&lt;p&gt;You don't start with a distributed system.&lt;/p&gt;

&lt;p&gt;You &lt;strong&gt;grow into one&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A backend might begin as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server + Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then evolve into:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Load Balancer
+ Multiple Servers
+ Cache
+ Database Replication
+ Queue
+ Workers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And eventually, parts of the system may become independent services.&lt;/p&gt;

&lt;p&gt;But every step should have a reason.&lt;/p&gt;

&lt;p&gt;Before adding a new component, ask two questions:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What problem does this solve?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What new complexity does this introduce?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you can answer both, you're not just adding technologies.&lt;/p&gt;

&lt;p&gt;You're designing a system.&lt;/p&gt;

&lt;p&gt;And that is the real skill behind scaling big backend applications.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>backend</category>
      <category>performance</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>What Happens When Your Backend Gets 1 Million Requests?</title>
      <dc:creator>Tanu Priya</dc:creator>
      <pubDate>Fri, 18 Sep 2026 08:27:13 +0000</pubDate>
      <link>https://dev.to/tanu_priya/what-happens-when-your-backend-gets-1-million-requests-31ko</link>
      <guid>https://dev.to/tanu_priya/what-happens-when-your-backend-gets-1-million-requests-31ko</guid>
      <description>&lt;p&gt;An API can look perfectly fine during development.&lt;/p&gt;

&lt;p&gt;You test it locally, everything responds quickly, and a single server seems more than enough.&lt;/p&gt;

&lt;p&gt;Then traffic grows.&lt;/p&gt;

&lt;p&gt;Suddenly, the server is handling thousands of requests at the same time. CPU usage increases, database queries pile up, response times get worse, and eventually requests start failing.&lt;/p&gt;

&lt;p&gt;At that point, the solution usually isn't just a bigger server.&lt;/p&gt;

&lt;p&gt;You need to change how the system is designed.&lt;/p&gt;

&lt;p&gt;A common architecture 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;                         Users
                           |
                           v
                    Load Balancer
                    /     |     \
                   v      v      v
                Server  Server  Server
                   \      |      /
                    \     |     /
                      Cache
                        |
                        v
                     Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For work that doesn't need to happen during the request, a queue can be added:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;API Server
    |
    v
  Queue
    |
    +----&amp;gt; Worker
    +----&amp;gt; Worker
    +----&amp;gt; Worker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the point where backend development starts becoming system design.&lt;/p&gt;




&lt;h2&gt;
  
  
  The First Problem: One Server
&lt;/h2&gt;

&lt;p&gt;Start with the simplest architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Users
  |
  v
Server
  |
  v
Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every request reaches the same server.&lt;/p&gt;

&lt;p&gt;That server handles authentication, business logic, database queries, API responses, and potentially background work too.&lt;/p&gt;

&lt;p&gt;As traffic increases, its resources become limited:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CPU       → High
Memory    → High
Latency   → Increasing
Errors    → Increasing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can move to a larger machine.&lt;/p&gt;

&lt;p&gt;That's &lt;strong&gt;vertical scaling&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But eventually, a single machine still has a ceiling.&lt;/p&gt;

&lt;p&gt;The other option is to add more servers.&lt;/p&gt;




&lt;h2&gt;
  
  
  Horizontal Scaling
&lt;/h2&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Users
  |
  v
One Server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;we can have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             Load Balancer
              /    |    \
             v     v     v
          Server Server Server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is &lt;strong&gt;horizontal scaling&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The load balancer distributes incoming requests across available servers.&lt;/p&gt;

&lt;p&gt;For example, if three servers are handling traffic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10,000 requests/sec
        |
        v
Load Balancer
   /     |     \
3333   3333   3334
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The actual distribution won't always be perfectly equal. It depends on the load-balancing strategy and the workload.&lt;/p&gt;

&lt;p&gt;Common strategies include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Round Robin
Least Connections
Weighted Routing
IP Hash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important idea is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Spread the work instead of depending on one machine.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Keeping Servers Stateless
&lt;/h2&gt;

&lt;p&gt;Multiple servers introduce another problem.&lt;/p&gt;

&lt;p&gt;Suppose a user logs in through Server 1.&lt;/p&gt;

&lt;p&gt;If the login state exists only in Server 1's memory, the next request could reach Server 3.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Login
  ↓
Server 1
  ↓
Session stored locally

Next request
  ↓
Server 3
  ↓
Session not found
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is one reason scalable applications generally avoid keeping important shared state only in a server's local memory.&lt;/p&gt;

&lt;p&gt;Instead, shared state can be stored in something accessible to all instances:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server 1 ─┐
Server 2 ─┼──&amp;gt; Redis / Database
Server 3 ─┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now any server can handle the next request.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Database Becomes the Next Bottleneck
&lt;/h2&gt;

&lt;p&gt;Adding more backend servers doesn't automatically solve the whole problem.&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 plaintext"&gt;&lt;code&gt;             Load Balancer
            /      |      \
        Server   Server   Server
            \      |      /
                 Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now three servers can process requests, but all of them are still querying the same database.&lt;/p&gt;

&lt;p&gt;The database may become the bottleneck.&lt;/p&gt;

&lt;p&gt;This leads to an important system-design principle:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;When you remove one bottleneck, another one often becomes visible.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So instead of sending every request to the database, we can reduce unnecessary database work.&lt;/p&gt;




&lt;h2&gt;
  
  
  Caching
&lt;/h2&gt;

&lt;p&gt;Suppose thousands of users request the same product:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /api/products/123
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without caching:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request
   ↓
Server
   ↓
Database
   ↓
Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With a cache:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request
   ↓
Server
   ↓
Cache
   |
   +---- Hit → Response
   |
   +---- Miss
          ↓
       Database
          ↓
        Cache
          ↓
       Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the requested data is already in the cache, the database doesn't need to process another query.&lt;/p&gt;

&lt;p&gt;A simple example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1,000 requests
      ↓
    Cache
      ↓
900 cache hits
      ↓
100 database requests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The numbers are just an example. The actual benefit depends on the application's traffic and cache-hit rate.&lt;/p&gt;

&lt;p&gt;Redis is commonly used for this kind of workload.&lt;/p&gt;




&lt;h2&gt;
  
  
  But Caching Creates Another Problem
&lt;/h2&gt;

&lt;p&gt;What happens when the database changes?&lt;/p&gt;

&lt;p&gt;Suppose the cache contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;product:123 → ₹999
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then the database is updated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;₹999 → ₹899
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The cache may still contain the old value.&lt;/p&gt;

&lt;p&gt;Now the application can return stale data.&lt;/p&gt;

&lt;p&gt;This is why caching isn't simply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Put Redis in front of the database."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You also need to think about:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TTL
Invalidation
Cache-aside
Write-through
Stale data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Caching can reduce database load significantly, but it introduces another system that needs to be designed and maintained.&lt;/p&gt;




&lt;h2&gt;
  
  
  Not Every Task Belongs in the Request
&lt;/h2&gt;

&lt;p&gt;Some operations are expensive but don't need to finish before the user gets a response.&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 plaintext"&gt;&lt;code&gt;Upload video
     ↓
Process video
     ↓
Generate thumbnails
     ↓
Send notifications
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Doing all of this inside the API request can make the endpoint slow.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client
  |
  v
API Server
  |
  v
Queue
  |
  +----&amp;gt; Worker 1
  +----&amp;gt; Worker 2
  +----&amp;gt; Worker 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The API creates a job and puts it into the queue.&lt;/p&gt;

&lt;p&gt;Workers process those jobs separately.&lt;/p&gt;

&lt;p&gt;This works well for things such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Emails
Notifications
Image processing
Video processing
Reports
Data exports
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The queue acts as a buffer between incoming requests and background processing.&lt;/p&gt;




&lt;h2&gt;
  
  
  A More Complete Architecture
&lt;/h2&gt;

&lt;p&gt;Putting the pieces together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                         Users
                           |
                           v
                    Load Balancer
                           |
              +------------+------------+
              |            |            |
              v            v            v
          Server 1     Server 2     Server 3
              |            |            |
              +------------+------------+
                           |
                    +------+------+
                    |             |
                    v             v
                  Cache        Database
                                  |
                                  v
                             Read Replica

              Server
                 |
                 v
               Queue
                 |
          +------+------+ 
          |      |      |
          v      v      v
       Worker  Worker  Worker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each component has a different responsibility:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Load Balancer
→ Distributes requests

Servers
→ Run application logic

Cache
→ Avoids repeated expensive reads

Database
→ Stores persistent data

Queue
→ Holds asynchronous work

Workers
→ Process background jobs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the important part of this architecture.&lt;/p&gt;

&lt;p&gt;You're not adding technologies randomly.&lt;/p&gt;

&lt;p&gt;You're adding them because a specific part of the system needs help.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Happens During a Traffic Spike?
&lt;/h2&gt;

&lt;p&gt;Imagine your application normally receives:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10,000 requests/minute
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then traffic suddenly jumps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;100,000 requests/minute
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A scalable architecture might handle the increase 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;Traffic Spike
     ↓
Load Balancer
     ↓
Multiple Servers
     ↓
Cache handles repeated reads
     ↓
Database handles remaining queries
     ↓
Queue absorbs background work
     ↓
Workers process jobs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the infrastructure supports autoscaling, more application instances can be started as demand increases.&lt;/p&gt;

&lt;p&gt;But simply adding servers isn't enough.&lt;/p&gt;

&lt;p&gt;You have to understand where the actual bottleneck is.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Database Has Its Own Scaling Problems
&lt;/h2&gt;

&lt;p&gt;At larger workloads, the database may need additional techniques:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Indexing
Connection Pooling
Query Optimization
Read Replicas
Partitioning
Sharding
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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;                 Database
                /        \
               v          v
           Primary     Read Replica
            Writes         Reads
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But these aren't default requirements for every application.&lt;/p&gt;

&lt;p&gt;If a database handles your workload comfortably, adding replicas or sharding can add unnecessary complexity.&lt;/p&gt;

&lt;p&gt;The architecture should follow the workload.&lt;/p&gt;




&lt;h2&gt;
  
  
  One Million Requests Doesn't Tell the Whole Story
&lt;/h2&gt;

&lt;p&gt;The number &lt;strong&gt;1 million requests&lt;/strong&gt; sounds huge, but request count alone doesn't tell us how difficult the system is.&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 plaintext"&gt;&lt;code&gt;1 million requests
→ Simple cached reads
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1 million requests
→ Complex queries
→ Multiple database writes
→ External API calls
→ File processing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are very different workloads.&lt;/p&gt;

&lt;p&gt;When designing for scale, ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;How many requests per second?

How expensive is each request?

How much data does each request access?

How much traffic can be cached?

How many requests reach the database?

Which operations can run asynchronously?

What happens when a server fails?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These questions are much more useful than simply asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Can my backend handle 1 million requests?"&lt;/p&gt;
&lt;/blockquote&gt;




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

&lt;p&gt;When traffic increases, don't immediately think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I need a bigger server."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Where is the bottleneck?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then solve that specific problem.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;More Traffic
     ↓
Load Balancer
     ↓
More Servers
     ↓
Cache
     ↓
Database
     ↓
Queue + Workers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The load balancer distributes traffic.&lt;/p&gt;

&lt;p&gt;Multiple servers increase application capacity.&lt;/p&gt;

&lt;p&gt;The cache reduces repeated work.&lt;/p&gt;

&lt;p&gt;The database stores persistent data.&lt;/p&gt;

&lt;p&gt;The queue moves expensive work out of the request path.&lt;/p&gt;

&lt;p&gt;Workers process that work independently.&lt;/p&gt;

&lt;p&gt;That's the transition from &lt;strong&gt;building an API&lt;/strong&gt; to &lt;strong&gt;engineering a system&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A backend that works for 100 users and a backend that works for millions of users can use the same basic code.&lt;/p&gt;

&lt;p&gt;What changes is how you design the system around that code.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>backend</category>
      <category>performance</category>
      <category>scalability</category>
    </item>
    <item>
      <title>How Do Backend Developers Secure APIs?</title>
      <dc:creator>Tanu Priya</dc:creator>
      <pubDate>Thu, 17 Sep 2026 05:51:08 +0000</pubDate>
      <link>https://dev.to/tanu_priya/how-do-backend-developers-secure-apis-4ho1</link>
      <guid>https://dev.to/tanu_priya/how-do-backend-developers-secure-apis-4ho1</guid>
      <description>&lt;p&gt;Building an API is only half the job.&lt;/p&gt;

&lt;p&gt;Once an API is exposed to real users, you have to think about what happens when someone sends unexpected input, calls an endpoint they shouldn't, sends thousands of requests, or gets access to a secret.&lt;/p&gt;

&lt;p&gt;That's why API security isn't a single feature. It's a collection of layers that protect different parts of the application.&lt;/p&gt;

&lt;p&gt;A typical request might go through:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request
   ↓
Authentication
   ↓
Authorization
   ↓
Validation
   ↓
Rate Limiting
   ↓
Business Logic
   ↓
Database
   ↓
Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's look at the important parts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authentication
&lt;/h2&gt;

&lt;p&gt;The first question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Who is making this request?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /api/profile
Authorization: Bearer &amp;lt;token&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The backend verifies the credentials and identifies the user.&lt;/p&gt;

&lt;p&gt;If authentication fails:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Invalid / missing credentials
        ↓
401 Unauthorized
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Authentication establishes identity, but it doesn't decide what that user can access.&lt;/p&gt;

&lt;p&gt;That's authorization's job.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authorization
&lt;/h2&gt;

&lt;p&gt;Suppose two users are logged in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Alex → user
Sarah → admin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alex sends:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;DELETE /api/users/100
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The backend shouldn't simply check whether Alex is logged in.&lt;/p&gt;

&lt;p&gt;It should also check whether Alex has permission to delete that user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authenticated user
       ↓
Permission check
       ↓
Allowed?
   ├── No → 403 Forbidden
   └── Yes → Continue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This check must happen on the &lt;strong&gt;backend&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Hiding a button in the frontend is not authorization.&lt;/p&gt;

&lt;p&gt;A user can always send the API request directly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Validate Client Input
&lt;/h2&gt;

&lt;p&gt;Never assume that data from the frontend is trustworthy.&lt;/p&gt;

&lt;p&gt;A client might send:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"age"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;-50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"admin"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;even if your frontend never allows those values.&lt;/p&gt;

&lt;p&gt;The backend should validate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Required fields
Data types
Formats
Lengths
Allowed values
Business rules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A useful rule is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Frontend validation improves the user experience. Backend validation protects the application.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  SQL Injection
&lt;/h2&gt;

&lt;p&gt;One classic API vulnerability is SQL injection.&lt;/p&gt;

&lt;p&gt;This is dangerous:&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;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="s2"&gt;`SELECT * FROM users WHERE email = '&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="s2"&gt;'`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;User input is being inserted directly into the SQL statement.&lt;/p&gt;

&lt;p&gt;Instead, use parameterized 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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SELECT * FROM users WHERE email = $1&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;email&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 database can then treat the supplied value as data rather than SQL syntax.&lt;/p&gt;

&lt;p&gt;The same principle applies when using ORMs: use their parameterized query mechanisms rather than constructing raw SQL from untrusted input.&lt;/p&gt;

&lt;h2&gt;
  
  
  XSS
&lt;/h2&gt;

&lt;p&gt;XSS stands for &lt;strong&gt;Cross-Site Scripting&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Consider a comment system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User input
   ↓
API
   ↓
Database
   ↓
Browser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the application later renders that content as executable HTML or JavaScript, an attacker could potentially run code in another user's browser.&lt;/p&gt;

&lt;p&gt;Common defenses include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Safe rendering
Output encoding
Avoiding unsafe HTML injection
Content Security Policy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important lesson is that data stored in your database isn't automatically safe.&lt;/p&gt;

&lt;p&gt;It may have originally come from an untrusted user.&lt;/p&gt;

&lt;h2&gt;
  
  
  CSRF
&lt;/h2&gt;

&lt;p&gt;CSRF stands for &lt;strong&gt;Cross-Site Request Forgery&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It is particularly relevant when authentication uses cookies because browsers can automatically send cookies with requests.&lt;/p&gt;

&lt;p&gt;A simplified attack looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User is logged in
      ↓
Authentication cookie
      ↓
Malicious website
      ↓
Forged request
      ↓
Your API
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depending on the application, protections can include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SameSite cookies
CSRF tokens
Origin validation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The right defense depends on how authentication and browser requests are designed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rate Limiting
&lt;/h2&gt;

&lt;p&gt;An attacker can automate requests to endpoints such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Login
OTP verification
Password reset
Search
Expensive API operations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without limits:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Attacker
   ↓
Thousands of requests
   ↓
Backend
   ↓
Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rate limiting can stop excessive traffic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Too many requests
       ↓
429 Too Many Requests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rate limiting isn't only about preventing brute-force attacks. It can also protect backend resources from accidental or malicious traffic spikes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Protect Your Secrets
&lt;/h2&gt;

&lt;p&gt;Backend applications often use sensitive credentials:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Database passwords
JWT signing keys
API keys
Cloud credentials
Payment provider secrets
OAuth secrets
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't put them directly into source 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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;my-secret-key&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;Use environment configuration or a dedicated secret-management system instead:&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;secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;JWT_SECRET&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also remember that secrets can leak through more than source code.&lt;/p&gt;

&lt;p&gt;Watch out for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Git repositories
Logs
Error messages
Frontend bundles
Debug endpoints
Screenshots
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A secret is only useful if it stays secret.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTTPS and Encryption
&lt;/h2&gt;

&lt;p&gt;API traffic should use HTTPS.&lt;/p&gt;

&lt;p&gt;Without HTTPS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client
   ↓
Network
   ↓
Server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With HTTPS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client
   ↓
Encrypted TLS connection
   ↓
Server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;HTTPS protects data while it travels between the client and server.&lt;/p&gt;

&lt;p&gt;This is especially important for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Passwords
Cookies
Tokens
Personal data
Payment information
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Encryption protects the connection, but it doesn't decide whether the authenticated user has permission to access a resource.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security Headers
&lt;/h2&gt;

&lt;p&gt;HTTP security headers can provide additional browser protections.&lt;/p&gt;

&lt;p&gt;Common examples include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Content-Security-Policy
Strict-Transport-Security
X-Content-Type-Options
Referrer-Policy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, Content Security Policy can restrict where a browser is allowed to load scripts and other resources.&lt;/p&gt;

&lt;p&gt;These headers don't replace secure application code, but they add another layer of defense.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't Return More Data Than Necessary
&lt;/h2&gt;

&lt;p&gt;Suppose your database contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;id
name
email
password_hash
internal_notes
created_at
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your API probably doesn't need to return all of it.&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 sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;select only what the client needs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same applies to error messages.&lt;/p&gt;

&lt;p&gt;Avoid exposing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Database credentials
SQL queries
Internal file paths
Stack traces
Private service information
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The client usually needs a simple error, while detailed information can remain in protected server logs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't Trust IDs From the Client
&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 http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /api/orders/123
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The user is authenticated.&lt;/p&gt;

&lt;p&gt;That's not enough.&lt;/p&gt;

&lt;p&gt;The backend should check whether that particular order belongs to that user.&lt;/p&gt;

&lt;p&gt;Otherwise, someone might change:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/api/orders/123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/api/orders/124
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and access another user's data.&lt;/p&gt;

&lt;p&gt;The check should be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authenticated user
       ↓
Requested resource
       ↓
Does the user have access?
       ↓
Allow / Reject
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a common authorization problem in APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Logging and Monitoring
&lt;/h2&gt;

&lt;p&gt;Security also means being able to notice suspicious activity.&lt;/p&gt;

&lt;p&gt;Useful events to track include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Failed logins
Permission failures
Password reset attempts
Rate-limit violations
Administrative actions
Unusual request patterns
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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;User 42
DELETE /api/users/100
Authorization denied
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But don't casually log sensitive credentials.&lt;/p&gt;

&lt;p&gt;Avoid storing things such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Passwords
Access tokens
Refresh tokens
API keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Logs can become a security risk themselves if they contain secrets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Defense in Depth
&lt;/h2&gt;

&lt;p&gt;At this point, the bigger picture becomes clear.&lt;/p&gt;

&lt;p&gt;API security isn't about finding one perfect security mechanism.&lt;/p&gt;

&lt;p&gt;It's about having several layers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    Request
                       ↓
                 Rate Limiting
                       ↓
                Authentication
                       ↓
                 Authorization
                       ↓
                  Validation
                       ↓
                 Business Logic
                       ↓
                    Database
                       ↓
                   Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And around the application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTPS
Security Headers
Secret Management
Logging
Monitoring
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each layer deals with a different type of problem.&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 plaintext"&gt;&lt;code&gt;SQL Injection
→ Parameterized queries

XSS
→ Safe rendering + output handling

CSRF
→ Appropriate CSRF protections

Brute Force
→ Rate limiting

Broken Authorization
→ Server-side permission checks

Exposed Secrets
→ Secret management
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If one layer fails, another layer can still limit the damage.&lt;/p&gt;

&lt;p&gt;That's the basic idea behind &lt;strong&gt;defense in depth&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Practical Checklist
&lt;/h2&gt;

&lt;p&gt;Before putting an API into production, ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authentication
[ ] Are protected endpoints authenticated?

Authorization
[ ] Are permissions checked on the server?
[ ] Can users access other users' resources?

Validation
[ ] Are request bodies validated?
[ ] Are query parameters validated?

Database
[ ] Are queries parameterized?

Rate Limiting
[ ] Are login and expensive endpoints protected?

Secrets
[ ] Are credentials outside the source code?
[ ] Are secrets excluded from logs?

Transport
[ ] Is HTTPS enabled?

Browser Security
[ ] Are cookies configured appropriately?
[ ] Are CSRF protections considered?

Monitoring
[ ] Are suspicious activities detectable?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This isn't a complete security audit, but it's a good starting point.&lt;/p&gt;

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

&lt;p&gt;When securing an API, think about the request one question at a time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Who is making the request?
        ↓
Authentication

What can they access?
        ↓
Authorization

Is the input valid?
        ↓
Validation

Are they sending too many requests?
        ↓
Rate Limiting

Can the connection be intercepted?
        ↓
HTTPS

Can browser behavior be abused?
        ↓
CSRF / Security Headers

Are credentials protected?
        ↓
Secret Management

Can suspicious behavior be detected?
        ↓
Logging / Monitoring
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The main lesson is simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;API security isn't a feature you add once. It's a collection of decisions made throughout the backend.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Authentication tells you who the user is.&lt;/p&gt;

&lt;p&gt;Authorization controls what they can access.&lt;/p&gt;

&lt;p&gt;Validation keeps unexpected input out of your application logic.&lt;/p&gt;

&lt;p&gt;Rate limiting controls abusive traffic.&lt;/p&gt;

&lt;p&gt;HTTPS protects data in transit.&lt;/p&gt;

&lt;p&gt;And careful secret management prevents credentials from becoming an easy attack path.&lt;/p&gt;

&lt;p&gt;The most useful question isn't:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Is my API secure?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"What could go wrong at each stage of this request, and what prevents it?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's the mindset that helps turn a working API into a secure one.&lt;/p&gt;

</description>
      <category>api</category>
      <category>backend</category>
      <category>security</category>
    </item>
    <item>
      <title>Cookies vs Sessions vs JWT: What's the Difference?</title>
      <dc:creator>Tanu Priya</dc:creator>
      <pubDate>Wed, 16 Sep 2026 08:22:51 +0000</pubDate>
      <link>https://dev.to/tanu_priya/cookies-vs-sessions-vs-jwt-whats-the-difference-3l7n</link>
      <guid>https://dev.to/tanu_priya/cookies-vs-sessions-vs-jwt-whats-the-difference-3l7n</guid>
      <description>&lt;p&gt;When you build a login system, you'll quickly run into three terms:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cookies, sessions, and JWTs.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;They are often mentioned together, which makes it easy to assume that they are three different ways of doing the exact same thing.&lt;/p&gt;

&lt;p&gt;They're not.&lt;/p&gt;

&lt;p&gt;A cookie is mainly a way for a browser to store and send data.&lt;/p&gt;

&lt;p&gt;A session is server-side state that can be used to remember a logged-in user.&lt;/p&gt;

&lt;p&gt;A JWT is a signed token that can carry information about an authenticated user.&lt;/p&gt;

&lt;p&gt;The confusion usually starts because these things can also be used &lt;strong&gt;together&lt;/strong&gt;.&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 plaintext"&gt;&lt;code&gt;Browser
   ↓
Cookie
   ↓
Session ID
   ↓
Server-side Session
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser
   ↓
Cookie
   ↓
JWT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So instead of asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Which one is better?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;it's more useful to understand what each one actually does and then decide which combination fits your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  First, What Problem Are We Solving?
&lt;/h2&gt;

&lt;p&gt;Let's start with a normal login.&lt;/p&gt;

&lt;p&gt;A user sends:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST /api/login
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"alex@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mypassword"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The backend verifies the credentials.&lt;/p&gt;

&lt;p&gt;Let's say they are correct.&lt;/p&gt;

&lt;p&gt;The server now knows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User ID: 42
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But what happens when the user makes another request?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /api/profile
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;HTTP doesn't automatically remember that the previous request was a successful login.&lt;/p&gt;

&lt;p&gt;The application needs a way to recognize the user again.&lt;/p&gt;

&lt;p&gt;That's the problem these authentication mechanisms help solve.&lt;/p&gt;




&lt;h2&gt;
  
  
  Cookies: How Does the Browser Remember Something?
&lt;/h2&gt;

&lt;p&gt;Let's start with cookies because they are the easiest to misunderstand.&lt;/p&gt;

&lt;p&gt;A cookie is not an authentication system by itself.&lt;/p&gt;

&lt;p&gt;It's a small piece of data that a browser can store and send back to a website.&lt;/p&gt;

&lt;p&gt;A server can send:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Set-Cookie: session_id=abc123
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser stores it.&lt;/p&gt;

&lt;p&gt;Later, when making another request to the relevant site, the browser can send:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Cookie: session_id=abc123
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;You can think of a cookie as a &lt;strong&gt;container for a value that the browser knows how to send back to the server&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That value could be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;session_id
authentication-related data
preferences
language settings
analytics identifiers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cookie ≠ Session
Cookie ≠ JWT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A cookie is a transport/storage mechanism.&lt;/p&gt;

&lt;p&gt;What you put in it determines how it's being used.&lt;/p&gt;




&lt;h2&gt;
  
  
  Sessions: Keep the Login State on the Server
&lt;/h2&gt;

&lt;p&gt;Now let's look at sessions.&lt;/p&gt;

&lt;p&gt;After a successful login, the server can create a session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Session ID: abc123
User ID: 42
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The actual session information stays on the server.&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;abc123 → User 42
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser only needs to keep the session identifier.&lt;/p&gt;

&lt;p&gt;That's where cookies often come in.&lt;/p&gt;

&lt;p&gt;The server sends:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Set-Cookie: session_id=abc123
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser stores it.&lt;/p&gt;

&lt;p&gt;On a later request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /api/profile
Cookie: session_id=abc123
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the server reads the session ID and looks up the corresponding session.&lt;/p&gt;

&lt;p&gt;The flow is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Login
  ↓
Verify credentials
  ↓
Create session
  ↓
Store session on server
  ↓
Send session ID in cookie
  ↓
Browser stores cookie
  ↓
Browser sends cookie later
  ↓
Server finds session
  ↓
User identified
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is why you will often see &lt;strong&gt;cookies and sessions used together&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The cookie carries the identifier.&lt;/p&gt;

&lt;p&gt;The session holds the state.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Simple Example
&lt;/h2&gt;

&lt;p&gt;Imagine a server has this session store:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;abc123 → User 42
xyz789 → User 91
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alex logs in and receives:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;When Alex requests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /api/profile
Cookie: session_id=abc123
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the server can do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;abc123
  ↓
Session Store
  ↓
User 42
  ↓
Fetch profile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser never needs to know what is stored inside the server-side session.&lt;/p&gt;

&lt;p&gt;That's one of the useful properties of this approach.&lt;/p&gt;




&lt;h2&gt;
  
  
  So Where Does JWT Come In?
&lt;/h2&gt;

&lt;p&gt;JWT stands for &lt;strong&gt;JSON Web Token&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of giving the client a random session ID that points to server-side authentication state, the server can issue a signed token containing claims.&lt;/p&gt;

&lt;p&gt;A simplified payload might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sub"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"42"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1760003600&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server signs the token.&lt;/p&gt;

&lt;p&gt;The resulting JWT looks roughly like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Header.Payload.Signature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The client can then send it with future API requests.&lt;/p&gt;

&lt;p&gt;A common format is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Authorization: Bearer eyJ...
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The backend receives the token and verifies its signature and relevant claims.&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;Login
  ↓
Verify credentials
  ↓
Create JWT
  ↓
Sign JWT
  ↓
Send JWT to client
  ↓
Client sends JWT
  ↓
Server verifies JWT
  ↓
Identify user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the basic JWT model.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Important Difference
&lt;/h2&gt;

&lt;p&gt;At this point, the three terms should start looking different.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cookie&lt;/td&gt;
&lt;td&gt;Stores and sends data through the browser&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Session&lt;/td&gt;
&lt;td&gt;Keeps authentication state on the server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JWT&lt;/td&gt;
&lt;td&gt;Carries signed claims that a server can verify&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is why comparing them as if they were direct alternatives can be confusing.&lt;/p&gt;

&lt;p&gt;They're not really at the same layer.&lt;/p&gt;

&lt;p&gt;For example, you can have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cookie + Session
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cookie + JWT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authorization Header + JWT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those are all different architectures.&lt;/p&gt;




&lt;h2&gt;
  
  
  Cookie + Session
&lt;/h2&gt;

&lt;p&gt;This is a common pattern for traditional web applications.&lt;/p&gt;

&lt;p&gt;The architecture looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             Browser
                |
             Cookie
                |
          Session ID
                |
                ↓
        Server-side Session
                |
             User ID
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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;Cookie:
session_id=abc123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;abc123 → User 42
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser carries the identifier.&lt;/p&gt;

&lt;p&gt;The server owns the actual session state.&lt;/p&gt;

&lt;p&gt;One practical advantage is that the server can invalidate the session directly.&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 plaintext"&gt;&lt;code&gt;Logout
  ↓
Invalidate session
  ↓
Session ID no longer works
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can make server-side session management convenient.&lt;/p&gt;




&lt;h2&gt;
  
  
  Cookie + JWT
&lt;/h2&gt;

&lt;p&gt;A JWT doesn't have to be stored in JavaScript-accessible browser storage.&lt;/p&gt;

&lt;p&gt;It can also be placed in a cookie.&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 http"&gt;&lt;code&gt;&lt;span class="err"&gt;Set-Cookie: access_token=eyJ...; HttpOnly; Secure
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser then sends the cookie with appropriate requests.&lt;/p&gt;

&lt;p&gt;The architecture becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser
   ↓
Cookie
   ↓
JWT
   ↓
Server verifies JWT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the cookie is handling browser storage/transmission while the JWT is the authentication credential.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cookie ≠ JWT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They are doing different jobs.&lt;/p&gt;




&lt;h2&gt;
  
  
  JWT in the Authorization Header
&lt;/h2&gt;

&lt;p&gt;Another common pattern is to send the JWT explicitly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /api/profile
Authorization: Bearer eyJ...
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is common when working with APIs where the client is responsible for attaching the token.&lt;/p&gt;

&lt;p&gt;The server receives it and performs verification.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request
   ↓
Authorization header
   ↓
JWT
   ↓
Verify token
   ↓
Identify user
   ↓
Process request
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pattern is common in applications where the frontend, mobile app, or another client communicates with a backend API.&lt;/p&gt;

&lt;p&gt;But having an API does &lt;strong&gt;not&lt;/strong&gt; automatically mean JWT is required.&lt;/p&gt;

&lt;p&gt;That's an important distinction.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Does "Stateless JWT" Mean?
&lt;/h2&gt;

&lt;p&gt;One reason JWTs are popular is that they can support a stateless authentication model.&lt;/p&gt;

&lt;p&gt;With a traditional session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Session ID
    ↓
Server
    ↓
Session Store
    ↓
User
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server needs access to the session state.&lt;/p&gt;

&lt;p&gt;With a self-contained JWT:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;JWT
 ↓
Verify signature
 ↓
Read claims
 ↓
Identify subject
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server can potentially authenticate the request without looking up a traditional session record.&lt;/p&gt;

&lt;p&gt;This can be useful when an application has multiple backend servers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 Load Balancer
                 /     |     \
                /      |      \
          Server A  Server B  Server C
                \      |      /
                 \     |     /
                 Verify JWT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each server can verify the token using the appropriate key.&lt;/p&gt;

&lt;p&gt;However, calling JWT authentication "stateless" doesn't mean the entire authentication system has zero state.&lt;/p&gt;

&lt;p&gt;Applications may still need state for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Refresh tokens
Revocation
Device sessions
Security events
User sessions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So stateless JWT authentication is a design choice, not a guarantee that the whole system becomes state-free.&lt;/p&gt;




&lt;h2&gt;
  
  
  What About Security?
&lt;/h2&gt;

&lt;p&gt;This is where the choice becomes more interesting.&lt;/p&gt;

&lt;p&gt;For browser applications, cookies have security-related attributes such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HttpOnly
Secure
SameSite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Set-Cookie: session_id=abc123;
HttpOnly;
Secure;
SameSite=Lax
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;HttpOnly&lt;/code&gt; prevents ordinary JavaScript from reading the cookie directly.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Secure&lt;/code&gt; restricts the cookie to HTTPS connections.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SameSite&lt;/code&gt; controls when the browser sends the cookie in cross-site situations.&lt;/p&gt;

&lt;p&gt;These options are useful, but they don't magically make authentication secure.&lt;/p&gt;

&lt;p&gt;The application still needs to consider things like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTPS
CSRF
XSS
Token theft
Session fixation
Password security
Session expiration
Authorization
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The correct security setup depends on the application.&lt;/p&gt;




&lt;h2&gt;
  
  
  What About localStorage?
&lt;/h2&gt;

&lt;p&gt;You may have seen JWTs stored 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="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is convenient.&lt;/p&gt;

&lt;p&gt;But there's an important trade-off.&lt;/p&gt;

&lt;p&gt;JavaScript running on the page can read values stored in &lt;code&gt;localStorage&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So if an attacker manages to execute malicious JavaScript through an XSS vulnerability, a token stored there may be accessible to that script.&lt;/p&gt;

&lt;p&gt;This doesn't mean:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;localStorage = always insecure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cookies = automatically secure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Security is more complicated than that.&lt;/p&gt;

&lt;p&gt;It means you should understand what each storage mechanism exposes and choose based on your application's threat model.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Happens During Logout?
&lt;/h2&gt;

&lt;p&gt;This is one of the places where sessions and JWTs behave differently.&lt;/p&gt;

&lt;p&gt;With a server-side session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Logout
  ↓
Invalidate session
  ↓
Session ID becomes useless
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server can immediately stop recognizing that session.&lt;/p&gt;

&lt;p&gt;With a self-contained access JWT, the server may continue accepting the token until it expires unless the application has an additional revocation mechanism.&lt;/p&gt;

&lt;p&gt;That's one reason JWT-based systems often use short-lived access tokens.&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 plaintext"&gt;&lt;code&gt;Access token
   ↓
15-minute lifetime
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A refresh mechanism can then be used to obtain another access token when necessary.&lt;/p&gt;

&lt;p&gt;A common flow is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Login
  ↓
Access Token + Refresh Token
  ↓
Use Access Token
  ↓
Access Token expires
  ↓
Use Refresh Token
  ↓
Get new Access Token
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Refresh-token handling needs its own security design.&lt;/p&gt;




&lt;h2&gt;
  
  
  Scaling Sessions
&lt;/h2&gt;

&lt;p&gt;Now imagine your application grows.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Users
  ↓
Server
  ↓
Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             Load Balancer
                  ↓
          ┌───────┼───────┐
          ↓       ↓       ↓
       Server A Server B Server C
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With server-side sessions, you need to decide where those sessions live.&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 plaintext"&gt;&lt;code&gt;Server A ──┐
Server B ──┼──→ Shared Session Store
Server C ──┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A shared store allows different servers to find the same session.&lt;/p&gt;

&lt;p&gt;This adds infrastructure, but it is a perfectly reasonable architecture.&lt;/p&gt;

&lt;p&gt;With JWTs, each server can potentially validate the token independently:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;That can simplify some scaling scenarios.&lt;/p&gt;

&lt;p&gt;But it doesn't eliminate the other problems involved in distributed authentication.&lt;/p&gt;

&lt;p&gt;You still have to think about:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Key management
Token expiration
Refresh tokens
Revocation
Authorization
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  So Which One Should You Use?
&lt;/h2&gt;

&lt;p&gt;This is the part where generic tutorials often go wrong.&lt;/p&gt;

&lt;p&gt;They say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Use JWT because it's modern."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's not a useful architectural decision.&lt;/p&gt;

&lt;p&gt;Start with the application.&lt;/p&gt;

&lt;h3&gt;
  
  
  A traditional web application
&lt;/h3&gt;

&lt;p&gt;If most of your application is server-rendered and the server already owns the user's session state, a session-based approach can be a straightforward choice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser
  ↓
Secure Cookie
  ↓
Session ID
  ↓
Server Session
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  A frontend + backend API
&lt;/h3&gt;

&lt;p&gt;If you have separate clients communicating with an API, token-based authentication may fit naturally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Web App
Mobile App
Desktop App
      ↓
     API
      ↓
Authentication
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JWT can be useful here, but it isn't mandatory.&lt;/p&gt;

&lt;p&gt;Cookies and sessions can also be used with APIs.&lt;/p&gt;

&lt;h3&gt;
  
  
  A distributed system
&lt;/h3&gt;

&lt;p&gt;If several services need to verify the same authentication information, signed tokens can be convenient:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             API Gateway
                  ↓
       ┌──────────┼──────────┐
       ↓          ↓          ↓
   Service A  Service B  Service C
       ↓          ↓          ↓
       └──── Verify identity ──┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, the architecture determines whether that benefit actually matters.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Questions I Would Ask Before Choosing
&lt;/h2&gt;

&lt;p&gt;Instead of starting with:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Should I use JWT?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I'd ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Who are the clients?

Is the application browser-based?

Do we need server-side session state?

How should logout work?

Do we need immediate credential revocation?

How long should authentication credentials live?

How will refresh work?

Where will credentials be stored?

Do multiple services need to verify the identity?

What threats does the application need to handle?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These questions tell you much more than simply choosing a technology because it's popular.&lt;/p&gt;




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

&lt;p&gt;If you remember only one thing from this article, 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;Cookie
→ How the browser stores and sends a value

Session
→ Authentication state maintained by the server

JWT
→ A signed token containing claims
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And they can be combined:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cookie + Session
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cookie + JWT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authorization Header + JWT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They're not mutually exclusive.&lt;/p&gt;

&lt;p&gt;That's the part that usually clears up the confusion.&lt;/p&gt;

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

&lt;p&gt;Cookies, sessions, and JWTs are often discussed together, but they solve different problems.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;cookie&lt;/strong&gt; is a mechanism for storing and sending data through the browser.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;session&lt;/strong&gt; is server-side state that can be used to remember an authenticated user.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;JWT&lt;/strong&gt; is a signed token that carries claims which a server can verify.&lt;/p&gt;

&lt;p&gt;The right architecture depends on what you're building.&lt;/p&gt;

&lt;p&gt;A small server-rendered application might be perfectly comfortable with cookies and server-side sessions.&lt;/p&gt;

&lt;p&gt;A system serving multiple types of clients might benefit from token-based authentication.&lt;/p&gt;

&lt;p&gt;A distributed system might find signed tokens useful for passing verifiable identity information between services.&lt;/p&gt;

&lt;p&gt;None of those choices makes one technology universally better than the others.&lt;/p&gt;

&lt;p&gt;The better question isn't:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"JWT or sessions?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Where should authentication state live, how should the client carry it, and how should the server verify and revoke it?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once you start thinking in those terms, cookies, sessions, and JWTs stop looking like competing technologies and start looking like different pieces of an authentication architecture.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>authentication</category>
      <category>backend</category>
      <category>security</category>
    </item>
    <item>
      <title>How Does JWT Authentication Work? A Complete Guide!</title>
      <dc:creator>Tanu Priya</dc:creator>
      <pubDate>Tue, 15 Sep 2026 10:23:19 +0000</pubDate>
      <link>https://dev.to/tanu_priya/how-does-jwt-authentication-work-a-complete-guide-2o79</link>
      <guid>https://dev.to/tanu_priya/how-does-jwt-authentication-work-a-complete-guide-2o79</guid>
      <description>&lt;p&gt;You enter your email and password, click &lt;strong&gt;Login&lt;/strong&gt;, and suddenly the application knows who you are.&lt;/p&gt;

&lt;p&gt;A few seconds later, you open your profile and the backend already knows which user's data to return.&lt;/p&gt;

&lt;p&gt;But HTTP doesn't work like that by itself.&lt;/p&gt;

&lt;p&gt;Every request is independent. So after the login request finishes, how does the server recognize the next request?&lt;/p&gt;

&lt;p&gt;One popular solution is &lt;strong&gt;JWT authentication&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;JWT stands for &lt;strong&gt;JSON Web Token&lt;/strong&gt;. It gives the client a signed piece of information that can be sent with later requests so the server can verify the request's identity.&lt;/p&gt;

&lt;p&gt;A simplified flow 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;Login
  ↓
Verify credentials
  ↓
Create JWT
  ↓
Send JWT to client
  ↓
Client sends JWT with API requests
  ↓
Server verifies JWT
  ↓
Request continues
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The interesting part is what happens inside that flow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Authentication Need a Token?
&lt;/h2&gt;

&lt;p&gt;Imagine you log into an application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST /api/login
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"alex@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mypassword"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The backend verifies the credentials.&lt;/p&gt;

&lt;p&gt;At this point, it knows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This is user 42.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But the next request could be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /api/profile
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is nothing inherent in HTTP that tells the server:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"This is the same person who successfully logged in two seconds ago."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The application needs a way to carry that authentication information from one request to another.&lt;/p&gt;

&lt;p&gt;That's where the token comes in.&lt;/p&gt;

&lt;p&gt;After successful authentication, the server issues a JWT:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Login
  ↓
JWT issued
  ↓
Client keeps JWT
  ↓
JWT sent with future requests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The token becomes part of the application's authentication mechanism.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Inside a JWT?
&lt;/h2&gt;

&lt;p&gt;A JWT usually 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;xxxxx.yyyyy.zzzzz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are three sections:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Header.Payload.Signature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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;eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.
eyJzdWIiOiI0MiIsInJvbGUiOiJ1c2VyIn0
.
signature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These three parts have different jobs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Header
&lt;/h3&gt;

&lt;p&gt;The header describes the token.&lt;/p&gt;

&lt;p&gt;A simplified example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"alg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"HS256"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"typ"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"JWT"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;alg&lt;/code&gt; specifies the signing algorithm and &lt;code&gt;typ&lt;/code&gt; identifies the token type.&lt;/p&gt;

&lt;h3&gt;
  
  
  Payload
&lt;/h3&gt;

&lt;p&gt;The payload contains claims.&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 json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sub"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"42"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"iat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1760000000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1760003600&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sub → subject / user identifier
role → application-specific role
iat → issued-at time
exp → expiration time
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These claims allow the server to carry useful information about the token and its subject.&lt;/p&gt;

&lt;p&gt;There is an important security detail here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A normal JWT payload is not encrypted.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It is encoded so that the token can be represented as a compact string.&lt;/p&gt;

&lt;p&gt;Anyone who obtains the token can generally decode its header and payload.&lt;/p&gt;

&lt;p&gt;So don't put things like passwords, private keys, or other secrets inside the payload.&lt;/p&gt;

&lt;h3&gt;
  
  
  Signature
&lt;/h3&gt;

&lt;p&gt;The signature is what protects the integrity of the signed token data.&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;Header + Payload
       ↓
Signing algorithm
       +
Secret/private key
       ↓
Signature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server can later verify the signature.&lt;/p&gt;

&lt;p&gt;If someone changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"admin"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;without having the appropriate signing key, the signature will no longer match.&lt;/p&gt;

&lt;p&gt;The server can reject the token.&lt;/p&gt;

&lt;p&gt;So the signature doesn't hide the payload.&lt;/p&gt;

&lt;p&gt;It helps answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Has the signed token data been changed, and does it have a valid signature?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What Happens When You Log In?
&lt;/h2&gt;

&lt;p&gt;Let's follow the request from beginning to end.&lt;/p&gt;

&lt;p&gt;The client sends:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST /api/login
Content-Type: application/json
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"alex@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mypassword"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The backend might do 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;Receive credentials
       ↓
Find user
       ↓
Verify password
       ↓
Credentials valid?
       ↓
Create JWT
       ↓
Sign JWT
       ↓
Return token
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The token might contain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sub"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"42"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1760003600&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server signs it using the configured key.&lt;/p&gt;

&lt;p&gt;The response could then contain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"accessToken"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"eyJ..."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The client can now use that access token when calling protected APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Next API Request
&lt;/h2&gt;

&lt;p&gt;Now the frontend wants Alex's profile.&lt;/p&gt;

&lt;p&gt;It sends:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /api/profile
Authorization: Bearer eyJ...
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The backend receives the request and extracts the token.&lt;/p&gt;

&lt;p&gt;It then verifies it.&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;Request
  ↓
Extract JWT
  ↓
Verify signature
  ↓
Check expiration
  ↓
Validate required claims
  ↓
Identify user
  ↓
Continue request
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the token represents user &lt;code&gt;42&lt;/code&gt;, the application can use that identity when processing the request.&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 plaintext"&gt;&lt;code&gt;JWT
 ↓
sub = 42
 ↓
User 42
 ↓
Fetch profile
 ↓
Return profile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice something important here.&lt;/p&gt;

&lt;p&gt;The user doesn't send their password with every request.&lt;/p&gt;

&lt;p&gt;The JWT is the credential being presented for that request.&lt;/p&gt;

&lt;h2&gt;
  
  
  JWT Authentication in Express
&lt;/h2&gt;

&lt;p&gt;In a Node.js application, JWT verification is often placed in middleware.&lt;/p&gt;

&lt;p&gt;A simplified 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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;authenticate&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="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;header&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;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authorization&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bearer &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Authentication required&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;JWT_SECRET&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Invalid or expired token&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A protected route can then use the middleware:&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="s2"&gt;/api/profile&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;getProfile&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The request now has a predictable path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /api/profile
       ↓
Authentication middleware
       ↓
Verify JWT
       ↓
Attach user to request
       ↓
Controller
       ↓
Database
       ↓
Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The controller doesn't need to repeatedly implement JWT verification.&lt;/p&gt;

&lt;p&gt;That responsibility stays in the authentication layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authentication Is Still Different From Authorization
&lt;/h2&gt;

&lt;p&gt;This is where many beginners mix things up.&lt;/p&gt;

&lt;p&gt;Suppose the JWT tells the application that the current user is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User ID: 42
Role: user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That establishes identity.&lt;/p&gt;

&lt;p&gt;But now the user requests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;DELETE /api/users/100
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The backend still has another question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is user 42 allowed to delete another user?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's &lt;strong&gt;authorization&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So the complete process is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;JWT verification
      ↓
Who is this?
      ↓
User 42
      ↓
Authorization check
      ↓
Can User 42 perform this action?
      ↓
Allow / Reject
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;requireAdmin&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="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;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Forbidden&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;next&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:&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="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/users/:id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;requireAdmin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;deleteUser&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JWT helps with authentication.&lt;/p&gt;

&lt;p&gt;It does &lt;strong&gt;not&lt;/strong&gt; automatically give the user permission to do everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Does Stateless JWT Authentication Mean?
&lt;/h2&gt;

&lt;p&gt;You've probably heard that JWT authentication is &lt;strong&gt;stateless&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The idea is that the server doesn't necessarily need to maintain a traditional server-side session for every access token.&lt;/p&gt;

&lt;p&gt;With a session-based approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client
  ↓
Session ID
  ↓
Server
  ↓
Session Store
  ↓
User
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With a self-contained JWT:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client
  ↓
JWT
  ↓
Server verifies token
  ↓
Claims identify subject
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can be convenient in systems with multiple backend instances.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 Load Balancer
                      ↓
          ┌───────────┼───────────┐
          ↓           ↓           ↓
       Server A    Server B    Server C
          ↑           ↑           ↑
          └──── Verify JWT ───────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each server can verify the token using the appropriate key.&lt;/p&gt;

&lt;p&gt;There is no requirement for every request to first find a traditional session record.&lt;/p&gt;

&lt;p&gt;But there's a catch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stateless doesn't mean there is no state anywhere in the authentication system.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Applications may still maintain state for refresh tokens, revocation, device sessions, security events, or other security controls.&lt;/p&gt;

&lt;h2&gt;
  
  
  Access Tokens and Refresh Tokens
&lt;/h2&gt;

&lt;p&gt;Access tokens are often short-lived.&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 plaintext"&gt;&lt;code&gt;Access Token
↓
Expires in 15 minutes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the access token expires, the user shouldn't necessarily have to log in again.&lt;/p&gt;

&lt;p&gt;A common design is to use a refresh token.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Login
  ↓
Access Token + Refresh Token
  ↓
Access Token used for APIs
  ↓
Access Token expires
  ↓
Refresh Token
  ↓
New Access Token
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives the application a way to keep a user signed in while limiting the lifetime of an individual access token.&lt;/p&gt;

&lt;p&gt;Refresh tokens need careful handling because a stolen refresh token can have a much longer useful lifetime.&lt;/p&gt;

&lt;p&gt;That's why real authentication systems often add things like refresh-token rotation and revocation.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Happens When the JWT Expires?
&lt;/h2&gt;

&lt;p&gt;JWTs commonly contain an expiration claim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sub"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"42"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1760003600&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once that time has passed, the token should no longer be accepted as a valid access token.&lt;/p&gt;

&lt;p&gt;The API might respond with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;401 Unauthorized
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The client can then use its refresh mechanism if one exists:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;API request
    ↓
Access token expired
    ↓
401
    ↓
Refresh authentication
    ↓
New access token
    ↓
Retry request
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is one reason short-lived access tokens are useful.&lt;/p&gt;

&lt;p&gt;If an access token is stolen, its useful lifetime can be limited.&lt;/p&gt;

&lt;p&gt;It doesn't make theft harmless, but it can reduce the window of exposure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Should You Store a JWT?
&lt;/h2&gt;

&lt;p&gt;There isn't one universal answer.&lt;/p&gt;

&lt;p&gt;JWTs are commonly transported using:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



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

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

&lt;/div&gt;



&lt;p&gt;For browser applications, cookies can provide useful security controls.&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 http"&gt;&lt;code&gt;&lt;span class="err"&gt;Set-Cookie: access_token=...;
HttpOnly;
Secure;
SameSite=Lax
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;HttpOnly&lt;/code&gt; prevents normal page JavaScript from directly reading the cookie.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Secure&lt;/code&gt; tells the browser to send it only over HTTPS.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SameSite&lt;/code&gt; controls when the browser sends the cookie in cross-site situations.&lt;/p&gt;

&lt;p&gt;Cookies aren't automatically safer in every situation, though. They introduce considerations such as CSRF protection and cross-origin configuration.&lt;/p&gt;

&lt;p&gt;The right approach depends on the application's architecture and threat model.&lt;/p&gt;

&lt;h2&gt;
  
  
  What If Someone Steals the JWT?
&lt;/h2&gt;

&lt;p&gt;A valid access token should be treated like a credential.&lt;/p&gt;

&lt;p&gt;If an attacker gets one, they may be able to make authenticated API requests until the token expires or is otherwise invalidated.&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 plaintext"&gt;&lt;code&gt;Attacker
   ↓
Stolen JWT
   ↓
Authorization: Bearer &amp;lt;token&amp;gt;
   ↓
API
   ↓
Authenticated request
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's why protecting the token matters.&lt;/p&gt;

&lt;p&gt;Common security practices include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTPS
Short-lived access tokens
Secure refresh-token handling
Signature verification
Expiration checks
Issuer/audience validation when applicable
Restricted signing algorithms
Avoiding sensitive information in payloads
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JWT doesn't provide all of these protections automatically.&lt;/p&gt;

&lt;p&gt;The application has to implement the authentication system correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  JWT Is Not Encryption
&lt;/h2&gt;

&lt;p&gt;This is probably the most common JWT misconception.&lt;/p&gt;

&lt;p&gt;People see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Header.Payload.Signature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and assume the contents are hidden.&lt;/p&gt;

&lt;p&gt;They're not.&lt;/p&gt;

&lt;p&gt;A normal signed JWT provides integrity, not confidentiality.&lt;/p&gt;

&lt;p&gt;Think of it this way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Encoding
→ Makes data representable as a token

Signing
→ Helps detect modification

Encryption
→ Hides the data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JWT signing and encryption solve different problems.&lt;/p&gt;

&lt;p&gt;If the application needs sensitive information to remain confidential, it needs an appropriate encryption mechanism rather than simply putting that information into a signed JWT.&lt;/p&gt;

&lt;h2&gt;
  
  
  401 vs 403
&lt;/h2&gt;

&lt;p&gt;JWT authentication also makes the difference between &lt;code&gt;401&lt;/code&gt; and &lt;code&gt;403&lt;/code&gt; easier to understand.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;401 Unauthorized&lt;/code&gt; response generally means the request doesn't have valid authentication credentials.&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 plaintext"&gt;&lt;code&gt;No token
Invalid token
Expired token
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In simple terms:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;401
→ "I can't authenticate you."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A &lt;code&gt;403 Forbidden&lt;/code&gt; response means the server knows who the user is, but the user isn't allowed to perform the requested action.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authenticated user
        ↓
Not enough permissions
        ↓
403
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;401 → Authentication problem
403 → Authorization problem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  JWT Doesn't Replace Good API Security
&lt;/h2&gt;

&lt;p&gt;It can be tempting to think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"We're using JWT, so our API is secure."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's not how it works.&lt;/p&gt;

&lt;p&gt;JWT only solves part of the problem.&lt;/p&gt;

&lt;p&gt;A production authentication system still needs to think about:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Password storage
HTTPS
Token lifetime
Refresh tokens
Token theft
Revocation
Key management
Authorization
CSRF
XSS
Rate limiting
Account recovery
Brute-force protection
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact list depends on the application.&lt;/p&gt;

&lt;p&gt;JWT is a tool, not the entire security architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  JWT vs Sessions
&lt;/h2&gt;

&lt;p&gt;JWT and sessions are often compared as if one has to replace the other.&lt;/p&gt;

&lt;p&gt;In reality, both are valid approaches.&lt;/p&gt;

&lt;p&gt;A session-based system might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Login
  ↓
Create session
  ↓
Session ID in cookie
  ↓
Server looks up session
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A JWT-based system might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Login
  ↓
Create signed JWT
  ↓
Client receives token
  ↓
Client sends token
  ↓
Server verifies token
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sessions make some server-side operations, such as immediate session invalidation, straightforward.&lt;/p&gt;

&lt;p&gt;JWTs can be useful when authentication information needs to be verified across multiple services without relying on a shared session store.&lt;/p&gt;

&lt;p&gt;But JWT systems can become complicated once you add refresh tokens, revocation, key rotation, and multiple token types.&lt;/p&gt;

&lt;p&gt;So don't choose JWT simply because it is popular.&lt;/p&gt;

&lt;p&gt;Start with the requirements of the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Complete JWT Flow
&lt;/h2&gt;

&lt;p&gt;Putting everything together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    LOGIN
                      ↓
             Email + Password
                      ↓
                  Backend
                      ↓
             Verify credentials
                      ↓
                 Create JWT
                      ↓
                 Sign JWT
                      ↓
              Send to client
                      ↓
             Future API request
                      ↓
              Send JWT with request
                      ↓
               Verify JWT
                      ↓
             Validate its claims
                      ↓
               Identify user
                      ↓
             Check permissions
                      ↓
               Business logic
                      ↓
                  Database
                      ↓
                  Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are really two separate decisions happening:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authentication
      ↓
"Who is making this request?"

Authorization
      ↓
"What is this user allowed to do?"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  A Practical Mental Model
&lt;/h2&gt;

&lt;p&gt;When you encounter JWT authentication in a project, think about it in this order:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. User logs in
       ↓
2. Backend verifies credentials
       ↓
3. Backend issues a signed JWT
       ↓
4. Client sends the JWT with API requests
       ↓
5. Backend verifies the token
       ↓
6. Backend identifies the user
       ↓
7. Authorization checks permissions
       ↓
8. Request is allowed or rejected
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And remember what each part actually means:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;JWT
├── Header
│   └── Token metadata
│
├── Payload
│   └── Claims
│
└── Signature
    └── Integrity/authenticity check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The easiest mistake to make is thinking that JWT is simply a secure replacement for a password.&lt;/p&gt;

&lt;p&gt;It isn't.&lt;/p&gt;

&lt;p&gt;A JWT is a &lt;strong&gt;signed token carrying claims&lt;/strong&gt;. The server uses it to authenticate requests without requiring the user's password on every request.&lt;/p&gt;

&lt;p&gt;Once you understand that, the rest of the system starts making sense.&lt;/p&gt;

&lt;p&gt;Login creates the authentication context.&lt;br&gt;
The JWT carries that context between requests.&lt;br&gt;
The server verifies the JWT.&lt;br&gt;
Authorization decides what the authenticated user can actually do.&lt;/p&gt;

&lt;p&gt;That's the core of JWT authentication.&lt;/p&gt;

</description>
      <category>authentication</category>
      <category>backend</category>
      <category>security</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Authentication vs Authorization: What Is the Difference?</title>
      <dc:creator>Tanu Priya</dc:creator>
      <pubDate>Mon, 14 Sep 2026 09:34:52 +0000</pubDate>
      <link>https://dev.to/tanu_priya/authentication-vs-authorization-what-is-the-difference-9m6</link>
      <guid>https://dev.to/tanu_priya/authentication-vs-authorization-what-is-the-difference-9m6</guid>
      <description>&lt;p&gt;You log into an application with your email and password.&lt;/p&gt;

&lt;p&gt;The application checks your credentials and lets you in.&lt;/p&gt;

&lt;p&gt;Now you open the admin dashboard.&lt;/p&gt;

&lt;p&gt;The application checks something else: &lt;strong&gt;are you actually allowed to use the admin dashboard?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These two checks are related, but they aren't the same.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authentication → Who are you?

Authorization  → What are you allowed to do?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A simple real-world example makes the difference easier to understand.&lt;/p&gt;

&lt;p&gt;When you show your ID at an office entrance, security verifies that you are actually you.&lt;/p&gt;

&lt;p&gt;That's &lt;strong&gt;authentication&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Once you're inside, your ID might allow you to enter some rooms but not others.&lt;/p&gt;

&lt;p&gt;That's &lt;strong&gt;authorization&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The same idea is used inside web applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authentication: Who Are You?
&lt;/h2&gt;

&lt;p&gt;Authentication is about verifying a user's identity.&lt;/p&gt;

&lt;p&gt;A typical login request might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST /api/login
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"alex@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mypassword"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The backend receives the credentials and verifies them.&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;Email + Password
       ↓
    Backend
       ↓
Find user
       ↓
Verify password
       ↓
Credentials valid?
       ↓
Authenticated
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If everything checks out, the server now knows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User ID: 42
Email: alex@example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But there is a problem.&lt;/p&gt;

&lt;p&gt;HTTP is stateless.&lt;/p&gt;

&lt;p&gt;The next request doesn't automatically know that the previous login succeeded.&lt;/p&gt;

&lt;p&gt;That's where sessions, cookies, and tokens come in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sessions: Remembering the User
&lt;/h2&gt;

&lt;p&gt;One common solution is a server-side session.&lt;/p&gt;

&lt;p&gt;After successful login, the server creates a session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User 42
   ↓
Session created
   ↓
Session ID = abc123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server stores something similar to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;abc123 → User 42
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser then needs to send that session ID with future requests.&lt;/p&gt;

&lt;p&gt;This is commonly done using a cookie.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Login
  ↓
Create session
  ↓
Send session cookie
  ↓
Browser stores cookie
  ↓
Future requests include cookie
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Set-Cookie: session_id=abc123
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Cookie: session_id=abc123
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server can look up the session and determine which user is making the request.&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;Browser
   ↓
Cookie
   ↓
Session ID
   ↓
Server
   ↓
User 42
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser doesn't need to send the user's password again.&lt;/p&gt;

&lt;h2&gt;
  
  
  What About Tokens?
&lt;/h2&gt;

&lt;p&gt;Another common approach is token-based authentication.&lt;/p&gt;

&lt;p&gt;After login, the server generates a token and gives it to the client.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Login
  ↓
Verify credentials
  ↓
Generate token
  ↓
Send token
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The client can then include the token with API requests.&lt;/p&gt;

&lt;p&gt;A common format is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Authorization: Bearer &amp;lt;token&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The backend receives the token and verifies it.&lt;/p&gt;

&lt;p&gt;If the token is valid, the backend can identify the user and continue processing the request.&lt;/p&gt;

&lt;p&gt;This approach is particularly common with APIs and applications where the client and backend are separate systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sessions vs Tokens
&lt;/h2&gt;

&lt;p&gt;The difference is mainly about where authentication state is maintained.&lt;/p&gt;

&lt;p&gt;With a traditional session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client
  ↓
Session ID
  ↓
Server
  ↓
Session data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With a self-contained token:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client
  ↓
Token
  ↓
Server validates token
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neither approach is universally better.&lt;/p&gt;

&lt;p&gt;The choice depends on the application, security requirements, infrastructure, and how authentication needs to be managed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authorization: What Can the User Do?
&lt;/h2&gt;

&lt;p&gt;Now let's say Alex has successfully logged in.&lt;/p&gt;

&lt;p&gt;Authentication is complete.&lt;/p&gt;

&lt;p&gt;But Alex tries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /api/admin/users
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Being logged in doesn't automatically give Alex access to this endpoint.&lt;/p&gt;

&lt;p&gt;The backend needs to ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Does this user have permission to access this resource?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;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;Alex
Role: user

/admin/users
     ↓
Access denied
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An administrator might have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sarah
Role: admin

/admin/users
     ↓
Access allowed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's authorization.&lt;/p&gt;

&lt;p&gt;The complete flow looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request
   ↓
Authentication
   ↓
Who is the user?
   ↓
Authorization
   ↓
Is the user allowed?
   ↓
Business logic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This distinction becomes especially important when building APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authentication and Authorization in Middleware
&lt;/h2&gt;

&lt;p&gt;In a Node.js application, authentication and authorization are often separated into middleware.&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;authenticate&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="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authorization&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Authentication required&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="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="nf"&gt;verifyToken&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Invalid token&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;user&lt;/span&gt; &lt;span class="o"&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;next&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 middleware identifies the user and attaches that information to the request.&lt;/p&gt;

&lt;p&gt;Then authorization can happen separately:&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;requireAdmin&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="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;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Access denied&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;next&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 route can combine both:&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="s2"&gt;/admin/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;authenticate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;requireAdmin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;getUsers&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the request goes through two different checks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /admin/users
       ↓
authenticate
       ↓
Who is this?
       ↓
requireAdmin
       ↓
Can they access this?
       ↓
getUsers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's a much cleaner design than putting all of the security logic inside every controller.&lt;/p&gt;

&lt;h2&gt;
  
  
  401 vs 403
&lt;/h2&gt;

&lt;p&gt;You'll often see two status codes when working with protected APIs.&lt;/p&gt;

&lt;h3&gt;
  
  
  401 Unauthorized
&lt;/h3&gt;

&lt;p&gt;The server doesn't have valid authentication information.&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 plaintext"&gt;&lt;code&gt;No token
Invalid token
Expired credentials
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"I don't know who you are."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  403 Forbidden
&lt;/h3&gt;

&lt;p&gt;The server knows who you are, but you don't have permission to perform the operation.&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 plaintext"&gt;&lt;code&gt;Logged in as normal user
        ↓
Trying to delete another user
        ↓
403 Forbidden
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"I know who you are, but you can't do this."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A simple way to remember it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;401 → Authentication problem

403 → Authorization problem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Roles and Permissions
&lt;/h2&gt;

&lt;p&gt;Authorization is often implemented using roles.&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 plaintext"&gt;&lt;code&gt;User
Admin
Moderator
Editor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An admin might be allowed to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create users
Delete users
Manage settings
View reports
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;while a normal user might only be able to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;View their profile
Create comments
View posts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For larger applications, permissions can be more granular:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;users:read
users:create
users:delete

posts:read
posts:update
posts:delete
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes it possible to give users exactly the permissions they need instead of relying entirely on broad roles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't Trust the Frontend for Authorization
&lt;/h2&gt;

&lt;p&gt;This is one of the most important points.&lt;/p&gt;

&lt;p&gt;Suppose your frontend hides the delete button from normal users:&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;if &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;role&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;admin&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;showDeleteButton&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 good for the UI.&lt;/p&gt;

&lt;p&gt;But it isn't a security mechanism.&lt;/p&gt;

&lt;p&gt;A user can still manually send the request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;DELETE /api/users/123
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;directly to your backend.&lt;/p&gt;

&lt;p&gt;That's why authorization must happen on the server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Frontend
   ↓
API Request
   ↓
Backend
   ↓
Authentication
   ↓
Authorization
   ↓
Allow / Reject
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The frontend decides what the user sees.&lt;/p&gt;

&lt;p&gt;The backend decides what the user is actually allowed to do.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Passwords Fit In
&lt;/h2&gt;

&lt;p&gt;Authentication often starts with a password, but passwords should not be stored directly in the database.&lt;/p&gt;

&lt;p&gt;Instead, applications use password-hashing algorithms designed for secure password storage.&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;Password
   ↓
Password hashing
   ↓
Stored password hash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;During login, the submitted password is verified against the stored hash.&lt;/p&gt;

&lt;p&gt;The application should not need to retrieve the original password.&lt;/p&gt;

&lt;p&gt;This is one of the basic security boundaries every authentication system needs to get right.&lt;/p&gt;

&lt;h2&gt;
  
  
  Putting Everything Together
&lt;/h2&gt;

&lt;p&gt;A typical protected API request might 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;                    LOGIN
                      ↓
              Verify credentials
                      ↓
                Authentication
                      ↓
            Session / Cookie / Token
                      ↓
              Future API Request
                      ↓
                Authentication
                      ↓
                 Authorization
                      ↓
                 Controller
                      ↓
                  Database
                      ↓
                  Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each part has a different job.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authentication
→ Establish the user's identity

Authorization
→ Decide what that user can access
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sessions, cookies, and tokens help the application maintain or carry authentication information between requests.&lt;/p&gt;

&lt;p&gt;They don't decide what the user is allowed to do.&lt;/p&gt;

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

&lt;p&gt;Whenever you're building a protected API, ask two questions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Who is making this request?

2. Is this user allowed to perform this action?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first question is &lt;strong&gt;authentication&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The second is &lt;strong&gt;authorization&lt;/strong&gt;.&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 plaintext"&gt;&lt;code&gt;User logs in
     ↓
Authentication
     ↓
"I know who you are."
     ↓
User requests admin dashboard
     ↓
Authorization
     ↓
"I know who you are,
but are you allowed here?"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the core difference.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Authentication establishes identity. Authorization controls access.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once you understand that distinction, sessions, cookies, tokens, roles, permissions, &lt;code&gt;401&lt;/code&gt;, and &lt;code&gt;403&lt;/code&gt; all start fitting into the same picture.&lt;/p&gt;

&lt;p&gt;And when you're designing a backend, keeping authentication and authorization as separate responsibilities makes the security model much easier to reason about.&lt;/p&gt;

</description>
      <category>authentication</category>
      <category>backend</category>
      <category>security</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Database Indexing: Why Can an Index Make Queries Faster?</title>
      <dc:creator>Tanu Priya</dc:creator>
      <pubDate>Sun, 13 Sep 2026 07:53:00 +0000</pubDate>
      <link>https://dev.to/tanu_priya/database-indexing-why-can-an-index-make-queries-faster-2c16</link>
      <guid>https://dev.to/tanu_priya/database-indexing-why-can-an-index-make-queries-faster-2c16</guid>
      <description>&lt;p&gt;Imagine your &lt;code&gt;users&lt;/code&gt; table has 10 million rows.&lt;/p&gt;

&lt;p&gt;Your application frequently runs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'alex@example.com'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database returns the result, but how did it find one user among millions?&lt;/p&gt;

&lt;p&gt;It could check the rows one by one.&lt;/p&gt;

&lt;p&gt;Or, it could use an &lt;strong&gt;index&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;An index gives the database a more efficient way to find data without scanning the entire table every time.&lt;/p&gt;

&lt;p&gt;But indexes aren't magic. They consume storage, add overhead to writes, and aren't useful for every query.&lt;/p&gt;

&lt;p&gt;Understanding that trade-off is what makes indexing useful from a developer's perspective.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. What Is a Database Index?
&lt;/h2&gt;

&lt;p&gt;A database index is an additional data structure that helps the database locate rows more efficiently.&lt;/p&gt;

&lt;p&gt;Think about a book.&lt;/p&gt;

&lt;p&gt;If you want to find a particular topic, you don't normally read every page. You use the index to find where that topic appears.&lt;/p&gt;

&lt;p&gt;A database index follows a similar idea:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Without Index

Query
  ↓
Scan rows
  ↓
Find matching rows
  ↓
Return result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With an appropriate index:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Query
  ↓
Search Index
  ↓
Locate relevant rows
  ↓
Read required data
  ↓
Return result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important idea is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;An index can reduce the amount of data the database needs to examine.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's the real reason indexes can make queries faster.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. What Happens Without an Index?
&lt;/h2&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 plaintext"&gt;&lt;code&gt;users

id    name      email
-----------------------------
1     Rahul     rahul@mail.com
2     Priya     priya@mail.com
3     Alex      alex@mail.com
4     John      john@mail.com
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'alex@mail.com'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If there isn't a useful index on &lt;code&gt;email&lt;/code&gt;, the database may perform a sequential scan.&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;Row 1 → Check
Row 2 → Check
Row 3 → Match
Row 4 → Check
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With a small table, this isn't a big deal.&lt;/p&gt;

&lt;p&gt;But imagine the table contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10,000 rows
1 million rows
100 million rows
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Scanning a large portion of the table for every lookup can become expensive.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. What Changes When We Add an Index?
&lt;/h2&gt;

&lt;p&gt;We can create an index:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_users_email&lt;/span&gt;
&lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the database has another structure that can help it search for email values.&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;Query
  ↓
Email Index
  ↓
alex@mail.com
  ↓
Row location
  ↓
User row
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of searching through potentially millions of table rows, the database can first search the much more structured index.&lt;/p&gt;

&lt;p&gt;That's the fundamental advantage.&lt;/p&gt;

&lt;p&gt;The database isn't necessarily processing the same amount of data faster.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's potentially processing much less data.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  4. How Does an Index Search So Quickly?
&lt;/h2&gt;

&lt;p&gt;Many traditional database indexes use tree-based structures, particularly &lt;strong&gt;B-tree-style indexes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can think about a simplified tree 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;                 50
              /      \
            25        75
           /  \      /  \
         10   40    60   90
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're searching for &lt;code&gt;60&lt;/code&gt;, you don't need to inspect every value.&lt;/p&gt;

&lt;p&gt;You start at the top:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;60 &amp;gt; 50
  ↓
Go right

60 &amp;lt; 75
  ↓
Go left

60 found
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Real database indexes are much more sophisticated and optimized for storage systems, but the underlying idea is useful:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Organize values so large portions of the search space can be eliminated quickly.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  5. Indexes Usually Don't Store the Whole Table
&lt;/h2&gt;

&lt;p&gt;An index isn't simply a second copy of your table.&lt;/p&gt;

&lt;p&gt;Conceptually, an index might contain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;email              → row location

alex@mail.com      → location
john@mail.com      → location
priya@mail.com     → location
rahul@mail.com     → location
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact structure depends on the database and index type.&lt;/p&gt;

&lt;p&gt;The index provides information that helps the database locate the underlying data.&lt;/p&gt;

&lt;p&gt;So you can think of your database as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Database
   |
   ├── Table
   |
   └── Index
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The table stores the actual records.&lt;/p&gt;

&lt;p&gt;The index provides an additional access path to those records.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. An Index Doesn't Guarantee Faster Queries
&lt;/h2&gt;

&lt;p&gt;This is an important detail.&lt;/p&gt;

&lt;p&gt;Suppose your table contains only 20 rows.&lt;/p&gt;

&lt;p&gt;You create an index:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_users_email&lt;/span&gt;
&lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database might still choose a table scan.&lt;/p&gt;

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

&lt;p&gt;Because scanning 20 rows could be cheaper than using the index and then fetching the corresponding table rows.&lt;/p&gt;

&lt;p&gt;The database's &lt;strong&gt;query optimizer&lt;/strong&gt; decides which execution strategy appears cheaper.&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;Query
  ↓
Query Optimizer
  ↓
Evaluate possible plans
  ↓
Choose execution plan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Creating an index gives the database an option. It doesn't force the database to use it.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  7. How Do You Know What the Database Is Doing?
&lt;/h2&gt;

&lt;p&gt;Instead of guessing, inspect the execution plan.&lt;/p&gt;

&lt;p&gt;For example, PostgreSQL supports:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;EXPLAIN&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'alex@example.com'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also inspect actual execution behavior with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;EXPLAIN&lt;/span&gt; &lt;span class="k"&gt;ANALYZE&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'alex@example.com'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can help you understand:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Was an index used?

Was a sequential scan performed?

How many rows were expected?

How many rows were actually processed?

How much time did the operation take?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is much more useful than simply assuming an index is helping.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Indexes Are a Trade-Off
&lt;/h2&gt;

&lt;p&gt;If indexes only had benefits, we'd put them on every column.&lt;/p&gt;

&lt;p&gt;But they don't.&lt;/p&gt;

&lt;p&gt;Indexes require additional:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Storage&lt;/li&gt;
&lt;li&gt;Memory&lt;/li&gt;
&lt;li&gt;Write work&lt;/li&gt;
&lt;li&gt;Maintenance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Suppose you insert a new user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Alex'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'alex@example.com'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database needs to update the table.&lt;/p&gt;

&lt;p&gt;If &lt;code&gt;email&lt;/code&gt; is indexed, it also needs to maintain that index.&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;INSERT
  ↓
Update Table
  ↓
Update Index
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a table has many indexes, writes may require more index maintenance.&lt;/p&gt;

&lt;p&gt;So indexing creates a trade-off:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Faster Reads
     ↕
More Write Overhead
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Good database design is about finding the right balance.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. Which Columns Should You Index?
&lt;/h2&gt;

&lt;p&gt;Don't start by looking at the schema and saying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"This column looks important. Let's index it."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Start with your queries.&lt;/p&gt;

&lt;p&gt;Suppose your application frequently executes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An index on &lt;code&gt;email&lt;/code&gt; could be useful.&lt;/p&gt;

&lt;p&gt;If it frequently executes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;an index on &lt;code&gt;user_id&lt;/code&gt; may be worth considering.&lt;/p&gt;

&lt;p&gt;If it frequently executes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;an index involving &lt;code&gt;created_at&lt;/code&gt; might help.&lt;/p&gt;

&lt;p&gt;The key question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;How does the application actually access the data?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Indexes should follow real access patterns.&lt;/p&gt;




&lt;h2&gt;
  
  
  10. Primary Keys and Indexes
&lt;/h2&gt;

&lt;p&gt;Primary keys are common candidates for efficient lookups.&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 sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;BIGINT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&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;span class="n"&gt;email&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A database generally creates or enforces an index-like structure associated with the primary key, depending on the database system.&lt;/p&gt;

&lt;p&gt;That makes queries such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;a natural use case for indexed access.&lt;/p&gt;

&lt;p&gt;This is one reason primary keys are so commonly used for direct record retrieval.&lt;/p&gt;




&lt;h2&gt;
  
  
  11. Unique Indexes
&lt;/h2&gt;

&lt;p&gt;Indexes can also help enforce data integrity.&lt;/p&gt;

&lt;p&gt;Suppose every user must have a unique email:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_users_email&lt;/span&gt;
&lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the index isn't only useful for finding users.&lt;/p&gt;

&lt;p&gt;It also helps enforce the rule that two users cannot have the same email value under that uniqueness constraint.&lt;/p&gt;

&lt;p&gt;So an index can contribute to both:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Performance
+
Data Integrity
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  12. Composite Indexes
&lt;/h2&gt;

&lt;p&gt;Real applications often filter using multiple columns.&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 sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;
&lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'completed'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You might consider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_orders_user_status&lt;/span&gt;
&lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a &lt;strong&gt;composite index&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It indexes a combination of columns rather than just one.&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;(user_id, status)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Composite indexes can be extremely useful when they match common query patterns.&lt;/p&gt;

&lt;p&gt;But there's an important detail.&lt;/p&gt;




&lt;h2&gt;
  
  
  13. Column Order Matters
&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 sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_orders_user_status&lt;/span&gt;
&lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&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 is organized around:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user_id
   ↓
status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A query using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;aligns naturally with the leading column.&lt;/p&gt;

&lt;p&gt;A query using only:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'completed'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is a different situation.&lt;/p&gt;

&lt;p&gt;This is why composite indexes should be designed based on the queries they are intended to support.&lt;/p&gt;

&lt;p&gt;Don't simply combine every column that appears in your queries.&lt;/p&gt;

&lt;p&gt;Think about the actual access patterns.&lt;/p&gt;




&lt;h2&gt;
  
  
  14. Indexes Can Help With Sorting
&lt;/h2&gt;

&lt;p&gt;Indexes aren't only useful for &lt;code&gt;WHERE&lt;/code&gt; conditions.&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 sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without a suitable access path, the database may need to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Read rows
   ↓
Sort rows
   ↓
Return 20
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With an appropriate index, the database may be able to access rows in a useful order.&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;Index
  ↓
Rows already accessible in useful order
  ↓
Return required rows
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whether the database actually chooses this strategy depends on the query and execution plan.&lt;/p&gt;




&lt;h2&gt;
  
  
  15. Indexes Can Help With Range Queries
&lt;/h2&gt;

&lt;p&gt;Indexes are also useful for many range queries.&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 sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
&lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An ordered index on &lt;code&gt;price&lt;/code&gt; can help locate the relevant range.&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;Price Index

500
1000  ← Start
1500
2000
3000
4000
5000  ← End
6000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of searching the entire table, the database can navigate toward the relevant part of the index.&lt;/p&gt;

&lt;p&gt;This is useful for things such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Prices
Dates
Timestamps
Numeric values
IDs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  16. Not Every Query Benefits From an Index
&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 sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'active'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Suppose the table contains 10 million users and 9 million are active.&lt;/p&gt;

&lt;p&gt;An index on &lt;code&gt;status&lt;/code&gt; may not provide much benefit for this particular query because most of the table matches anyway.&lt;/p&gt;

&lt;p&gt;The database may decide that scanning the table is more efficient.&lt;/p&gt;

&lt;p&gt;This is related to &lt;strong&gt;selectivity&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A condition is highly selective when it narrows the possible rows significantly.&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 plaintext"&gt;&lt;code&gt;email = 'alex@example.com'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;might match one row.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;status = 'active'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;might match millions.&lt;/p&gt;

&lt;p&gt;But don't treat selectivity as an absolute rule.&lt;/p&gt;

&lt;p&gt;The optimizer considers many factors when choosing a plan.&lt;/p&gt;




&lt;h2&gt;
  
  
  17. Indexes Don't Fix Bad Queries
&lt;/h2&gt;

&lt;p&gt;Suppose you create an index on:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;and then execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What if user 42 has 10 million orders?&lt;/p&gt;

&lt;p&gt;The index can help locate those orders, but the database still has to process and return a huge result.&lt;/p&gt;

&lt;p&gt;The problem isn't necessarily the missing index anymore.&lt;/p&gt;

&lt;p&gt;The query itself may be asking for too much data.&lt;/p&gt;

&lt;p&gt;A better API might use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&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;Indexing and query design need to work together.&lt;/p&gt;




&lt;h2&gt;
  
  
  18. Indexes and Pagination
&lt;/h2&gt;

&lt;p&gt;This becomes particularly important for APIs.&lt;/p&gt;

&lt;p&gt;A common pagination approach is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="k"&gt;OFFSET&lt;/span&gt; &lt;span class="mi"&gt;20000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For large offsets, the database may still need to process or skip many preceding rows.&lt;/p&gt;

&lt;p&gt;An alternative is cursor or keyset pagination:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;20000&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With a suitable index, the database can start from a known position.&lt;/p&gt;

&lt;p&gt;This is a good example of a broader lesson:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Performance comes from good query design plus appropriate indexing.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An index isn't a substitute for understanding how your data is accessed.&lt;/p&gt;




&lt;h2&gt;
  
  
  19. Too Many Indexes Can Become a Problem
&lt;/h2&gt;

&lt;p&gt;Imagine this table:&lt;br&gt;
&lt;/p&gt;

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

id
name
email
phone
age
city
status
created_at
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You might create an index on every column.&lt;/p&gt;

&lt;p&gt;It sounds optimized.&lt;/p&gt;

&lt;p&gt;But now every relevant write may require maintaining several index structures.&lt;/p&gt;

&lt;p&gt;You also consume more storage.&lt;/p&gt;

&lt;p&gt;And some indexes might never be used by important queries.&lt;/p&gt;

&lt;p&gt;So the goal isn't:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;It's:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;A good index is one that solves a real access problem.&lt;/p&gt;




&lt;h2&gt;
  
  
  20. A Practical Example
&lt;/h2&gt;

&lt;p&gt;Imagine an e-commerce application.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;orders&lt;/code&gt; table contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;50 million rows
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application frequently runs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As the table grows, the endpoint becomes slower.&lt;/p&gt;

&lt;p&gt;Instead of immediately adding more backend servers, you inspect the database execution plan.&lt;/p&gt;

&lt;p&gt;You discover that the database is doing far more work than necessary.&lt;/p&gt;

&lt;p&gt;Now you can evaluate whether an index designed around:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;matches the query pattern.&lt;/p&gt;

&lt;p&gt;After making the change, you check the execution plan again and benchmark the query.&lt;/p&gt;

&lt;p&gt;That's the right way to approach indexing.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;"The query is slow, so add an index."&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Slow Query
    ↓
Inspect Plan
    ↓
Understand the Work
    ↓
Design Appropriate Index
    ↓
Measure Again
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  21. Indexing Is Part of System Design
&lt;/h2&gt;

&lt;p&gt;Database indexing might look like a small implementation detail.&lt;/p&gt;

&lt;p&gt;But database performance affects the entire application.&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 plaintext"&gt;&lt;code&gt;User
  ↓
API Request
  ↓
Backend
  ↓
Database Query
  ↓
Slow Scan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the query becomes slower:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Database latency increases
        ↓
API latency increases
        ↓
Requests stay active longer
        ↓
More concurrent requests
        ↓
Higher resource usage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A well-designed index can sometimes reduce that chain by making the database work more efficiently.&lt;/p&gt;

&lt;p&gt;That's why database optimization is part of system design.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Simple Mental Model
&lt;/h2&gt;

&lt;p&gt;When you see a slow query, don't immediately think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I need an index."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What is the database doing?
        ↓
Is it scanning too much data?
        ↓
Can an index provide a better access path?
        ↓
Does the query itself need improvement?
        ↓
What does EXPLAIN show?
        ↓
Did performance actually improve?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And remember the fundamental trade-off:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                INDEX
                  |
        ┌─────────┴─────────┐
        ↓                   ↓
   Faster Reads        Additional Cost
                            |
                   ┌────────┼────────┐
                   ↓        ↓        ↓
                Storage   Writes  Maintenance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The biggest misconception about indexing is that an index simply makes the database "search faster."&lt;/p&gt;

&lt;p&gt;A better way to think about it is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;An index gives the database a more efficient access path to the data.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If that access path matches the query, the database may avoid scanning, sorting, or processing large amounts of unnecessary data.&lt;/p&gt;

&lt;p&gt;But every index comes with a cost.&lt;/p&gt;

&lt;p&gt;So good indexing isn't about creating indexes everywhere.&lt;/p&gt;

&lt;p&gt;It's about understanding your application's most important queries, inspecting how the database executes them, and creating indexes that reduce expensive work without creating unnecessary overhead elsewhere.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The best index isn't the one you can create. It's the one your workload actually needs.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>database</category>
      <category>performance</category>
      <category>sql</category>
    </item>
    <item>
      <title>What Actually Happens When You Run a Database Query?</title>
      <dc:creator>Tanu Priya</dc:creator>
      <pubDate>Sat, 12 Sep 2026 10:28:23 +0000</pubDate>
      <link>https://dev.to/tanu_priya/what-actually-happens-when-you-run-a-database-query-22o9</link>
      <guid>https://dev.to/tanu_priya/what-actually-happens-when-you-run-a-database-query-22o9</guid>
      <description>&lt;p&gt;You write something that looks almost too simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database returns a row, and from the application's perspective, the job is done.&lt;/p&gt;

&lt;p&gt;But the database didn't simply "look through the table" and return the answer.&lt;/p&gt;

&lt;p&gt;Behind that one query, the database may parse SQL, check permissions, build an execution plan, choose an index, read pages from memory or disk, filter rows, perform joins or sorting, and finally return the result to your application.&lt;/p&gt;

&lt;p&gt;Understanding this process makes databases much easier to reason about.&lt;/p&gt;

&lt;p&gt;It also explains why some queries take milliseconds while others take seconds.&lt;/p&gt;

&lt;p&gt;Let's follow a query from the moment your application sends it until the result comes back.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The Application Sends a Query
&lt;/h2&gt;

&lt;p&gt;Imagine your backend executes:&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="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SELECT * FROM users WHERE id = 42&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;The application sends the query to the database server.&lt;/p&gt;

&lt;p&gt;The simplified flow is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application
     ↓
Database Connection
     ↓
SQL Query
     ↓
Database Server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database receives the SQL statement as text or through a database protocol.&lt;/p&gt;

&lt;p&gt;At this point, the database still has to figure out what the query means and how it should execute it.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. The Database Receives the Request
&lt;/h2&gt;

&lt;p&gt;The database server receives the query through an existing or newly established connection.&lt;/p&gt;

&lt;p&gt;In a production application, there is often a &lt;strong&gt;connection pool&lt;/strong&gt; between your application and database.&lt;/p&gt;

&lt;p&gt;Instead of creating a completely new database connection for every query, the application can reuse existing connections.&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;Application
     ↓
Connection Pool
     ↓
Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This matters because creating and maintaining connections has overhead.&lt;/p&gt;

&lt;p&gt;A connection pool allows multiple requests to efficiently share a controlled number of database connections.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. The Database Parses the SQL
&lt;/h2&gt;

&lt;p&gt;Now the database needs to understand the query.&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 sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database parses the SQL syntax and builds an internal representation of the statement.&lt;/p&gt;

&lt;p&gt;It needs to understand things such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT → What data do we want?
FROM   → Which table?
WHERE  → Which conditions?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;SQL Query
   ↓
Parser
   ↓
Internal Representation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the SQL syntax is invalid, execution stops here.&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 sql"&gt;&lt;code&gt;&lt;span class="n"&gt;SELEC&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;would result in a syntax error.&lt;/p&gt;

&lt;p&gt;The database cannot execute something it cannot understand.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. The Database Checks Permissions
&lt;/h2&gt;

&lt;p&gt;The database also needs to determine whether the requesting user is allowed to perform the operation.&lt;/p&gt;

&lt;p&gt;For example, a database user might have permission to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT
&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 plaintext"&gt;&lt;code&gt;DELETE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the application attempts an operation it isn't authorized to perform, the database can reject the query.&lt;/p&gt;

&lt;p&gt;So the flow is more like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Query
  ↓
Parse
  ↓
Check Permissions
  ↓
Continue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is one reason database credentials and permissions should be carefully configured.&lt;/p&gt;

&lt;p&gt;Your application should generally have only the database privileges it actually needs.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. The Query Optimizer Enters the Picture
&lt;/h2&gt;

&lt;p&gt;This is where things become interesting.&lt;/p&gt;

&lt;p&gt;Suppose you run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'alex@example.com'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database has multiple ways to execute this query.&lt;/p&gt;

&lt;p&gt;It could scan every row:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User 1
User 2
User 3
User 4
...
User 1,000,000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or, if there is an index on &lt;code&gt;email&lt;/code&gt;, it could use the index to find the relevant row much more efficiently.&lt;/p&gt;

&lt;p&gt;The database needs to decide:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What is the most efficient way to execute this query?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's the job of the &lt;strong&gt;query optimizer&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. What Is a Query Execution Plan?
&lt;/h2&gt;

&lt;p&gt;The optimizer creates an &lt;strong&gt;execution plan&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The plan describes how the database intends to execute the query.&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 plaintext"&gt;&lt;code&gt;Query
 ↓
Use index on email
 ↓
Find matching row
 ↓
Fetch row from table
 ↓
Return result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another query might produce:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Query
 ↓
Scan table
 ↓
Filter rows
 ↓
Sort results
 ↓
Return result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database chooses a plan based on information such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;available indexes&lt;/li&gt;
&lt;li&gt;estimated number of rows&lt;/li&gt;
&lt;li&gt;filtering conditions&lt;/li&gt;
&lt;li&gt;table statistics&lt;/li&gt;
&lt;li&gt;join relationships&lt;/li&gt;
&lt;li&gt;sorting requirements&lt;/li&gt;
&lt;li&gt;database configuration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The exact optimizer behavior depends on the database engine.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Full Table Scan
&lt;/h2&gt;

&lt;p&gt;Let's say you run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If there is no useful index, the database may need to inspect many rows.&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;Users Table

Row 1 → age 21
Row 2 → age 32
Row 3 → age 25 ✓
Row 4 → age 41
Row 5 → age 25 ✓
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database checks rows to determine which ones satisfy:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;This is often called a &lt;strong&gt;table scan&lt;/strong&gt; or &lt;strong&gt;sequential scan&lt;/strong&gt;, depending on the database.&lt;/p&gt;

&lt;p&gt;For a small table, this may be completely fine.&lt;/p&gt;

&lt;p&gt;For a table containing hundreds of millions of rows, scanning a huge amount of data can become expensive.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Indexes Change the Game
&lt;/h2&gt;

&lt;p&gt;Now suppose you create:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_users_email&lt;/span&gt;
&lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'alex@example.com'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database may be able to use the index instead of scanning the entire table.&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;Without Index

Query
 ↓
Scan many rows
 ↓
Find matching row
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With an appropriate index:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Query
 ↓
Index
 ↓
Locate matching value
 ↓
Fetch row
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can dramatically reduce the amount of data the database needs to inspect.&lt;/p&gt;

&lt;p&gt;But indexes aren't magic.&lt;/p&gt;

&lt;p&gt;They also consume storage and add work to inserts, updates, and deletes.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. Why Not Create an Index on Everything?
&lt;/h2&gt;

&lt;p&gt;It might sound logical to create an index for every column.&lt;/p&gt;

&lt;p&gt;But that's usually a bad idea.&lt;/p&gt;

&lt;p&gt;Suppose a table has:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;id
name
email
age
city
phone
created_at
status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You could theoretically create indexes on all of them.&lt;/p&gt;

&lt;p&gt;But indexes have costs.&lt;/p&gt;

&lt;p&gt;When you insert a new row:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INSERT
  ↓
Update Table
  ↓
Update Relevant Indexes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;More indexes can mean more maintenance work.&lt;/p&gt;

&lt;p&gt;They also consume storage.&lt;/p&gt;

&lt;p&gt;So indexing is a trade-off:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Faster Reads
     ↕
More Storage + Write Overhead
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Good database design means choosing indexes based on actual query patterns.&lt;/p&gt;




&lt;h2&gt;
  
  
  10. The Database Reads Data Pages
&lt;/h2&gt;

&lt;p&gt;A database doesn't usually think about data exactly like your application does.&lt;/p&gt;

&lt;p&gt;It manages data in units such as &lt;strong&gt;pages&lt;/strong&gt; or &lt;strong&gt;blocks&lt;/strong&gt;, depending on the database system.&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;Database
 ├── Page 1
 ├── Page 2
 ├── Page 3
 ├── Page 4
 └── ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rows are stored within these structures.&lt;/p&gt;

&lt;p&gt;When the database needs data, it needs to access the relevant pages.&lt;/p&gt;

&lt;p&gt;And this leads to one of the most important performance concepts:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Memory is much faster than storage.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  11. Database Memory and Buffer Cache
&lt;/h2&gt;

&lt;p&gt;Databases try to avoid reading from disk unnecessarily.&lt;/p&gt;

&lt;p&gt;Frequently accessed data can remain in memory through mechanisms such as a database buffer pool or cache.&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;Query
  ↓
Memory?
  |
  ├── Yes → Use cached page
  |
  └── No
       ↓
      Storage
       ↓
     Load page
       ↓
      Memory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the required data is already in memory, the database can avoid a slower storage read.&lt;/p&gt;

&lt;p&gt;This is one reason repeated queries can behave very differently from a first query, depending on the workload and cache state.&lt;/p&gt;




&lt;h2&gt;
  
  
  12. The Database Doesn't Always Read the Entire Row
&lt;/h2&gt;

&lt;p&gt;Suppose your query is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You only asked for:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;The database doesn't necessarily need to return every column to the application.&lt;/p&gt;

&lt;p&gt;This is one reason it's often better to avoid:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;when you only need a few columns.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes the requested data explicit and can reduce the amount of data that needs to be processed or transferred.&lt;/p&gt;




&lt;h2&gt;
  
  
  13. What Happens With Multiple Conditions?
&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 sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;category&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'laptops'&lt;/span&gt;
&lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;50000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the database needs to evaluate multiple conditions.&lt;/p&gt;

&lt;p&gt;It may use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Index
   ↓
Find candidate rows
   ↓
Check category
   ↓
Check price
   ↓
Return matching rows
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The optimizer determines the actual execution strategy.&lt;/p&gt;

&lt;p&gt;This is why two queries that look similar to a developer can have very different performance characteristics.&lt;/p&gt;




&lt;h2&gt;
  
  
  14. Joins Make Queries More Interesting
&lt;/h2&gt;

&lt;p&gt;Suppose you have:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;and want to find orders belonging to a particular user.&lt;/p&gt;

&lt;p&gt;You might write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;
&lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the database has to combine information from two tables.&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;Users
   ↓
Match user_id
   ↓
Orders
   ↓
Filter
   ↓
Result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database has different algorithms for performing joins, and the optimizer chooses a strategy based on the available information and estimated cost.&lt;/p&gt;

&lt;p&gt;This is one of the strengths of relational databases.&lt;/p&gt;




&lt;h2&gt;
  
  
  15. Sorting Also Costs Work
&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 sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database needs to produce the rows in price order.&lt;/p&gt;

&lt;p&gt;Depending on the query and available indexes, it may need to perform a sort.&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;Rows
 ↓
Read
 ↓
Sort
 ↓
Return
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sorting a small number of rows is usually cheap.&lt;/p&gt;

&lt;p&gt;Sorting millions of rows can be much more expensive.&lt;/p&gt;

&lt;p&gt;This is why queries involving large datasets should be designed carefully.&lt;/p&gt;




&lt;h2&gt;
  
  
  16. LIMIT Can Reduce Unnecessary Work
&lt;/h2&gt;

&lt;p&gt;Suppose you only need the latest 20 posts.&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 sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you might use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the database knows that the application only needs a limited number of results.&lt;/p&gt;

&lt;p&gt;With a suitable index and execution plan, this can be significantly more efficient than retrieving a huge result set.&lt;/p&gt;

&lt;p&gt;This is especially important for APIs that power feeds, search results, dashboards, and admin panels.&lt;/p&gt;




&lt;h2&gt;
  
  
  17. Aggregations Require Computation
&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 sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database needs to calculate the result.&lt;/p&gt;

&lt;p&gt;Other examples include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;MIN&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;MAX&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;category&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&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;The database now needs to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Read data
   ↓
Group rows
   ↓
Calculate counts
   ↓
Build result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aggregation queries can become expensive when they operate on large datasets.&lt;/p&gt;




&lt;h2&gt;
  
  
  18. Transactions Change How Queries Are Executed
&lt;/h2&gt;

&lt;p&gt;Now consider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;accounts&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;accounts&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;COMMIT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These queries are part of one transaction.&lt;/p&gt;

&lt;p&gt;The database needs to ensure that the transaction follows its consistency and durability rules.&lt;/p&gt;

&lt;p&gt;If something goes wrong before the transaction commits:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BEGIN
 ↓
UPDATE
 ↓
ERROR
 ↓
ROLLBACK
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database can undo the transaction according to its transactional model.&lt;/p&gt;

&lt;p&gt;Transactions are essential for operations where multiple changes need to behave as one logical unit.&lt;/p&gt;




&lt;h2&gt;
  
  
  19. Concurrency Makes Databases Harder
&lt;/h2&gt;

&lt;p&gt;Imagine two users try to purchase the last available product at exactly the same time.&lt;/p&gt;

&lt;p&gt;Both requests might execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Check inventory
     ↓
Inventory = 1
     ↓
Purchase
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the system isn't designed correctly, both requests might believe the product is available.&lt;/p&gt;

&lt;p&gt;Databases provide mechanisms such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;locks&lt;/li&gt;
&lt;li&gt;isolation levels&lt;/li&gt;
&lt;li&gt;MVCC&lt;/li&gt;
&lt;li&gt;transactions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;to manage concurrent operations.&lt;/p&gt;

&lt;p&gt;The exact behavior depends on the database engine and configuration.&lt;/p&gt;

&lt;p&gt;This is where database design becomes much more than simply writing SQL.&lt;/p&gt;




&lt;h2&gt;
  
  
  20. MVCC and Concurrent Reads
&lt;/h2&gt;

&lt;p&gt;Many modern relational databases use some form of &lt;strong&gt;Multi-Version Concurrency Control (MVCC)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The basic idea is that readers and writers can often work concurrently without every read blocking every write.&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;Transaction A
     ↓
Reads version 1

Transaction B
     ↓
Creates version 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depending on the database's isolation model, Transaction A can continue seeing a consistent view while Transaction B modifies newer data.&lt;/p&gt;

&lt;p&gt;The exact implementation differs between databases, but the larger idea is important:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Databases need sophisticated mechanisms to handle many operations happening at the same time.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  21. The Database Produces the Result
&lt;/h2&gt;

&lt;p&gt;Once the database has completed the execution plan, it produces the result.&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 plaintext"&gt;&lt;code&gt;Query
 ↓
Parse
 ↓
Optimize
 ↓
Execute
 ↓
Read Data
 ↓
Filter / Join / Sort
 ↓
Result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result might be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;id | name  | email
-------------------------
42 | Alex  | alex@mail.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database then sends the result back through the database connection.&lt;/p&gt;




&lt;h2&gt;
  
  
  22. The Backend Receives the Result
&lt;/h2&gt;

&lt;p&gt;Your backend receives the database result:&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="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SELECT name, email FROM users WHERE id = 42&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;The application can then transform the database representation into an API response.&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 json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Alex"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"alex@example.com"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The client doesn't need to know how the database produced the result.&lt;/p&gt;

&lt;p&gt;The backend acts as the boundary between the API and the data layer.&lt;/p&gt;




&lt;h2&gt;
  
  
  23. The Entire Journey
&lt;/h2&gt;

&lt;p&gt;Let's put everything together.&lt;/p&gt;

&lt;p&gt;Suppose your application executes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A simplified journey is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application
     ↓
Connection Pool
     ↓
Database Server
     ↓
Parse SQL
     ↓
Check Permissions
     ↓
Query Optimizer
     ↓
Execution Plan
     ↓
Index / Table Scan
     ↓
Memory / Storage
     ↓
Filter Rows
     ↓
Build Result
     ↓
Send Result
     ↓
Application
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One SQL statement can therefore trigger a surprisingly large amount of work.&lt;/p&gt;




&lt;h2&gt;
  
  
  24. Why Some Queries Are Slow
&lt;/h2&gt;

&lt;p&gt;When someone says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The database is slow."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;that doesn't necessarily mean the database itself is the problem.&lt;/p&gt;

&lt;p&gt;The issue could be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Missing Index
       ↓
Large Table Scan
       ↓
Too Many Rows
       ↓
Expensive Join
       ↓
Large Sort
       ↓
Lock Contention
       ↓
Slow Storage
       ↓
Connection Pool Exhaustion
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or the query might simply be asking the database to do an enormous amount of work.&lt;/p&gt;

&lt;p&gt;This is why database performance tuning should start with understanding &lt;strong&gt;what the database is actually doing&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  25. EXPLAIN Shows the Database's Plan
&lt;/h2&gt;

&lt;p&gt;Most major relational databases provide tools for inspecting query execution plans.&lt;/p&gt;

&lt;p&gt;For example, PostgreSQL supports:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;EXPLAIN&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'alex@example.com'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;EXPLAIN&lt;/span&gt; &lt;span class="k"&gt;ANALYZE&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'alex@example.com'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output can help you understand things such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Which index was used?
Was a table scan performed?
How many rows were estimated?
How many rows were actually processed?
How much time did each operation take?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is one of the most useful tools for understanding slow queries.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;"Maybe I need an index."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;you can inspect what the database is actually doing.&lt;/p&gt;




&lt;h2&gt;
  
  
  26. Query Optimization Is About Reducing Work
&lt;/h2&gt;

&lt;p&gt;A useful mental model is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A fast query usually isn't doing less work by accident. It has been designed so the database can avoid unnecessary work.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;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;Bad Pattern
Query
 ↓
Scan 10 million rows
 ↓
Filter
 ↓
Sort
 ↓
Return 20 rows
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A better execution strategy might be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Query
 ↓
Use Index
 ↓
Find relevant rows
 ↓
Return 20 rows
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal isn't simply:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Make the database faster."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Make the database do less unnecessary work."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  27. Why Database Indexes Are So Important
&lt;/h2&gt;

&lt;p&gt;Suppose your API frequently executes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;email&lt;/code&gt; is frequently used for lookups, an index may make sense.&lt;/p&gt;

&lt;p&gt;Without an index:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Query
 ↓
Potentially inspect many rows
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With an appropriate index:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Query
 ↓
Index lookup
 ↓
Relevant row(s)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But indexes should be based on actual workload.&lt;/p&gt;

&lt;p&gt;An index that helps one query may not help another.&lt;/p&gt;

&lt;p&gt;Database optimization is therefore closely connected to understanding how your application accesses its data.&lt;/p&gt;




&lt;h2&gt;
  
  
  28. The Database Is Not Just Storage
&lt;/h2&gt;

&lt;p&gt;A common beginner mental model is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Backend
   ↓
Database
   ↓
Save data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A database is much more than a place to store rows.&lt;/p&gt;

&lt;p&gt;It is responsible for things such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Parsing
Query Planning
Indexing
Data Retrieval
Transactions
Concurrency
Consistency
Durability
Caching
Recovery
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's why databases are such complex pieces of software.&lt;/p&gt;

&lt;p&gt;Your SQL query may be only a few lines long, but the database engine underneath it is doing significant work.&lt;/p&gt;




&lt;h2&gt;
  
  
  29. What Happens in a Production Application?
&lt;/h2&gt;

&lt;p&gt;A real application may look more like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 Client
                    ↓
                Backend
                    ↓
              Connection Pool
                    ↓
                Database
                    ↓
        ┌───────────┼───────────┐
        ↓           ↓           ↓
      Cache       Indexes      Storage
                    ↓
                 Query
                    ↓
               Execution
                    ↓
                Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And there may be additional infrastructure such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Read Replicas
Connection Proxies
Monitoring
Backups
Replication
Sharding
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is where database queries connect directly to system design.&lt;/p&gt;

&lt;p&gt;A query that takes 5 milliseconds on a small dataset may behave very differently when the database has billions of rows and thousands of concurrent requests.&lt;/p&gt;




&lt;h2&gt;
  
  
  30. A Query Is a Request for Work
&lt;/h2&gt;

&lt;p&gt;The most useful way to think about a database query is not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I'm asking the database for some data."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"I'm asking the database to perform a specific computation over stored data."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the database has to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Find users
   ↓
Filter age &amp;gt; 18
   ↓
Sort by name
   ↓
Take 20
   ↓
Return result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The SQL statement describes &lt;strong&gt;what&lt;/strong&gt; you want.&lt;/p&gt;

&lt;p&gt;The database decides &lt;strong&gt;how&lt;/strong&gt; to produce it.&lt;/p&gt;

&lt;p&gt;That separation is one of the most important concepts in database systems.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Simple Mental Model
&lt;/h2&gt;

&lt;p&gt;Whenever you execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application
     ↓
Connection
     ↓
Database
     ↓
Parse Query
     ↓
Check Permissions
     ↓
Build Execution Plan
     ↓
Choose Index / Scan
     ↓
Read Memory / Storage
     ↓
Filter / Join / Sort if needed
     ↓
Build Result
     ↓
Return Result
     ↓
Application
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And when a query becomes slow, don't immediately blame the database.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What is the database actually doing?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Is it scanning millions of rows?&lt;/p&gt;

&lt;p&gt;Is it missing an appropriate index?&lt;/p&gt;

&lt;p&gt;Is it sorting a huge dataset?&lt;/p&gt;

&lt;p&gt;Is a join producing far more rows than expected?&lt;/p&gt;

&lt;p&gt;Is the database waiting on locks?&lt;/p&gt;

&lt;p&gt;Is the application exhausting its connection pool?&lt;/p&gt;

&lt;p&gt;Is the query simply doing too much work?&lt;/p&gt;

&lt;p&gt;Tools such as execution plans can help answer these questions.&lt;/p&gt;

&lt;p&gt;The biggest lesson is simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SQL describes what you want. The database figures out how to get it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once you understand that process, indexes, query optimization, transactions, joins, caching, connection pooling, and database scaling stop feeling like isolated concepts.&lt;/p&gt;

&lt;p&gt;They become different ways of controlling how much work the database has to perform to answer your application's questions.&lt;/p&gt;

</description>
      <category>backend</category>
      <category>database</category>
      <category>performance</category>
      <category>sql</category>
    </item>
    <item>
      <title>SQL vs NoSQL: Which Database Should You Use?</title>
      <dc:creator>Tanu Priya</dc:creator>
      <pubDate>Fri, 11 Sep 2026 09:49:45 +0000</pubDate>
      <link>https://dev.to/tanu_priya/sql-vs-nosql-which-database-should-you-use-20f7</link>
      <guid>https://dev.to/tanu_priya/sql-vs-nosql-which-database-should-you-use-20f7</guid>
      <description>&lt;p&gt;Choosing a database is one of those decisions that looks simple when you're starting a project.&lt;/p&gt;

&lt;p&gt;You might hear:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Use PostgreSQL."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Someone else says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"MongoDB is easier."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Another developer recommends:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Just use Redis."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And suddenly a simple application has turned into a database debate.&lt;/p&gt;

&lt;p&gt;The reality is that &lt;strong&gt;SQL vs NoSQL is not about finding the universally better database.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It's about understanding how your application stores, reads, updates, and relates data.&lt;/p&gt;

&lt;p&gt;The right database depends on your data model, consistency requirements, query patterns, scale, and how the application is expected to evolve.&lt;/p&gt;

&lt;p&gt;Let's break down the actual differences.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. What Is a Database?
&lt;/h2&gt;

&lt;p&gt;Before comparing SQL and NoSQL, let's understand the problem a database solves.&lt;/p&gt;

&lt;p&gt;Imagine an e-commerce application.&lt;/p&gt;

&lt;p&gt;You need to store:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Users
Products
Orders
Payments
Reviews
Inventory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without a database, you would need some way to persist all this information and retrieve it efficiently.&lt;/p&gt;

&lt;p&gt;A database provides:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application
     ↓
Database
     ↓
Persistent Data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The backend can ask questions such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Find this user."

"Give me all products in this category."

"Which orders belong to this customer?"

"How many products are in stock?"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Different databases are optimized for different types of questions.&lt;/p&gt;

&lt;p&gt;That's where SQL and NoSQL start to differ.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. What Is SQL?
&lt;/h2&gt;

&lt;p&gt;SQL databases are &lt;strong&gt;relational databases&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;SQL stands for &lt;strong&gt;Structured Query Language&lt;/strong&gt;, which is commonly used to interact with relational databases.&lt;/p&gt;

&lt;p&gt;Popular relational databases include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PostgreSQL
MySQL
MariaDB
SQL Server
Oracle Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The data is generally organized into tables.&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 plaintext"&gt;&lt;code&gt;Users
-------------------------
id | name  | email
-------------------------
1  | Alex  | alex@mail.com
2  | Sam   | sam@mail.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Orders
-------------------------
id | user_id | total
-------------------------
101| 1       | 4999
102| 2       | 2999
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;user_id&lt;/code&gt; can establish a relationship between orders and users.&lt;/p&gt;

&lt;p&gt;This relational model is one of the defining characteristics of SQL databases.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. What Is NoSQL?
&lt;/h2&gt;

&lt;p&gt;NoSQL is a broad category of databases that don't primarily use the traditional relational table model.&lt;/p&gt;

&lt;p&gt;Popular NoSQL databases include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MongoDB
Redis
Cassandra
DynamoDB
Couchbase
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But an important point is that &lt;strong&gt;NoSQL doesn't mean one specific database structure.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Different NoSQL databases use different models.&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 plaintext"&gt;&lt;code&gt;Document
Key-Value
Wide-Column
Graph
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MongoDB is primarily a document database.&lt;/p&gt;

&lt;p&gt;Redis is primarily a key-value/data-structure store.&lt;/p&gt;

&lt;p&gt;Cassandra uses a wide-column model.&lt;/p&gt;

&lt;p&gt;So saying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"NoSQL is just MongoDB."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;would be incorrect.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. SQL Uses Tables and Relationships
&lt;/h2&gt;

&lt;p&gt;Suppose you're building a blogging platform.&lt;/p&gt;

&lt;p&gt;You might have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Users
Posts
Comments
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A relational design could look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Users
  |
  | 1-to-many
  ↓
Posts
  |
  | 1-to-many
  ↓
Comments
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database can represent these relationships using keys.&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 sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ability to query relationships is one of the strengths of relational databases.&lt;/p&gt;

&lt;p&gt;You don't have to store the same user information repeatedly inside every post.&lt;/p&gt;

&lt;p&gt;Instead, you store the relationship.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. NoSQL Often Stores Data Differently
&lt;/h2&gt;

&lt;p&gt;A document database might store a product like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Mechanical Keyboard"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4999&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"keyboard"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"mechanical"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"gaming"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another product could have different fields:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;43&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Monitor"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15999&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"refreshRate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;144&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can make document databases convenient when records naturally have different shapes.&lt;/p&gt;

&lt;p&gt;Instead of forcing every record into the same set of columns, documents can have more flexible structures.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Schema: Fixed vs Flexible
&lt;/h2&gt;

&lt;p&gt;One of the common differences between SQL and NoSQL is how schemas are handled.&lt;/p&gt;

&lt;p&gt;A SQL table might define:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&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;span class="n"&gt;email&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The structure is explicitly defined.&lt;/p&gt;

&lt;p&gt;A document database can allow documents with different fields:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Alex"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"alex@example.com"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Sam"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sam@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"github"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"samdev"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This flexibility can be useful when application data changes frequently.&lt;/p&gt;

&lt;p&gt;But flexible schema doesn't mean:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"No structure is required."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You still need to think carefully about how your data is modeled.&lt;/p&gt;

&lt;p&gt;Otherwise, flexibility can turn into inconsistency.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. SQL Is Strong When Relationships Matter
&lt;/h2&gt;

&lt;p&gt;Consider a banking system.&lt;/p&gt;

&lt;p&gt;You might have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customers
Accounts
Transactions
Loans
Payments
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These entities are strongly related.&lt;/p&gt;

&lt;p&gt;A transaction belongs to an account.&lt;/p&gt;

&lt;p&gt;An account belongs to a customer.&lt;/p&gt;

&lt;p&gt;A payment may be associated with an account or loan.&lt;/p&gt;

&lt;p&gt;You often need queries involving multiple related entities.&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 plaintext"&gt;&lt;code&gt;Find all transactions
for a particular customer
during a particular month.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Relational databases are very good at expressing this type of structured relationship.&lt;/p&gt;

&lt;p&gt;This is one reason SQL databases are common for systems involving complex relationships and transactional data.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. SQL and Transactions
&lt;/h2&gt;

&lt;p&gt;Transactions are another major reason developers choose relational databases.&lt;/p&gt;

&lt;p&gt;Suppose you transfer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;₹1,000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;from Account A to Account B.&lt;/p&gt;

&lt;p&gt;You don't want this to happen:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Account A → -₹1,000

Account B → unchanged
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The operation should behave as one logical unit.&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;BEGIN
   ↓
Debit Account A
   ↓
Credit Account B
   ↓
COMMIT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If something goes wrong:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BEGIN
   ↓
Debit Account A
   ↓
ERROR
   ↓
ROLLBACK
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database can maintain transactional guarantees so the system doesn't end up with partially completed operations.&lt;/p&gt;

&lt;p&gt;This is extremely important for many financial and business applications.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. ACID Properties
&lt;/h2&gt;

&lt;p&gt;Relational databases are commonly associated with &lt;strong&gt;ACID transactions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;ACID stands for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Atomicity
Consistency
Isolation
Durability
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A simplified understanding:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Atomicity&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The transaction succeeds as a unit or is rolled back.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consistency&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The database moves from one valid state to another while respecting its rules.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Isolation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Concurrent transactions should not incorrectly interfere with each other.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Durability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once committed, the data should persist despite failures within the database system's durability guarantees.&lt;/p&gt;

&lt;p&gt;You don't need to memorize these immediately.&lt;/p&gt;

&lt;p&gt;The important idea is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Transactions help keep related operations consistent.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  10. Does NoSQL Not Support Transactions?
&lt;/h2&gt;

&lt;p&gt;This is a common misconception.&lt;/p&gt;

&lt;p&gt;NoSQL does &lt;strong&gt;not&lt;/strong&gt; mean:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"No transactions."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Many modern NoSQL databases support transactional operations, although the exact capabilities and trade-offs differ by database.&lt;/p&gt;

&lt;p&gt;The more useful question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What transactional model does this database provide, and does it fit my application's requirements?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Don't choose a database based on old stereotypes.&lt;/p&gt;

&lt;p&gt;Look at the actual database and its guarantees.&lt;/p&gt;




&lt;h2&gt;
  
  
  11. NoSQL Can Be Useful for Flexible Data
&lt;/h2&gt;

&lt;p&gt;Imagine you're building a content platform where different types of content have different structures.&lt;/p&gt;

&lt;p&gt;A video might contain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"System Design Basics"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"duration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;420&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"resolution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1080p"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An article might contain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Understanding Redis"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"author"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Alex"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"readingTime"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A document-oriented database can naturally represent these different shapes.&lt;/p&gt;

&lt;p&gt;This can reduce friction when your data model is evolving or naturally document-oriented.&lt;/p&gt;

&lt;p&gt;But again, flexible data models still require good design.&lt;/p&gt;




&lt;h2&gt;
  
  
  12. SQL vs NoSQL Is Also About Query Patterns
&lt;/h2&gt;

&lt;p&gt;One of the biggest mistakes is asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Which database is faster?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's usually the wrong first question.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What queries will my application perform most often?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;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;Find user by email
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Get all orders for a user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Get latest 20 posts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Find products by category and price range
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database should be selected based partly on these access patterns.&lt;/p&gt;

&lt;p&gt;A database that is excellent for one workload might be a poor choice for another.&lt;/p&gt;




&lt;h2&gt;
  
  
  13. SQL Query Example
&lt;/h2&gt;

&lt;p&gt;Suppose you need all orders for a user.&lt;/p&gt;

&lt;p&gt;You might write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database can use indexes to make this query efficient.&lt;/p&gt;

&lt;p&gt;For a more complex query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;
&lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SQL is designed to express these kinds of relational queries.&lt;/p&gt;

&lt;p&gt;This is one of the reasons SQL remains extremely popular.&lt;/p&gt;




&lt;h2&gt;
  
  
  14. NoSQL Query Example
&lt;/h2&gt;

&lt;p&gt;In a document database, you might store data in a structure designed around how the application reads 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 json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"userId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Alex"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"orders"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"orderId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;101&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"total"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4999&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"orderId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;102&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"total"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2999&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now retrieving the user's orders can potentially involve reading one document.&lt;/p&gt;

&lt;p&gt;This is an important NoSQL design principle:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Model data around the queries your application needs.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead of always normalizing everything into separate tables, some NoSQL systems encourage denormalizing data when it makes common reads more efficient.&lt;/p&gt;




&lt;h2&gt;
  
  
  15. Normalization vs Denormalization
&lt;/h2&gt;

&lt;p&gt;SQL systems often encourage &lt;strong&gt;normalization&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of storing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Name
User Email
User Name
User Email
User Name
User Email
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in many places, you might store the user once and reference them using an ID.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Users
   ↓
user_id
   ↓
Orders
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This reduces unnecessary duplication.&lt;/p&gt;

&lt;p&gt;NoSQL systems may sometimes favor &lt;strong&gt;denormalization&lt;/strong&gt;.&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 json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"orderId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;101&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"customer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Alex"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"alex@example.com"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"total"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4999&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the order contains customer information directly.&lt;/p&gt;

&lt;p&gt;The trade-off is that duplicated data can become harder to keep synchronized.&lt;/p&gt;

&lt;p&gt;So neither approach is automatically better.&lt;/p&gt;

&lt;p&gt;The correct choice depends on how the application reads and updates data.&lt;/p&gt;




&lt;h2&gt;
  
  
  16. Scaling SQL Databases
&lt;/h2&gt;

&lt;p&gt;SQL databases can scale very well.&lt;/p&gt;

&lt;p&gt;A common architecture might start as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application
     ↓
PostgreSQL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As traffic grows, you might introduce:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application
     ↓
Connection Pool
     ↓
Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then potentially:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application
     ↓
Read/Write Layer
     ↓
 ┌───────────────┐
 ↓               ↓
Primary       Read Replicas
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;indexes&lt;/li&gt;
&lt;li&gt;caching&lt;/li&gt;
&lt;li&gt;read replicas&lt;/li&gt;
&lt;li&gt;partitioning&lt;/li&gt;
&lt;li&gt;sharding&lt;/li&gt;
&lt;li&gt;connection pooling&lt;/li&gt;
&lt;/ul&gt;

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

&lt;blockquote&gt;
&lt;p&gt;"SQL can't scale."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;is simply not true.&lt;/p&gt;

&lt;p&gt;The real question is how you scale the particular database and workload.&lt;/p&gt;




&lt;h2&gt;
  
  
  17. Scaling NoSQL Databases
&lt;/h2&gt;

&lt;p&gt;Many NoSQL systems are designed with horizontal scaling in mind.&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;             Application
                  ↓
             NoSQL Cluster
          ┌───────┼───────┐
          ↓       ↓       ↓
        Node 1  Node 2  Node 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Data can be distributed across multiple nodes depending on the database's architecture and configuration.&lt;/p&gt;

&lt;p&gt;This can be particularly useful for workloads involving:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;very large datasets&lt;/li&gt;
&lt;li&gt;high write volume&lt;/li&gt;
&lt;li&gt;geographically distributed traffic&lt;/li&gt;
&lt;li&gt;predictable access patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But horizontal scalability is not a free advantage.&lt;/p&gt;

&lt;p&gt;Distributed systems introduce complexity around consistency, partitioning, replication, failure handling, and operations.&lt;/p&gt;




&lt;h2&gt;
  
  
  18. SQL vs NoSQL: Consistency Trade-offs
&lt;/h2&gt;

&lt;p&gt;One of the deeper database decisions is consistency.&lt;/p&gt;

&lt;p&gt;Suppose a user changes their profile.&lt;/p&gt;

&lt;p&gt;You might expect:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Write
 ↓
Read
 ↓
Immediately see new value
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some distributed architectures may allow replicas to temporarily contain different versions of the data.&lt;/p&gt;

&lt;p&gt;You might have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Primary
   ↓
Replication
   ↓
Replica
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For some applications, slight replication delay is acceptable.&lt;/p&gt;

&lt;p&gt;For others, it may not be.&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 plaintext"&gt;&lt;code&gt;Social media feed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;might tolerate some delay.&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 plaintext"&gt;&lt;code&gt;Bank account balance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;has much stricter requirements.&lt;/p&gt;

&lt;p&gt;The important question is:&lt;/p&gt;

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




&lt;h2&gt;
  
  
  19. SQL vs NoSQL Is Not a Religion
&lt;/h2&gt;

&lt;p&gt;Developers sometimes turn database selection into a technology argument.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"PostgreSQL is better."

"No, MongoDB is better."

"SQL is outdated."

"NoSQL is unreliable."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These arguments usually miss the point.&lt;/p&gt;

&lt;p&gt;A database is a tool.&lt;/p&gt;

&lt;p&gt;The right question is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What does the application need?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Which database is trendy?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  20. When SQL Is Usually a Strong Choice
&lt;/h2&gt;

&lt;p&gt;SQL is often a good fit when your application has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;complex relationships&lt;/li&gt;
&lt;li&gt;structured data&lt;/li&gt;
&lt;li&gt;strong transactional requirements&lt;/li&gt;
&lt;li&gt;complex queries&lt;/li&gt;
&lt;li&gt;reporting requirements&lt;/li&gt;
&lt;li&gt;joins across entities&lt;/li&gt;
&lt;li&gt;well-defined business rules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Examples could include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Banking
Accounting
ERP
Inventory
E-commerce
Booking systems
Order management
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These systems often benefit from relational modeling and strong transaction support.&lt;/p&gt;




&lt;h2&gt;
  
  
  21. When NoSQL Can Be a Strong Choice
&lt;/h2&gt;

&lt;p&gt;NoSQL can be a good fit when you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;flexible or rapidly changing document structures&lt;/li&gt;
&lt;li&gt;very high-scale distributed workloads&lt;/li&gt;
&lt;li&gt;access patterns that fit a document/key-value/wide-column model&lt;/li&gt;
&lt;li&gt;large amounts of data&lt;/li&gt;
&lt;li&gt;workloads where horizontal distribution is important&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Examples might include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Event data
Activity feeds
Catalog-like documents
High-volume telemetry
Caching
Distributed key-value workloads
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But the exact database still matters.&lt;/p&gt;

&lt;p&gt;MongoDB, Redis, Cassandra, and DynamoDB solve different problems.&lt;/p&gt;




&lt;h2&gt;
  
  
  22. You Don't Have to Choose Only One
&lt;/h2&gt;

&lt;p&gt;This is an important point.&lt;/p&gt;

&lt;p&gt;Real systems often use multiple data stores.&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 plaintext"&gt;&lt;code&gt;                Application
                     |
          ┌──────────┼──────────┐
          ↓          ↓          ↓
      PostgreSQL   Redis    Object Storage
          |
       Primary Data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;PostgreSQL might store:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Users
Orders
Payments
Products
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Redis might store:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sessions
Cache
Rate Limits
Temporary Data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Object storage might contain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Images
Videos
Documents
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each system has a different responsibility.&lt;/p&gt;

&lt;p&gt;This is sometimes called &lt;strong&gt;polyglot persistence&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The goal isn't to force every type of data into one database.&lt;/p&gt;

&lt;p&gt;The goal is to use the appropriate storage system for each workload.&lt;/p&gt;




&lt;h2&gt;
  
  
  23. Don't Add a Database Just Because You Can
&lt;/h2&gt;

&lt;p&gt;Using multiple databases sounds powerful.&lt;/p&gt;

&lt;p&gt;But every additional system adds operational complexity.&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 plaintext"&gt;&lt;code&gt;PostgreSQL
Redis
MongoDB
Kafka
Elasticsearch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;means your team now needs to understand, monitor, secure, back up, upgrade, and troubleshoot all of them.&lt;/p&gt;

&lt;p&gt;If PostgreSQL solves the problem effectively, adding MongoDB just because it is popular may make the architecture worse.&lt;/p&gt;

&lt;p&gt;A good rule is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Use another database when it solves a real problem, not because it sounds more scalable.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  24. Database Choice Should Start With the Data Model
&lt;/h2&gt;

&lt;p&gt;Before choosing a database, ask:&lt;/p&gt;

&lt;h3&gt;
  
  
  What data am I storing?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Users
Orders
Products
Events
Sessions
Logs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How are these entities related?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User → Orders
Order → Products
Product → Reviews
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How will the application query the data?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;By ID?
By email?
By time?
By category?
By relationship?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How often does the data change?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Frequently?
Occasionally?
Mostly read-only?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How important is consistency?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Eventually consistent?
Strong consistency?
Transactional?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How much data and traffic do I expect?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1,000 users?
1 million?
100 million?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These questions are much more useful than simply asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"SQL or NoSQL?"&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  25. A Practical Decision Framework
&lt;/h2&gt;

&lt;p&gt;You can use a simple process.&lt;/p&gt;

&lt;p&gt;Start with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Do I have strong relationships
between entities?
        |
        ├── Yes → Consider SQL
        |
        └── No
             ↓
Do I need flexible documents
or a specialized NoSQL model?
             |
             ├── Yes → Consider NoSQL
             |
             └── No → Evaluate based on workload
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What queries will dominate?

What consistency is required?

What scale is expected?

What operational complexity can the team handle?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The answers should drive the decision.&lt;/p&gt;




&lt;h2&gt;
  
  
  26. The Database Is Part of System Design
&lt;/h2&gt;

&lt;p&gt;Choosing a database isn't an isolated decision.&lt;/p&gt;

&lt;p&gt;It affects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;API Design
     ↓
Data Model
     ↓
Caching
     ↓
Scaling
     ↓
Consistency
     ↓
Reliability
     ↓
Operations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, choosing a relational database may influence how you model relationships.&lt;/p&gt;

&lt;p&gt;Choosing a distributed NoSQL system may influence how you design partition keys.&lt;/p&gt;

&lt;p&gt;Choosing Redis for caching introduces cache invalidation and expiration decisions.&lt;/p&gt;

&lt;p&gt;The database becomes part of the overall architecture.&lt;/p&gt;




&lt;h2&gt;
  
  
  27. A Common Beginner Mistake
&lt;/h2&gt;

&lt;p&gt;A common mistake is choosing a database before understanding the application.&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 plaintext"&gt;&lt;code&gt;"I learned MongoDB, so I'll use MongoDB."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Everyone uses PostgreSQL, so I'll use PostgreSQL."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neither is a strong architectural decision.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Requirements
     ↓
Data Model
     ↓
Access Patterns
     ↓
Consistency Requirements
     ↓
Scale
     ↓
Database Choice
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database should follow the problem.&lt;/p&gt;

&lt;p&gt;Not the other way around.&lt;/p&gt;




&lt;h2&gt;
  
  
  SQL vs NoSQL at a Glance
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Requirement&lt;/th&gt;
&lt;th&gt;SQL&lt;/th&gt;
&lt;th&gt;NoSQL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Structured data&lt;/td&gt;
&lt;td&gt;Strong fit&lt;/td&gt;
&lt;td&gt;Depends on database&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Complex relationships&lt;/td&gt;
&lt;td&gt;Strong fit&lt;/td&gt;
&lt;td&gt;Often more application-managed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Joins&lt;/td&gt;
&lt;td&gt;Strong&lt;/td&gt;
&lt;td&gt;Usually limited/different&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transactions&lt;/td&gt;
&lt;td&gt;Strong support&lt;/td&gt;
&lt;td&gt;Depends on database&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flexible schema&lt;/td&gt;
&lt;td&gt;Possible, but typically more structured&lt;/td&gt;
&lt;td&gt;Often a strength&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Horizontal scaling&lt;/td&gt;
&lt;td&gt;Possible&lt;/td&gt;
&lt;td&gt;Often a core design goal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Complex queries&lt;/td&gt;
&lt;td&gt;Strong&lt;/td&gt;
&lt;td&gt;Depends on database&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Document-oriented data&lt;/td&gt;
&lt;td&gt;Possible&lt;/td&gt;
&lt;td&gt;Often a strong fit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Key-value workloads&lt;/td&gt;
&lt;td&gt;Usually not the primary strength&lt;/td&gt;
&lt;td&gt;Strong fit for some systems&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reporting&lt;/td&gt;
&lt;td&gt;Often strong&lt;/td&gt;
&lt;td&gt;Depends on database&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This table is intentionally simplified.&lt;/p&gt;

&lt;p&gt;Different databases have different capabilities, and modern SQL and NoSQL systems overlap more than many beginner comparisons suggest.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Bigger Lesson
&lt;/h2&gt;

&lt;p&gt;The real SQL vs NoSQL question isn't:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Which database is better?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Which data model, query model, consistency model, and scaling strategy best fit my application?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If your application has:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Users
Orders
Payments
Inventory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and those entities have strong relationships and transactional requirements, a relational database may be a natural starting point.&lt;/p&gt;

&lt;p&gt;If your application primarily works with flexible documents, massive distributed workloads, or specialized access patterns, a NoSQL database may be a better fit.&lt;/p&gt;

&lt;p&gt;And sometimes the answer is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SQL + NoSQL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;because different parts of the system have different requirements.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Simple Mental Model
&lt;/h2&gt;

&lt;p&gt;Before choosing a database, think through:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                Requirements
                     ↓
                 What data?
                     ↓
              How is it related?
                     ↓
              How will I query it?
                     ↓
            How consistent must it be?
                     ↓
              How much will it scale?
                     ↓
              Choose the database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't start with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SQL vs NoSQL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What problem am I trying to solve?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the mindset that leads to better database decisions.&lt;/p&gt;

&lt;p&gt;A database isn't good because it is popular.&lt;/p&gt;

&lt;p&gt;A database is good when its &lt;strong&gt;data model, guarantees, query capabilities, performance characteristics, and operational requirements match the problem you're solving.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And that's the real difference between choosing a database because you've heard of it and choosing one because your system actually needs it.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>backend</category>
      <category>database</category>
      <category>sql</category>
    </item>
    <item>
      <title>How Does a Backend Actually Connect to a Database?</title>
      <dc:creator>Tanu Priya</dc:creator>
      <pubDate>Thu, 10 Sep 2026 07:41:20 +0000</pubDate>
      <link>https://dev.to/tanu_priya/how-does-a-backend-actually-connect-to-a-database-24pa</link>
      <guid>https://dev.to/tanu_priya/how-does-a-backend-actually-connect-to-a-database-24pa</guid>
      <description>&lt;p&gt;Every time your API reads or writes data, there is a chain of components working behind the scenes: &lt;strong&gt;API → Backend → ORM/Database Driver → Connection Pool → Database → Result&lt;/strong&gt;. The database driver handles communication, connection pools prevent your application from creating a new connection for every request, and ORMs make database operations easier without eliminating SQL underneath. Understanding this flow is essential once you move beyond building simple APIs.&lt;/p&gt;

&lt;p&gt;You 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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;prisma&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;findUnique&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;where&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="mi"&gt;42&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 somehow a database returns the correct user.&lt;/p&gt;

&lt;p&gt;It looks like one line of code.&lt;/p&gt;

&lt;p&gt;It isn't.&lt;/p&gt;

&lt;p&gt;Behind that line, your application has to communicate with another system, obtain a database connection, send a query, wait for the database to execute it, receive the result, and return that connection so another request can use it.&lt;/p&gt;

&lt;p&gt;And when your application goes from 10 users to 10,000 users, those details stop being implementation trivia.&lt;/p&gt;

&lt;p&gt;They become architecture.&lt;/p&gt;

&lt;p&gt;This is the part of backend development that most tutorials hide.&lt;/p&gt;

&lt;p&gt;Let's look at what actually happens.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Request That Started It All
&lt;/h2&gt;

&lt;p&gt;Imagine you're building a blogging platform.&lt;/p&gt;

&lt;p&gt;A user opens their profile.&lt;/p&gt;

&lt;p&gt;The browser sends:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /api/users/42
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your backend receives the request and needs to return:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Alex"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"alex@example.com"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The obvious mental model is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;API → Database → Result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The real system is closer to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client
   ↓
API
   ↓
Backend
   ↓
ORM / Database Driver
   ↓
Connection Pool
   ↓
Database
   ↓
Query Result
   ↓
Backend
   ↓
API Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That middle section is where most of the interesting engineering happens.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The Database Driver: Your Backend's Translator
&lt;/h2&gt;

&lt;p&gt;Your Node.js, Python, Java, or Go application doesn't automatically know how to communicate with PostgreSQL or MySQL.&lt;/p&gt;

&lt;p&gt;It needs a &lt;strong&gt;database driver&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example, a Node.js application can use the PostgreSQL &lt;code&gt;pg&lt;/code&gt; driver.&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;Application
     ↓
Database Driver
     ↓
PostgreSQL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A simplified 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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;pg&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Pool&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pg&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Pool&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;connectionString&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DATABASE_URL&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The driver handles the database-specific communication.&lt;/p&gt;

&lt;p&gt;Your application says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Run this query."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The driver takes care of communicating with the database.&lt;/p&gt;

&lt;p&gt;This separation is useful because your application doesn't need to understand every low-level detail of the database protocol.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Then There Is the Query
&lt;/h2&gt;

&lt;p&gt;Once your application can communicate with the database, it needs to tell the database what it wants.&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 sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database receives that query and does the actual database work.&lt;/p&gt;

&lt;p&gt;It has to determine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which table is involved?&lt;/li&gt;
&lt;li&gt;Which rows match?&lt;/li&gt;
&lt;li&gt;Should an index be used?&lt;/li&gt;
&lt;li&gt;How should the query be executed?&lt;/li&gt;
&lt;li&gt;What data needs to be returned?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The database then sends the result back to your application.&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 json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Alex"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"alex@example.com"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your backend turns that into an API response.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTP Request
     ↓
Backend
     ↓
SQL Query
     ↓
Database
     ↓
Result
     ↓
Backend
     ↓
HTTP Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the basic version.&lt;/p&gt;

&lt;p&gt;But there's a scalability problem.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Why You Can't Just Open a New Connection for Every Request
&lt;/h2&gt;

&lt;p&gt;Suppose your API receives 1,000 requests.&lt;/p&gt;

&lt;p&gt;A naive approach would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request 1 → Open Connection → Query → Close
Request 2 → Open Connection → Query → Close
Request 3 → Open Connection → Query → Close
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It sounds reasonable.&lt;/p&gt;

&lt;p&gt;It isn't.&lt;/p&gt;

&lt;p&gt;Creating database connections consumes resources. Doing it repeatedly adds unnecessary overhead and can put significant pressure on the database.&lt;/p&gt;

&lt;p&gt;Instead, production applications generally reuse connections.&lt;/p&gt;

&lt;p&gt;That's what &lt;strong&gt;connection pooling&lt;/strong&gt; is for.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Connection Pools: The Unsung Hero of Backend Systems
&lt;/h2&gt;

&lt;p&gt;A connection pool maintains a set of reusable database connections.&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 plaintext"&gt;&lt;code&gt;Request
   ↓
Create Connection
   ↓
Query
   ↓
Destroy Connection
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request
   ↓
Borrow Connection
   ↓
Run Query
   ↓
Return Connection
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A pool might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             Connection Pool

        ┌─────────────────────┐
        │ Connection 1        │
        │ Connection 2        │
        │ Connection 3        │
        │ Connection 4        │
        └─────────────────────┘
                  │
                  ↓
               Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Imagine four requests arrive.&lt;/p&gt;

&lt;p&gt;They can use the available connections:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request A → Connection 1
Request B → Connection 2
Request C → Connection 3
Request D → Connection 4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When Request A finishes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Connection 1 → Available Again
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another request can reuse it.&lt;/p&gt;

&lt;p&gt;The connection doesn't need to be recreated.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. More Connections Doesn't Mean More Speed
&lt;/h2&gt;

&lt;p&gt;This is one of those backend lessons that becomes important only after you start dealing with production systems.&lt;/p&gt;

&lt;p&gt;You might think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"If 10 connections are good, 100 connections must be better."&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;Your database has finite resources.&lt;/p&gt;

&lt;p&gt;Too many connections can create:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;memory pressure&lt;/li&gt;
&lt;li&gt;CPU overhead&lt;/li&gt;
&lt;li&gt;contention&lt;/li&gt;
&lt;li&gt;increased latency&lt;/li&gt;
&lt;li&gt;unnecessary database load&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So a connection pool isn't just a performance trick.&lt;/p&gt;

&lt;p&gt;It's also a &lt;strong&gt;concurrency control mechanism&lt;/strong&gt;.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Pool&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;connectionString&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DATABASE_URL&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;10&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The correct pool size depends on your workload, database, server resources, and deployment architecture.&lt;/p&gt;

&lt;p&gt;The important lesson is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Your backend shouldn't be allowed to create an unlimited number of database connections.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  6. Where Does an ORM Fit?
&lt;/h2&gt;

&lt;p&gt;Now let's make the architecture more realistic.&lt;/p&gt;

&lt;p&gt;Most modern applications don't write SQL for every simple database operation.&lt;/p&gt;

&lt;p&gt;You might use an ORM such as Prisma.&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 sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you 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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;prisma&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;findUnique&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;where&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="mi"&gt;42&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;Much cleaner.&lt;/p&gt;

&lt;p&gt;But don't let the abstraction fool you.&lt;/p&gt;

&lt;p&gt;The database hasn't disappeared.&lt;/p&gt;

&lt;p&gt;The architecture is now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your Application
       ↓
      ORM
       ↓
Database Driver
       ↓
Connection Pool
       ↓
Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The ORM gives you a more convenient interface for working with the database.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. ORM Doesn't Mean "No SQL"
&lt;/h2&gt;

&lt;p&gt;This is probably the most important misconception to clear up.&lt;/p&gt;

&lt;p&gt;If you use Prisma, Sequelize, TypeORM, or another ORM, you're not avoiding databases.&lt;/p&gt;

&lt;p&gt;You're avoiding &lt;strong&gt;manually writing every database query&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The underlying system still needs database operations.&lt;/p&gt;

&lt;p&gt;So when you 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="nx"&gt;prisma&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;findUnique&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;where&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="mi"&gt;42&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 database still has to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Receive Query
     ↓
Understand Query
     ↓
Create Execution Plan
     ↓
Read Data
     ↓
Return Result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The ORM simply provides a higher-level way of expressing what you want.&lt;/p&gt;

&lt;p&gt;That's why SQL knowledge doesn't become irrelevant when you learn an ORM.&lt;/p&gt;

&lt;p&gt;If anything, it becomes more useful when things stop working as expected.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Raw SQL vs ORM: The Tradeoff
&lt;/h2&gt;

&lt;p&gt;This isn't really an argument about which technology is "better."&lt;/p&gt;

&lt;p&gt;It's about &lt;strong&gt;how much control versus abstraction you need&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Raw SQL
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;post_count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;LEFT&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;
    &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;author_id&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You control the query directly.&lt;/p&gt;

&lt;p&gt;That's valuable for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;complex joins&lt;/li&gt;
&lt;li&gt;aggregations&lt;/li&gt;
&lt;li&gt;database-specific features&lt;/li&gt;
&lt;li&gt;performance tuning&lt;/li&gt;
&lt;li&gt;advanced queries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But you're also responsible for writing and maintaining the SQL.&lt;/p&gt;

&lt;h3&gt;
  
  
  ORM
&lt;/h3&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;prisma&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;findMany&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;include&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;posts&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;p&gt;This can make everyday development much faster.&lt;/p&gt;

&lt;p&gt;You may also get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;type safety&lt;/li&gt;
&lt;li&gt;migrations&lt;/li&gt;
&lt;li&gt;schema modeling&lt;/li&gt;
&lt;li&gt;autocomplete&lt;/li&gt;
&lt;li&gt;relationship handling&lt;/li&gt;
&lt;li&gt;developer tooling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The tradeoff is abstraction.&lt;/p&gt;

&lt;p&gt;The ORM decides how your high-level operation gets translated into database operations.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. The Approach I'd Actually Recommend
&lt;/h2&gt;

&lt;p&gt;For most application development:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use the ORM where it makes the code simpler.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But don't treat it as a black box.&lt;/p&gt;

&lt;p&gt;If you encounter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a slow query&lt;/li&gt;
&lt;li&gt;unexpected database load&lt;/li&gt;
&lt;li&gt;a complicated join&lt;/li&gt;
&lt;li&gt;an inefficient query&lt;/li&gt;
&lt;li&gt;a database-specific requirement&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;drop down a level.&lt;/p&gt;

&lt;p&gt;Think of it 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;                 Your Application
                        │
                        ↓
              ┌──────────────────┐
              │       ORM        │
              └──────────────────┘
                    │        │
             Simple Queries  │
                    │        ↓
                    │     Raw SQL
                    │        │
                    └────┬───┘
                         ↓
                  Database Driver
                         ↓
                  Connection Pool
                         ↓
                      Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal isn't to eliminate SQL.&lt;/p&gt;

&lt;p&gt;The goal is to use the right abstraction for the job.&lt;/p&gt;




&lt;h2&gt;
  
  
  10. What Happens When the Database Is Slow?
&lt;/h2&gt;

&lt;p&gt;Here's where understanding the architecture starts paying off.&lt;/p&gt;

&lt;p&gt;Your endpoint suddenly takes three seconds.&lt;/p&gt;

&lt;p&gt;You look at the backend 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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;prisma&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;findUnique&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;where&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="mi"&gt;42&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;Nothing obviously looks wrong.&lt;/p&gt;

&lt;p&gt;So where is the bottleneck?&lt;/p&gt;

&lt;p&gt;It could be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;API
 ↓
Backend
 ↓
ORM
 ↓
Connection Pool
 ↓
Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Maybe:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the connection pool is exhausted&lt;/li&gt;
&lt;li&gt;the query is slow&lt;/li&gt;
&lt;li&gt;an index is missing&lt;/li&gt;
&lt;li&gt;the database is overloaded&lt;/li&gt;
&lt;li&gt;too much data is being returned&lt;/li&gt;
&lt;li&gt;another query is consuming resources&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is why knowing only the ORM isn't enough.&lt;/p&gt;

&lt;p&gt;You need to understand the layers underneath it.&lt;/p&gt;




&lt;h2&gt;
  
  
  11. Indexes: When the Database Has Too Much Data to Search
&lt;/h2&gt;

&lt;p&gt;Imagine your &lt;code&gt;users&lt;/code&gt; table contains 10 million rows.&lt;/p&gt;

&lt;p&gt;You run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'alex@example.com'&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 appropriate index, the database may need to inspect a large amount of data to find the matching record.&lt;/p&gt;

&lt;p&gt;With an index, the database can often locate the relevant record much more efficiently.&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;Without useful index:

Database
 ↓
Check many rows
 ↓
Find matching row


With index:

Database
 ↓
Index
 ↓
Matching row
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is why database performance isn't simply about writing faster backend code.&lt;/p&gt;

&lt;p&gt;Sometimes the bottleneck is inside the database itself.&lt;/p&gt;




&lt;h2&gt;
  
  
  12. What About Multiple Operations?
&lt;/h2&gt;

&lt;p&gt;Suppose a user publishes a post.&lt;/p&gt;

&lt;p&gt;Your application needs to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create Post
    ↓
Update User Statistics
    ↓
Create Activity Record
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What happens if:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create Post          ✅
Update Statistics    ❌
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now your data may be inconsistent.&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;transactions&lt;/strong&gt; become important.&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;BEGIN
  ↓
Create Post
  ↓
Update Statistics
  ↓
Create Activity
  ↓
COMMIT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If something fails:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BEGIN
  ↓
Create Post
  ↓
Update Statistics
  ↓
ERROR
  ↓
ROLLBACK
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of treating each operation independently, the database can treat the group as one logical unit.&lt;/p&gt;

&lt;p&gt;This is another reason understanding databases matters even if an ORM handles the syntax for you.&lt;/p&gt;




&lt;h2&gt;
  
  
  13. Things Get More Interesting When You Scale
&lt;/h2&gt;

&lt;p&gt;Imagine your application grows.&lt;/p&gt;

&lt;p&gt;You start with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1 Backend Server
       ↓
   Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then traffic increases.&lt;/p&gt;

&lt;p&gt;You add more servers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 Load Balancer
                /      |      \
               ↓       ↓       ↓
            Server  Server  Server
               \       |       /
                \      |      /
                 Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now there's something easy to overlook:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Each application server may have its own connection pool.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Suppose you configure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;20 connections per server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;5 backend servers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You could potentially have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;5 × 20 = 100
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;database connections.&lt;/p&gt;

&lt;p&gt;So scaling your application servers can also increase the number of connections reaching your database.&lt;/p&gt;

&lt;p&gt;This is why database configuration cannot be considered separately from application architecture.&lt;/p&gt;




&lt;h2&gt;
  
  
  14. The Production Stack Is More Than "Backend + Database"
&lt;/h2&gt;

&lt;p&gt;A beginner's architecture often looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Frontend
   ↓
Backend
   ↓
Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A production system can look more like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    Client
                      ↓
                Load Balancer
                      ↓
              Backend Servers
                      ↓
                ORM / Driver
                      ↓
               Connection Pool
                      ↓
          ┌───────────┴───────────┐
          ↓                       ↓
       Cache                  Database
                                  ↓
                               Indexes
                                  ↓
                              Storage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And depending on the application, you may also introduce:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;queues&lt;/li&gt;
&lt;li&gt;background workers&lt;/li&gt;
&lt;li&gt;read replicas&lt;/li&gt;
&lt;li&gt;monitoring&lt;/li&gt;
&lt;li&gt;caching layers&lt;/li&gt;
&lt;li&gt;database migrations&lt;/li&gt;
&lt;li&gt;transaction management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The database is not an isolated component.&lt;/p&gt;

&lt;p&gt;It's part of a larger system.&lt;/p&gt;




&lt;h2&gt;
  
  
  15. Common Mistakes Developers Make
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Creating a connection for every request
&lt;/h3&gt;

&lt;p&gt;This defeats one of the main benefits of connection pooling.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting the pool size arbitrarily high
&lt;/h3&gt;

&lt;p&gt;More connections can eventually make the database less stable, not more performant.&lt;/p&gt;

&lt;h3&gt;
  
  
  Assuming the ORM automatically creates efficient queries
&lt;/h3&gt;

&lt;p&gt;ORMs are useful abstractions, but developers still need to understand the queries their applications generate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ignoring indexes
&lt;/h3&gt;

&lt;p&gt;A perfectly written API can still be slow because the database is doing unnecessary work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Never learning SQL
&lt;/h3&gt;

&lt;p&gt;This becomes painful when you need to debug a slow query or understand why the database isn't behaving as expected.&lt;/p&gt;

&lt;h3&gt;
  
  
  Treating the database as a simple storage box
&lt;/h3&gt;

&lt;p&gt;A database isn't just where your JSON happens to live.&lt;/p&gt;

&lt;p&gt;It is an engine that manages querying, indexing, concurrency, consistency, transactions, and much more.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Mental Model That Actually Matters
&lt;/h2&gt;

&lt;p&gt;If you remember only one diagram from this article, make it this one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    API Request
                         ↓
                  Backend Server
                         ↓
                   ORM / Driver
                         ↓
                  Connection Pool
                         ↓
                     Database
                         ↓
                   Query Result
                         ↓
                  Backend Server
                         ↓
                  API Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each layer solves a different problem.&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;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;API&lt;/td&gt;
&lt;td&gt;Communicates with clients&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backend&lt;/td&gt;
&lt;td&gt;Handles application logic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ORM&lt;/td&gt;
&lt;td&gt;Provides a high-level database interface&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Driver&lt;/td&gt;
&lt;td&gt;Communicates with the database&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Connection Pool&lt;/td&gt;
&lt;td&gt;Reuses and manages connections&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database&lt;/td&gt;
&lt;td&gt;Stores and processes data&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Once you understand this pipeline, a lot of backend concepts stop feeling disconnected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Indexes&lt;/strong&gt; make database lookups more efficient.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Transactions&lt;/strong&gt; protect consistency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Connection pools&lt;/strong&gt; manage database concurrency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ORMs&lt;/strong&gt; provide abstraction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SQL&lt;/strong&gt; gives you direct control.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Caching&lt;/strong&gt; reduces unnecessary database work.&lt;/p&gt;

&lt;p&gt;They're all pieces of the same system.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Take
&lt;/h2&gt;

&lt;p&gt;The interesting thing about database communication is that the code you write is often the smallest part of the story.&lt;/p&gt;

&lt;p&gt;You might 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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;prisma&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;findUnique&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;where&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="mi"&gt;42&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;But underneath that line is an entire pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application
    ↓
ORM
    ↓
Database Driver
    ↓
Connection Pool
    ↓
Database
    ↓
Query Execution
    ↓
Result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When an application is small, you can get away with treating that pipeline as a black box.&lt;/p&gt;

&lt;p&gt;When the application grows, you can't.&lt;/p&gt;

&lt;p&gt;A slow API might actually be a slow query.&lt;/p&gt;

&lt;p&gt;A database outage might actually be an exhausted connection pool.&lt;/p&gt;

&lt;p&gt;A scaling problem might actually be too many connections across multiple servers.&lt;/p&gt;

&lt;p&gt;And a seemingly harmless ORM operation might generate far more database work than you expected.&lt;/p&gt;

&lt;p&gt;That's why learning backend development isn't just about learning frameworks.&lt;/p&gt;

&lt;p&gt;It's about understanding &lt;strong&gt;what those frameworks are doing underneath the surface&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The best backend developers don't just know how to query a database. They understand what happens between the API request and the row coming back.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And once you understand that journey, the next question naturally follows:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How does the database itself find, organize, and protect all those rows?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That's where &lt;strong&gt;tables, relationships, primary keys, foreign keys, indexes, normalization, transactions, and database design&lt;/strong&gt; begin.&lt;/p&gt;

</description>
      <category>api</category>
      <category>backend</category>
      <category>database</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
