<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[WebDevLogs]]></title><description><![CDATA[WebDevLogs]]></description><link>https://webdevlogs.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Sun, 30 Aug 2026 21:49:02 GMT</lastBuildDate><atom:link href="https://webdevlogs.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[🧠 Redis in Backend System Design (Node.js Edition)]]></title><description><![CDATA[🔍 The Problem Redis Solves
Modern applications demand speed, scalability, and resilience. But databases like PostgreSQL or MongoDB are disk-based and not optimized for high-frequency access patterns, like:

Reading the same user profile 100,000 time...]]></description><link>https://webdevlogs.hashnode.dev/redis-in-backend-system-design-nodejs-edition</link><guid isPermaLink="true">https://webdevlogs.hashnode.dev/redis-in-backend-system-design-nodejs-edition</guid><dc:creator><![CDATA[Haider Ali]]></dc:creator><pubDate>Wed, 16 Jul 2025 10:04:25 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-the-problem-redis-solves">🔍 The Problem Redis Solves</h2>
<p>Modern applications demand <strong>speed</strong>, <strong>scalability</strong>, and <strong>resilience</strong>. But databases like <strong>PostgreSQL</strong> or <strong>MongoDB</strong> are <strong>disk-based</strong> and <strong>not optimized for high-frequency access patterns</strong>, like:</p>
<ul>
<li><p>Reading the same user profile 100,000 times a day</p>
</li>
<li><p>Throttling requests from millions of clients</p>
</li>
<li><p>Handling bursty job queues</p>
</li>
<li><p>Broadcasting chat messages in real-time</p>
</li>
</ul>
<p>Here’s where <strong>Redis</strong> fits in.</p>
<p>Redis is not a replacement for your database. It’s a <strong>performance-enhancing layer</strong>, sitting beside your DB and application, <strong>handling use-cases where memory, atomicity, and instant access matter</strong>.</p>
<hr />
<h2 id="heading-redis-as-a-strategic-component">🧱 Redis as a Strategic Component</h2>
<p>Let’s go use-case by use-case, and ask <strong>WHY Redis? WHEN Redis?</strong></p>
<hr />
<h3 id="heading-1-caching">1. ✅ Caching</h3>
<h4 id="heading-scenario">Scenario:</h4>
<p>You're building a product API. Each product page shows availability, price, rating, and stock — data stored in your SQL DB.</p>
<p>Now, 10,000 users hit the same product page. Do you want 10,000 DB calls?</p>
<h4 id="heading-why-redis">Why Redis:</h4>
<ul>
<li><p>Redis is <strong>in-memory</strong>, making reads <strong>orders of magnitude faster</strong> than disk.</p>
</li>
<li><p>You can <strong>cache the result</strong> for a product ID.</p>
</li>
<li><p>Redis supports <strong>TTL</strong>, meaning data can expire automatically.</p>
</li>
</ul>
<h4 id="heading-when-to-use">When to Use:</h4>
<ul>
<li><p>High-read, low-write objects (e.g., product catalogs, user profiles)</p>
</li>
<li><p>Expensive computations or joins</p>
</li>
<li><p>Search results, landing page content</p>
</li>
</ul>
<h4 id="heading-strategic-insight">Strategic Insight:</h4>
<p>Redis becomes your <strong>first responder</strong>; the DB is your <strong>source of truth</strong>.</p>
<hr />
<h3 id="heading-2-session-management">2. 🔐 Session Management</h3>
<h4 id="heading-scenario-1">Scenario:</h4>
<p>You’ve built an Express or NestJS-based authentication flow. Users log in, and a session or token must persist between requests.</p>
<h4 id="heading-why-redis-1">Why Redis:</h4>
<ul>
<li><p>Session data needs to be <strong>fast to access</strong> and <strong>shared across instances</strong> (in a multi-server setup).</p>
</li>
<li><p>Redis provides a <strong>central, fast key-value store</strong>.</p>
</li>
<li><p>Most session middlewares (like <code>express-session</code>) have a Redis adapter.</p>
</li>
</ul>
<h4 id="heading-when-to-use-1">When to Use:</h4>
<ul>
<li><p>Stateless authentication with short-lived tokens</p>
</li>
<li><p>Stateful session management (e.g., for internal tools)</p>
</li>
<li><p>Login-based SaaS apps with frequent auth lookups</p>
</li>
</ul>
<h4 id="heading-strategic-insight-1">Strategic Insight:</h4>
<p>Redis is <strong>shared state across nodes</strong> — your user’s login persists even if your server restarts or scales horizontally.</p>
<hr />
<h3 id="heading-3-api-rate-limiting">3. 📈 API Rate Limiting</h3>
<h4 id="heading-scenario-2">Scenario:</h4>
<p>Your public API is getting abused — some users send 1000 requests per second.</p>
<p>You want to <strong>throttle access</strong>: no more than 100 requests/minute per user.</p>
<h4 id="heading-why-redis-2">Why Redis:</h4>
<ul>
<li><p>Redis can <strong>atomically increment counters per key (per user)</strong>.</p>
</li>
<li><p>It supports <strong>expiring counters</strong>, which reset automatically after a time window.</p>
</li>
<li><p>It's blazing fast and <strong>can handle thousands of increments per second</strong>.</p>
</li>
</ul>
<h4 id="heading-when-to-use-2">When to Use:</h4>
<ul>
<li><p>Public-facing APIs</p>
</li>
<li><p>Login attempt limits (prevent brute force)</p>
</li>
<li><p>Per-user pricing tiers (basic vs premium)</p>
</li>
</ul>
<h4 id="heading-strategic-insight-2">Strategic Insight:</h4>
<p>This is <strong>infrastructure-level control</strong>. Without Redis or similar, your backend has no memory of per-user usage. Redis gives it a short-term memory.</p>
<hr />
<h3 id="heading-4-job-queues-amp-background-workers">4. 🎯 Job Queues &amp; Background Workers</h3>
<h4 id="heading-scenario-3">Scenario:</h4>
<p>You don’t want to send emails or process images during a user request. Instead, you want to offload those jobs.</p>
<h4 id="heading-why-redis-3">Why Redis:</h4>
<ul>
<li><p>Redis supports <strong>queues using Lists</strong> (<code>LPUSH</code>, <code>BRPOP</code>).</p>
</li>
<li><p>It’s extremely fast, reliable, and <strong>works well with background workers</strong> (e.g., Bull, Bee-Queue).</p>
</li>
<li><p>Many job queue libraries in Node.js are Redis-backed.</p>
</li>
</ul>
<h4 id="heading-when-to-use-3">When to Use:</h4>
<ul>
<li><p>Email notifications</p>
</li>
<li><p>Invoice generation</p>
</li>
<li><p>Image processing</p>
</li>
<li><p>Any async task where response time matters</p>
</li>
</ul>
<h4 id="heading-strategic-insight-3">Strategic Insight:</h4>
<p>Your API stays fast, your jobs run reliably — all because Redis acts as a <strong>message broker</strong> for decoupled execution.</p>
<hr />
<h3 id="heading-5-real-time-leaderboards">5. 🥇 Real-Time Leaderboards</h3>
<h4 id="heading-scenario-4">Scenario:</h4>
<p>You run a game or coding competition platform (like LeetCode). You need a leaderboard sorted by score, updated live.</p>
<h4 id="heading-why-redis-4">Why Redis:</h4>
<ul>
<li><p>Redis’s <strong>Sorted Sets</strong> (<code>ZADD</code>, <code>ZREVRANGE</code>) are perfect for ranking users by score.</p>
</li>
<li><p>You can <strong>increment a user’s score</strong> atomically.</p>
</li>
<li><p>You can <strong>query top-N</strong> in milliseconds.</p>
</li>
</ul>
<h4 id="heading-when-to-use-4">When to Use:</h4>
<ul>
<li><p>Gaming apps</p>
</li>
<li><p>Learning platforms (e.g., XP, levels)</p>
</li>
<li><p>Competitive platforms (speed, accuracy, score)</p>
</li>
</ul>
<h4 id="heading-strategic-insight-4">Strategic Insight:</h4>
<p>Databases can calculate rankings — but not fast enough to feel “live.” Redis gives <strong>live ranking at memory speed</strong>.</p>
<hr />
<h3 id="heading-6-real-time-pubsub">6. 📣 Real-Time Pub/Sub</h3>
<h4 id="heading-scenario-5">Scenario:</h4>
<p>You’re building a chat app, live notifications, or a system that needs <strong>event broadcasting</strong> (e.g., “User X commented on your post”).</p>
<h4 id="heading-why-redis-5">Why Redis:</h4>
<ul>
<li><p>Redis has <strong>native pub/sub</strong> channels.</p>
</li>
<li><p>Messages are instantly broadcast to all subscribed services.</p>
</li>
<li><p>Great for <strong>event propagation</strong> across microservices.</p>
</li>
</ul>
<h4 id="heading-when-to-use-5">When to Use:</h4>
<ul>
<li><p>Live chat</p>
</li>
<li><p>Notification systems</p>
</li>
<li><p>Microservice communication</p>
</li>
</ul>
<h4 id="heading-strategic-insight-5">Strategic Insight:</h4>
<p>You’re not just sending data — you’re building a <strong>reactive backend</strong>. Redis acts like your internal WebSocket server for service-to-service comms.</p>
<hr />
<h2 id="heading-when-not-to-use-redis">🧠 When NOT to Use Redis</h2>
<p>Redis is amazing, but <strong>not for everything</strong>:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Case</td><td>Avoid Redis When...</td></tr>
</thead>
<tbody>
<tr>
<td>Durable data</td><td>Redis is <strong>volatile by default</strong> (though AOF/RDB persistence helps). Use Postgres/MySQL/Mongo for critical records.</td></tr>
<tr>
<td>Huge datasets</td><td>Redis runs <strong>in-memory</strong>. Large datasets can <strong>exhaust RAM quickly</strong> and become expensive.</td></tr>
<tr>
<td>Complex querying</td><td>Redis doesn't support joins, aggregations, or advanced querying. Use traditional DBs for those.</td></tr>
</tbody>
</table>
</div><hr />
<h2 id="heading-production-considerations">🛡 Production Considerations</h2>
<p>If you’re serious about using Redis in production:</p>
<ul>
<li><p>✅ <strong>Enable persistence</strong> if you can't afford data loss</p>
</li>
<li><p>✅ Use <strong>Redis Sentinel</strong> for HA (failover)</p>
</li>
<li><p>✅ Use <strong>Redis Cluster</strong> for horizontal scaling</p>
</li>
<li><p>✅ Apply <strong>key naming conventions</strong> (e.g., <code>user:123:session</code>)</p>
</li>
<li><p>✅ Monitor memory usage — Redis is RAM-limited</p>
</li>
<li><p>✅ Use <strong>TTL</strong> wisely to avoid stale or bloated keys</p>
</li>
</ul>
<hr />
<h2 id="heading-redis-in-the-bigger-picture">🧩 Redis in the Bigger Picture</h2>
<p>In a <strong>Node.js microservices environment</strong>, Redis may sit at multiple architectural levels:</p>
<ul>
<li><p><strong>As a cache</strong> in front of your DB</p>
</li>
<li><p><strong>As a queue</strong> between your API and worker pool</p>
</li>
<li><p><strong>As a pub/sub layer</strong> between microservices</p>
</li>
<li><p><strong>As a session/token store</strong> between users and auth service</p>
</li>
<li><p><strong>As a coordination layer</strong> for distributed systems (e.g., locks)</p>
</li>
</ul>
<p>Redis isn’t just a cache. It's a <strong>multi-role utility</strong> that, when used wisely, can <strong>optimize performance, scalability, and responsiveness</strong> across your system.</p>
<hr />
<h2 id="heading-final-thoughts">🎓 Final Thoughts</h2>
<p>Using Redis well isn’t about knowing commands like <code>SET</code>, <code>GET</code>, or <code>LPUSH</code>. It’s about <strong>knowing where Redis makes architectural sense</strong> — where it helps you:</p>
<ul>
<li><p>Minimize latency</p>
</li>
<li><p>Maximize throughput</p>
</li>
<li><p>Offload compute</p>
</li>
<li><p>Decouple services</p>
</li>
</ul>
<p>Master Redis not just as a tool — but as a <strong>design pattern</strong> for building systems that scale.</p>
<hr />
<p>Perfect — let’s now dive into the <strong>Node.js + Redis</strong> code part, <strong>based on the real-world system design use cases</strong> we just discussed. These snippets are written in a clean, modular style, ideal for production backend apps (e.g., Express.js, NestJS, or any Node-based architecture).</p>
<hr />
<h1 id="heading-redis-in-nodejs-code-snippets-for-real-scenarios">🧩 Redis in Node.js: Code Snippets for Real Scenarios</h1>
<hr />
<h3 id="heading-1-redis-setup">✅ 1. Redis Setup</h3>
<pre><code class="lang-bash">npm install redis
</code></pre>
<pre><code class="lang-js"><span class="hljs-comment">// redisClient.js</span>
<span class="hljs-keyword">const</span> { createClient } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'redis'</span>);

<span class="hljs-keyword">const</span> redisClient = createClient({
  <span class="hljs-attr">url</span>: <span class="hljs-string">'redis://localhost:6379'</span>,
});

redisClient.on(<span class="hljs-string">'error'</span>, <span class="hljs-function">(<span class="hljs-params">err</span>) =&gt;</span> <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Redis error:'</span>, err));
redisClient.connect();

<span class="hljs-built_in">module</span>.exports = redisClient;
</code></pre>
<hr />
<h3 id="heading-2-caching-api-responses">⚡ 2. Caching API Responses</h3>
<pre><code class="lang-js"><span class="hljs-comment">// productService.js</span>
<span class="hljs-keyword">const</span> redis = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./redisClient'</span>);
<span class="hljs-keyword">const</span> db = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./fakeDB'</span>); <span class="hljs-comment">// assume DB function</span>

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getProduct</span>(<span class="hljs-params">productId</span>) </span>{
  <span class="hljs-keyword">const</span> cacheKey = <span class="hljs-string">`product:<span class="hljs-subst">${productId}</span>`</span>;
  <span class="hljs-keyword">const</span> cached = <span class="hljs-keyword">await</span> redis.get(cacheKey);

  <span class="hljs-keyword">if</span> (cached) {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">JSON</span>.parse(cached); <span class="hljs-comment">// cache hit</span>
  }

  <span class="hljs-keyword">const</span> product = <span class="hljs-keyword">await</span> db.getProductById(productId); <span class="hljs-comment">// cache miss</span>
  <span class="hljs-keyword">await</span> redis.setEx(cacheKey, <span class="hljs-number">3600</span>, <span class="hljs-built_in">JSON</span>.stringify(product)); <span class="hljs-comment">// cache for 1 hour</span>
  <span class="hljs-keyword">return</span> product;
}
</code></pre>
<hr />
<h3 id="heading-3-session-management-with-redis">🔐 3. Session Management with Redis</h3>
<pre><code class="lang-bash">npm install express-session connect-redis
</code></pre>
<pre><code class="lang-js"><span class="hljs-comment">// session.js</span>
<span class="hljs-keyword">const</span> session = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express-session'</span>);
<span class="hljs-keyword">const</span> RedisStore = <span class="hljs-built_in">require</span>(<span class="hljs-string">'connect-redis'</span>).default;
<span class="hljs-keyword">const</span> redisClient = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./redisClient'</span>);

<span class="hljs-keyword">const</span> store = <span class="hljs-keyword">new</span> RedisStore({ <span class="hljs-attr">client</span>: redisClient });

<span class="hljs-built_in">module</span>.exports = session({
  store,
  <span class="hljs-attr">secret</span>: <span class="hljs-string">'s3cr3t!'</span>,
  <span class="hljs-attr">resave</span>: <span class="hljs-literal">false</span>,
  <span class="hljs-attr">saveUninitialized</span>: <span class="hljs-literal">false</span>,
  <span class="hljs-attr">cookie</span>: { <span class="hljs-attr">maxAge</span>: <span class="hljs-number">1000</span> * <span class="hljs-number">60</span> * <span class="hljs-number">15</span> }, <span class="hljs-comment">// 15 minutes</span>
});
</code></pre>
<pre><code class="lang-js"><span class="hljs-comment">// app.js</span>
<span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>);
<span class="hljs-keyword">const</span> sessionMiddleware = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./session'</span>);

<span class="hljs-keyword">const</span> app = express();
app.use(sessionMiddleware);

app.get(<span class="hljs-string">'/'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  req.session.views = (req.session.views || <span class="hljs-number">0</span>) + <span class="hljs-number">1</span>;
  res.send(<span class="hljs-string">`Session views: <span class="hljs-subst">${req.session.views}</span>`</span>);
});
</code></pre>
<hr />
<h3 id="heading-4-rate-limiting-per-ip">🚦 4. Rate Limiting (Per IP)</h3>
<pre><code class="lang-js"><span class="hljs-comment">// rateLimiter.js</span>
<span class="hljs-keyword">const</span> redis = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./redisClient'</span>);

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">rateLimiter</span>(<span class="hljs-params">req, res, next</span>) </span>{
  <span class="hljs-keyword">const</span> ip = req.ip;
  <span class="hljs-keyword">const</span> key = <span class="hljs-string">`rate:<span class="hljs-subst">${ip}</span>`</span>;

  <span class="hljs-keyword">const</span> count = <span class="hljs-keyword">await</span> redis.incr(key);
  <span class="hljs-keyword">if</span> (count === <span class="hljs-number">1</span>) <span class="hljs-keyword">await</span> redis.expire(key, <span class="hljs-number">60</span>); <span class="hljs-comment">// 1 minute window</span>

  <span class="hljs-keyword">if</span> (count &gt; <span class="hljs-number">100</span>) {
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">429</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">'Rate limit exceeded'</span> });
  }

  next();
}

<span class="hljs-built_in">module</span>.exports = rateLimiter;
</code></pre>
<pre><code class="lang-js"><span class="hljs-comment">// app.js</span>
<span class="hljs-keyword">const</span> rateLimiter = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./rateLimiter'</span>);
app.use(rateLimiter);
</code></pre>
<hr />
<h3 id="heading-5-redis-queue-job-producerworker">📬 5. Redis Queue (Job Producer/Worker)</h3>
<h4 id="heading-producer-enqueue-job">Producer (enqueue job):</h4>
<pre><code class="lang-js"><span class="hljs-comment">// emailQueue.js</span>
<span class="hljs-keyword">const</span> redis = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./redisClient'</span>);

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">enqueueEmail</span>(<span class="hljs-params">to</span>) </span>{
  <span class="hljs-keyword">const</span> job = <span class="hljs-built_in">JSON</span>.stringify({ <span class="hljs-attr">task</span>: <span class="hljs-string">'sendEmail'</span>, to });
  <span class="hljs-keyword">await</span> redis.lPush(<span class="hljs-string">'emailQueue'</span>, job);
}
</code></pre>
<h4 id="heading-worker-process-job">Worker (process job):</h4>
<pre><code class="lang-js"><span class="hljs-comment">// worker.js</span>
<span class="hljs-keyword">const</span> redis = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./redisClient'</span>);

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">processQueue</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) {
    <span class="hljs-keyword">const</span> job = <span class="hljs-keyword">await</span> redis.brPop(<span class="hljs-string">'emailQueue'</span>, <span class="hljs-number">0</span>);
    <span class="hljs-keyword">const</span> data = <span class="hljs-built_in">JSON</span>.parse(job.element);
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Sending email to: <span class="hljs-subst">${data.to}</span>`</span>);
    <span class="hljs-comment">// simulate processing...</span>
  }
}

processQueue();
</code></pre>
<hr />
<h3 id="heading-6-leaderboard-with-sorted-sets">🥇 6. Leaderboard with Sorted Sets</h3>
<pre><code class="lang-js"><span class="hljs-comment">// leaderboard.js</span>
<span class="hljs-keyword">const</span> redis = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./redisClient'</span>);

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">updateScore</span>(<span class="hljs-params">userId, score</span>) </span>{
  <span class="hljs-keyword">await</span> redis.zIncrBy(<span class="hljs-string">'leaderboard'</span>, score, userId);
}

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getTopUsers</span>(<span class="hljs-params">limit = <span class="hljs-number">10</span></span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> redis.zRevRangeWithScores(<span class="hljs-string">'leaderboard'</span>, <span class="hljs-number">0</span>, limit - <span class="hljs-number">1</span>);
}
</code></pre>
<hr />
<h3 id="heading-7-pubsub-for-notifications-or-chat">📣 7. Pub/Sub for Notifications or Chat</h3>
<h4 id="heading-publisher">Publisher:</h4>
<pre><code class="lang-js"><span class="hljs-comment">// publisher.js</span>
<span class="hljs-keyword">const</span> redis = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./redisClient'</span>);

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sendNotification</span>(<span class="hljs-params">message</span>) </span>{
  <span class="hljs-keyword">await</span> redis.publish(<span class="hljs-string">'notifications'</span>, message);
}
</code></pre>
<h4 id="heading-subscriber">Subscriber:</h4>
<pre><code class="lang-js"><span class="hljs-comment">// subscriber.js</span>
<span class="hljs-keyword">const</span> { createClient } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'redis'</span>);
<span class="hljs-keyword">const</span> subscriber = createClient();
<span class="hljs-keyword">await</span> subscriber.connect();

<span class="hljs-keyword">await</span> subscriber.subscribe(<span class="hljs-string">'notifications'</span>, <span class="hljs-function">(<span class="hljs-params">msg</span>) =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Notification received:'</span>, msg);
});
</code></pre>
<hr />
<h2 id="heading-redis-testing-optional">🧪 Redis Testing (Optional)</h2>
<p>Try these manually with Redis CLI:</p>
<pre><code class="lang-bash">redis-cli
&gt; GET product:123
&gt; ZREVRANGE leaderboard 0 4 WITHSCORES
&gt; LLEN emailQueue
</code></pre>
<hr />
<h3 id="heading-best-practices-summary-in-code">📌 Best Practices Summary in Code</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Task</td><td>Redis Commands</td></tr>
</thead>
<tbody>
<tr>
<td>Caching</td><td><code>SETEX</code>, <code>GET</code></td></tr>
<tr>
<td>Session</td><td>via <code>connect-redis</code></td></tr>
<tr>
<td>Rate Limit</td><td><code>INCR</code>, <code>EXPIRE</code></td></tr>
<tr>
<td>Queue/Jobs</td><td><code>LPUSH</code>, <code>BRPOP</code></td></tr>
<tr>
<td>Leaderboard</td><td><code>ZINCRBY</code>, <code>ZREVRANGE</code></td></tr>
<tr>
<td>Pub/Sub</td><td><code>PUBLISH</code>, <code>SUBSCRIBE</code></td></tr>
</tbody>
</table>
</div><hr />
]]></content:encoded></item><item><title><![CDATA[🧠 System Architecture of LeetCode Backend – A Deep Dive]]></title><description><![CDATA[Great! Here's the enhanced version of the LeetCode Backend System Architecture Blog with:

📊 A detailed diagram of the architecture

💻 Code snippets to demonstrate real-world implementations


LeetCode powers millions of daily code submissions in d...]]></description><link>https://webdevlogs.hashnode.dev/system-architecture-of-leetcode-backend-a-deep-dive</link><guid isPermaLink="true">https://webdevlogs.hashnode.dev/system-architecture-of-leetcode-backend-a-deep-dive</guid><dc:creator><![CDATA[Haider Ali]]></dc:creator><pubDate>Wed, 16 Jul 2025 09:59:35 GMT</pubDate><content:encoded><![CDATA[<p>Great! Here's the enhanced version of the <strong>LeetCode Backend System Architecture Blog</strong> with:</p>
<ul>
<li><p>📊 A detailed <strong>diagram</strong> of the architecture</p>
</li>
<li><p>💻 <strong>Code snippets</strong> to demonstrate real-world implementations</p>
</li>
</ul>
<p>LeetCode powers millions of daily code submissions in dozens of languages, discussion forums, and a premium learning system. In this blog, we’ll explore how LeetCode likely structures its <strong>backend system</strong>, including:</p>
<ul>
<li><p>API Gateway</p>
</li>
<li><p>Microservices</p>
</li>
<li><p>Code Execution Engine</p>
</li>
<li><p>Security and Sandboxing</p>
</li>
<li><p>Caching &amp; Database</p>
</li>
<li><p>CI/CD and Scaling</p>
</li>
</ul>
<hr />
<h2 id="heading-1-high-level-architecture-diagram">🧭 <strong>1. High-Level Architecture Diagram</strong></h2>
<p><img src="https://i.imgur.com/C5UrnU5.png" alt="LeetCode Backend Architecture" /></p>
<p><em>(You can request a customized, editable diagram version too.)</em></p>
<hr />
<h2 id="heading-2-api-gateway-amp-load-balancer">🔁 <strong>2. API Gateway &amp; Load Balancer</strong></h2>
<pre><code class="lang-nginx"><span class="hljs-comment"># Sample NGINX config for routing API requests</span>
<span class="hljs-section">server</span> {
  <span class="hljs-attribute">listen</span> <span class="hljs-number">80</span>;
  <span class="hljs-attribute">server_name</span> leetcode.com;

  <span class="hljs-attribute">location</span> /api/ {
    <span class="hljs-attribute">proxy_pass</span> http://backend_services;
    <span class="hljs-attribute">proxy_set_header</span> Host <span class="hljs-variable">$host</span>;
    <span class="hljs-attribute">proxy_set_header</span> X-Real-IP <span class="hljs-variable">$remote_addr</span>;
  }
}
</code></pre>
<ul>
<li><p><strong>API Gateway</strong>: Nginx, Kong, or Envoy</p>
</li>
<li><p><strong>WAF/CDN</strong>: Cloudflare or AWS Shield</p>
</li>
</ul>
<hr />
<h2 id="heading-3-microservices-layer">🧩 <strong>3. Microservices Layer</strong></h2>
<p>Each service is typically containerized (Docker) and deployed via Kubernetes:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Dockerfile for Problem Service</span>
FROM node:18

WORKDIR /app
COPY . .

RUN npm install
CMD [<span class="hljs-string">"node"</span>, <span class="hljs-string">"server.js"</span>]
</code></pre>
<ul>
<li><p><strong>User Service</strong> → Auth, profiles</p>
</li>
<li><p><strong>Problem Service</strong> → Fetching question data</p>
</li>
<li><p><strong>Submission Service</strong> → Handling code submissions</p>
</li>
<li><p><strong>Leaderboard Service</strong> → Community &amp; ranking</p>
</li>
<li><p><strong>Subscription Service</strong> → Premium access</p>
</li>
</ul>
<hr />
<h2 id="heading-4-code-execution-engine">🧪 <strong>4. Code Execution Engine</strong></h2>
<h3 id="heading-secure-execution-flow">Secure Execution Flow:</h3>
<ol>
<li><p>User submits code.</p>
</li>
<li><p>Submission service places a job into the queue.</p>
</li>
<li><p>Worker pulls job, runs it in isolated environment.</p>
</li>
<li><p>Returns stdout, stderr, runtime.</p>
</li>
</ol>
<pre><code class="lang-python"><span class="hljs-comment"># Python worker consuming jobs (using Redis Queue)</span>
<span class="hljs-keyword">import</span> redis
<span class="hljs-keyword">import</span> docker

r = redis.Redis()
container_client = docker.from_env()

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">run_code</span>(<span class="hljs-params">code, lang</span>):</span>
    container = container_client.containers.run(
        image=<span class="hljs-string">f"leetcode-<span class="hljs-subst">{lang}</span>"</span>,
        command=[<span class="hljs-string">"/bin/sh"</span>, <span class="hljs-string">"-c"</span>, <span class="hljs-string">f"echo \"<span class="hljs-subst">{code}</span>\" | python3"</span>],
        detach=<span class="hljs-literal">True</span>,
        mem_limit=<span class="hljs-string">"128m"</span>,
        network_disabled=<span class="hljs-literal">True</span>,
        stdin_open=<span class="hljs-literal">True</span>
    )
    result = container.logs()
    container.remove()
    <span class="hljs-keyword">return</span> result
</code></pre>
<ul>
<li><p><strong>Sandbox Tools</strong>: Docker + seccomp / AppArmor</p>
</li>
<li><p><strong>Alternative</strong>: Firecracker VM for better isolation</p>
</li>
</ul>
<hr />
<h2 id="heading-5-job-queue-amp-async-processing">📬 <strong>5. Job Queue &amp; Async Processing</strong></h2>
<p>LeetCode must offload execution to keep the frontend responsive.</p>
<pre><code class="lang-js"><span class="hljs-comment">// Node.js submission handler (simplified)</span>
app.post(<span class="hljs-string">"/submit"</span>, <span class="hljs-keyword">async</span> (req, res) =&gt; {
  <span class="hljs-keyword">const</span> { code, lang, problemId } = req.body;
  <span class="hljs-keyword">await</span> redis.lpush(<span class="hljs-string">"execution_queue"</span>, <span class="hljs-built_in">JSON</span>.stringify({ code, lang, problemId }));
  res.json({ <span class="hljs-attr">status</span>: <span class="hljs-string">"queued"</span> });
});
</code></pre>
<ul>
<li><p><strong>Queue tools</strong>: Redis Queue, RabbitMQ, Kafka</p>
</li>
<li><p><strong>Worker autoscaling</strong>: Based on queue length (via Kubernetes HPA)</p>
</li>
</ul>
<hr />
<h2 id="heading-6-database-design">🗃️ <strong>6. Database Design</strong></h2>
<h3 id="heading-user-table">User Table</h3>
<pre><code class="lang-sql"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> <span class="hljs-keyword">users</span> (
  <span class="hljs-keyword">id</span> <span class="hljs-built_in">SERIAL</span> PRIMARY <span class="hljs-keyword">KEY</span>,
  username <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">50</span>) <span class="hljs-keyword">UNIQUE</span> <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
  email <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">100</span>) <span class="hljs-keyword">UNIQUE</span>,
  premium <span class="hljs-built_in">BOOLEAN</span> <span class="hljs-keyword">DEFAULT</span> <span class="hljs-literal">false</span>
);
</code></pre>
<h3 id="heading-submission-table">Submission Table</h3>
<pre><code class="lang-sql"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> submissions (
  <span class="hljs-keyword">id</span> <span class="hljs-built_in">SERIAL</span> PRIMARY <span class="hljs-keyword">KEY</span>,
  user_id <span class="hljs-built_in">INT</span> <span class="hljs-keyword">REFERENCES</span> <span class="hljs-keyword">users</span>(<span class="hljs-keyword">id</span>),
  problem_id <span class="hljs-built_in">INT</span>,
  <span class="hljs-keyword">language</span> <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">20</span>),
  code <span class="hljs-built_in">TEXT</span>,
  <span class="hljs-keyword">result</span> JSONB,
  submitted_at <span class="hljs-built_in">TIMESTAMP</span> <span class="hljs-keyword">DEFAULT</span> <span class="hljs-keyword">NOW</span>()
);
</code></pre>
<ul>
<li><p><strong>Relational DB</strong>: PostgreSQL / MySQL</p>
</li>
<li><p><strong>NoSQL</strong>: MongoDB for discussions</p>
</li>
<li><p><strong>Redis</strong>: Session cache, hot problem cache</p>
</li>
</ul>
<hr />
<h2 id="heading-7-authentication-amp-security">🛡️ <strong>7. Authentication &amp; Security</strong></h2>
<p>LeetCode supports session tokens and OAuth login.</p>
<pre><code class="lang-js"><span class="hljs-comment">// JWT-based authentication (Node.js)</span>
<span class="hljs-keyword">const</span> jwt = <span class="hljs-built_in">require</span>(<span class="hljs-string">'jsonwebtoken'</span>);

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">authenticate</span>(<span class="hljs-params">req, res, next</span>) </span>{
  <span class="hljs-keyword">const</span> token = req.headers.authorization?.split(<span class="hljs-string">" "</span>)[<span class="hljs-number">1</span>];
  <span class="hljs-keyword">if</span> (!token) <span class="hljs-keyword">return</span> res.sendStatus(<span class="hljs-number">401</span>);
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> user = jwt.verify(token, process.env.JWT_SECRET);
    req.user = user;
    next();
  } <span class="hljs-keyword">catch</span> {
    res.sendStatus(<span class="hljs-number">403</span>);
  }
}
</code></pre>
<ul>
<li><p><strong>OAuth2</strong>: GitHub, Google</p>
</li>
<li><p><strong>Rate limiting</strong>: Login attempts, brute-force prevention</p>
</li>
<li><p><strong>API keys</strong> for internal runner services</p>
</li>
</ul>
<hr />
<h2 id="heading-8-monitoring-amp-logging">🔍 <strong>8. Monitoring &amp; Logging</strong></h2>
<pre><code class="lang-yaml"><span class="hljs-comment"># Prometheus config example for metrics scraping</span>
<span class="hljs-attr">scrape_configs:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">job_name:</span> <span class="hljs-string">'leetcode-backend'</span>
    <span class="hljs-attr">static_configs:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">targets:</span> [<span class="hljs-string">'backend-service:3000'</span>]
</code></pre>
<ul>
<li><p><strong>Logging</strong>: ELK Stack or Loki</p>
</li>
<li><p><strong>Metrics</strong>: Prometheus + Grafana</p>
</li>
<li><p><strong>Tracing</strong>: OpenTelemetry or Jaeger</p>
</li>
</ul>
<hr />
<h2 id="heading-9-cicd-amp-deployment">🚀 <strong>9. CI/CD &amp; Deployment</strong></h2>
<pre><code class="lang-yaml"><span class="hljs-comment"># GitHub Actions – CI for Node backend</span>
<span class="hljs-attr">name:</span> <span class="hljs-string">Deploy</span> <span class="hljs-string">Backend</span>

<span class="hljs-attr">on:</span>
  <span class="hljs-attr">push:</span>
    <span class="hljs-attr">branches:</span> [<span class="hljs-string">main</span>]

<span class="hljs-attr">jobs:</span>
  <span class="hljs-attr">build:</span>
    <span class="hljs-attr">runs-on:</span> <span class="hljs-string">ubuntu-latest</span>
    <span class="hljs-attr">steps:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/checkout@v2</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">run:</span> <span class="hljs-string">npm</span> <span class="hljs-string">install</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">run:</span> <span class="hljs-string">npm</span> <span class="hljs-string">test</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">run:</span> <span class="hljs-string">docker</span> <span class="hljs-string">build</span> <span class="hljs-string">-t</span> <span class="hljs-string">leetcode-backend</span> <span class="hljs-string">.</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">run:</span> <span class="hljs-string">docker</span> <span class="hljs-string">push</span> <span class="hljs-string">my-registry/leetcode-backend</span>
</code></pre>
<ul>
<li><p><strong>CI Tools</strong>: GitHub Actions, Jenkins, GitLab CI</p>
</li>
<li><p><strong>CD</strong>: ArgoCD, Spinnaker</p>
</li>
<li><p><strong>K8s Deployments</strong>: Blue-green or canary rollouts</p>
</li>
</ul>
<hr />
<h2 id="heading-10-scalability-best-practices">📈 <strong>10. Scalability Best Practices</strong></h2>
<ul>
<li><p>Use <strong>HPA (Horizontal Pod Autoscaler)</strong> in Kubernetes</p>
</li>
<li><p>Keep <strong>submission runner stateless</strong></p>
</li>
<li><p>Cache hot problems at edge/CDN</p>
</li>
<li><p>Batch slow analytics jobs offline</p>
</li>
</ul>
<hr />
<h2 id="heading-conclusion">🧵 <strong>Conclusion</strong></h2>
<p>LeetCode’s architecture is a blend of:</p>
<ul>
<li><p><strong>Containerization (Docker/Kubernetes)</strong></p>
</li>
<li><p><strong>Microservices</strong> for scalability</p>
</li>
<li><p><strong>Secure Sandboxing</strong> for code execution</p>
</li>
<li><p><strong>Asynchronous job handling</strong></p>
</li>
<li><p><strong>Robust observability and deployment pipelines</strong></p>
</li>
</ul>
<p>Whether you're building a coding platform, an online judge, or just curious about complex distributed systems, the LeetCode backend provides a stellar blueprint.</p>
<hr />
]]></content:encoded></item><item><title><![CDATA[🚦React Router Deep Dive: Build Modern, Navigable SPAs with Ease]]></title><description><![CDATA[When building modern Single Page Applications (SPAs), client-side routing becomes essential. React, being a library for building user interfaces, doesn't include routing out of the box. That’s where React Router comes in — a powerful library that all...]]></description><link>https://webdevlogs.hashnode.dev/react-router-deep-dive-build-modern-navigable-spas-with-ease</link><guid isPermaLink="true">https://webdevlogs.hashnode.dev/react-router-deep-dive-build-modern-navigable-spas-with-ease</guid><dc:creator><![CDATA[Haider Ali]]></dc:creator><pubDate>Mon, 21 Apr 2025 16:41:23 GMT</pubDate><content:encoded><![CDATA[<p>When building modern Single Page Applications (SPAs), <strong>client-side routing</strong> becomes essential. React, being a library for building user interfaces, doesn't include routing out of the box. That’s where <strong>React Router</strong> comes in — a powerful library that allows dynamic routing in React apps.</p>
<p>In this post, we’ll explore React Router (v6+), understand how it works, and build a sample navigable app with practical examples.</p>
<hr />
<h2 id="heading-what-is-react-router">📦 What is React Router?</h2>
<p>React Router is a standard library for routing in React. It enables navigation among views of various components, allows changing the browser URL, and keeps the UI in sync with the URL.</p>
<h3 id="heading-key-features">✨ Key Features:</h3>
<ul>
<li><p>Nested Routing</p>
</li>
<li><p>Dynamic Routing</p>
</li>
<li><p>Route Parameters</p>
</li>
<li><p>Lazy Loading</p>
</li>
<li><p>Navigation Programmatically</p>
</li>
<li><p>Not Found Pages (404)</p>
</li>
<li><p>Route Protection</p>
</li>
</ul>
<hr />
<h2 id="heading-installation">🔧 Installation</h2>
<p>Before diving in, install React Router in your React project:</p>
<pre><code class="lang-bash">npm install react-router-dom
</code></pre>
<p>Or with yarn:</p>
<pre><code class="lang-bash">yarn add react-router-dom
</code></pre>
<hr />
<h2 id="heading-basic-routing-example">🧭 Basic Routing Example</h2>
<p>Let’s start with a simple setup using <code>BrowserRouter</code>, <code>Routes</code>, and <code>Route</code>.</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// App.jsx</span>
<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> { BrowserRouter, Routes, Route, Link } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-router-dom'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Home</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>🏠 Home Page<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span>;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">About</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>ℹ️ About Page<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span>;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Contact</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>📞 Contact Page<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span>;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">BrowserRouter</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">nav</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">display:</span> '<span class="hljs-attr">flex</span>', <span class="hljs-attr">gap:</span> '<span class="hljs-attr">1rem</span>' }}&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Link</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"/"</span>&gt;</span>Home<span class="hljs-tag">&lt;/<span class="hljs-name">Link</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Link</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"/about"</span>&gt;</span>About<span class="hljs-tag">&lt;/<span class="hljs-name">Link</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Link</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"/contact"</span>&gt;</span>Contact<span class="hljs-tag">&lt;/<span class="hljs-name">Link</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">nav</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">Routes</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">Home</span> /&gt;</span>} /&gt;
        <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/about"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">About</span> /&gt;</span>} /&gt;
        <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/contact"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">Contact</span> /&gt;</span>} /&gt;
      <span class="hljs-tag">&lt;/<span class="hljs-name">Routes</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">BrowserRouter</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p><strong>Explanation:</strong></p>
<ul>
<li><p><code>BrowserRouter</code>: Wraps your app and enables routing.</p>
</li>
<li><p><code>Link</code>: Used instead of <code>&lt;a&gt;</code> to avoid full-page reloads.</p>
</li>
<li><p><code>Routes</code> &amp; <code>Route</code>: Define the component to render based on the URL.</p>
</li>
</ul>
<hr />
<h2 id="heading-nested-routes">🔁 Nested Routes</h2>
<p>React Router makes nesting routes easy.</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// Dashboard.jsx</span>
<span class="hljs-keyword">import</span> { Outlet, Link } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-router-dom'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Dashboard</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>📊 Dashboard<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">nav</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Link</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"profile"</span>&gt;</span>Profile<span class="hljs-tag">&lt;/<span class="hljs-name">Link</span>&gt;</span> | <span class="hljs-tag">&lt;<span class="hljs-name">Link</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"settings"</span>&gt;</span>Settings<span class="hljs-tag">&lt;/<span class="hljs-name">Link</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">nav</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Outlet</span> /&gt;</span> {/* Child components render here */}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}

<span class="hljs-comment">// Inside App.jsx</span>
&lt;Route path=<span class="hljs-string">"/dashboard"</span> element={<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Dashboard</span> /&gt;</span></span>}&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"profile"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">div</span>&gt;</span>👤 Profile<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>} /&gt;</span>
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"settings"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">div</span>&gt;</span>⚙️ Settings<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>} /&gt;</span>
&lt;/Route&gt;
</code></pre>
<hr />
<h2 id="heading-route-parameters">🧩 Route Parameters</h2>
<p>You can pass parameters via the URL to create dynamic routes.</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// User.jsx</span>
<span class="hljs-keyword">import</span> { useParams } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-router-dom'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">User</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> { userId } = useParams();
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>User ID: {userId}<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span></span>;
}

<span class="hljs-comment">// Inside App.jsx</span>
&lt;Route path=<span class="hljs-string">"/user/:userId"</span> element={<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">User</span> /&gt;</span></span>} /&gt;
</code></pre>
<p>Visit <code>/user/123</code> and you'll see: <strong>User ID: 123</strong></p>
<hr />
<h2 id="heading-redirects-and-navigation">⏩ Redirects and Navigation</h2>
<p>Use <code>useNavigate()</code> to navigate programmatically.</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// Login.jsx</span>
<span class="hljs-keyword">import</span> { useNavigate } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-router-dom'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Login</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> navigate = useNavigate();

  <span class="hljs-keyword">const</span> handleLogin = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">// Assume login success</span>
    navigate(<span class="hljs-string">'/dashboard'</span>);
  };

  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleLogin}</span>&gt;</span>Login<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>;
}
</code></pre>
<hr />
<h2 id="heading-404-not-found-page">🛑 404 Not Found Page</h2>
<p>You can catch all unmatched routes:</p>
<pre><code class="lang-jsx">&lt;Route path=<span class="hljs-string">"*"</span> element={<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>404 Page Not Found 🚫<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span>} /&gt;
</code></pre>
<hr />
<h2 id="heading-protected-routes">🔐 Protected Routes</h2>
<p>For authentication-based routing:</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// ProtectedRoute.jsx</span>
<span class="hljs-keyword">import</span> { Navigate } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-router-dom'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ProtectedRoute</span>(<span class="hljs-params">{ isAuthenticated, children }</span>) </span>{
  <span class="hljs-keyword">return</span> isAuthenticated ? children : <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Navigate</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"/login"</span> /&gt;</span></span>;
}

<span class="hljs-comment">// Inside App.jsx</span>
&lt;Route path=<span class="hljs-string">"/admin"</span> element={
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ProtectedRoute</span> <span class="hljs-attr">isAuthenticated</span>=<span class="hljs-string">{loggedIn}</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">AdminPanel</span> /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">ProtectedRoute</span>&gt;</span></span>
} /&gt;
</code></pre>
<hr />
<h2 id="heading-lazy-loading-routes">🧠 Lazy Loading Routes</h2>
<p>Improve performance by loading components on demand.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { lazy, Suspense } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">const</span> LazyAbout = lazy(<span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">import</span>(<span class="hljs-string">'./About'</span>));

<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Route</span>
  <span class="hljs-attr">path</span>=<span class="hljs-string">"/about"</span>
  <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>
    &lt;<span class="hljs-attr">Suspense</span> <span class="hljs-attr">fallback</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">div</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>}&gt;
      <span class="hljs-tag">&lt;<span class="hljs-name">LazyAbout</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Suspense</span>&gt;</span>
  }
/&gt;</span>
</code></pre>
<hr />
<h2 id="heading-final-project-structure">🧪 Final Project Structure</h2>
<pre><code class="lang-markdown">src/
├── App.jsx
├── index.js
├── components/
│   └── ProtectedRoute.jsx
├── pages/
│   ├── Home.jsx
│   ├── About.jsx
│   ├── Contact.jsx
│   ├── Dashboard.jsx
│   ├── Login.jsx
│   └── User.jsx
</code></pre>
<hr />
<h2 id="heading-summary">✅ Summary</h2>
<p>React Router is an essential library for React developers building modern SPAs. Here's a recap:</p>
<ul>
<li><p>Use <code>BrowserRouter</code> to wrap your app.</p>
</li>
<li><p>Define navigation with <code>Link</code>.</p>
</li>
<li><p>Organize views with <code>Routes</code> and <code>Route</code>.</p>
</li>
<li><p>Create dynamic URLs with parameters.</p>
</li>
<li><p>Use <code>useNavigate()</code> for programmatic redirects.</p>
</li>
<li><p>Protect routes using conditional rendering.</p>
</li>
<li><p>Optimize with lazy loading.</p>
</li>
</ul>
<hr />
<h2 id="heading-pro-tips">💡 Pro Tips</h2>
<ul>
<li><p>Always keep your routes in sync with your component structure.</p>
</li>
<li><p>Use <code>useLocation()</code> for conditional UI based on route.</p>
</li>
<li><p>Prefer <code>Outlet</code> for nested routes to keep components clean.</p>
</li>
</ul>
<hr />
<h2 id="heading-try-this">🎯 Try This!</h2>
<p><strong>Mini challenge:</strong> Create a mini blog app with:</p>
<ul>
<li><p>Home</p>
</li>
<li><p>Blog list (<code>/blogs</code>)</p>
</li>
<li><p>Individual blog post (<code>/blogs/:id</code>)</p>
</li>
<li><p>Protected "New Post" page that only shows when <code>isLoggedIn === true</code></p>
</li>
</ul>
<hr />
]]></content:encoded></item><item><title><![CDATA[⚔️ Server vs Client Components: The In-Depth Guide (With Fun Examples)]]></title><description><![CDATA[React's evolution with Server Components and frameworks like Next.js 13+ has introduced a new superpower for developers: splitting UI logic between server and client.
But what does this mean for your app—and why does it matter?
Let’s go deep.

🧠 The...]]></description><link>https://webdevlogs.hashnode.dev/server-vs-client-components-the-in-depth-guide-with-fun-examples</link><guid isPermaLink="true">https://webdevlogs.hashnode.dev/server-vs-client-components-the-in-depth-guide-with-fun-examples</guid><category><![CDATA[React]]></category><category><![CDATA[Next.js]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[components]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Client-side rendering]]></category><category><![CDATA[Server side rendering]]></category><dc:creator><![CDATA[Haider Ali]]></dc:creator><pubDate>Sat, 19 Apr 2025 13:36:55 GMT</pubDate><content:encoded><![CDATA[<p>React's evolution with <strong>Server Components</strong> and frameworks like <strong>Next.js 13+</strong> has introduced a new superpower for developers: splitting UI logic between <strong>server and client</strong>.</p>
<p>But what does this mean for your app—and why does it matter?</p>
<p>Let’s go deep.</p>
<hr />
<h2 id="heading-the-core-idea">🧠 The Core Idea</h2>
<p>Traditionally, all React components were <strong>Client Components</strong>—they rendered in the browser. But now we can offload rendering logic to the <strong>server</strong>, send only HTML to the client, and save on JS bundle size. This is the magic of <strong>Server Components</strong>.</p>
<p>The result?<br />⚡ Faster apps<br />🔒 More secure data fetching<br />📦 Smaller client-side bundles<br />📈 Better SEO</p>
<hr />
<h2 id="heading-what-are-server-components">🎯 What Are Server Components?</h2>
<p><strong>Server Components</strong> render on the server during the request. They never touch the browser. They output <strong>HTML only</strong>.</p>
<h3 id="heading-capabilities">✅ Capabilities:</h3>
<ul>
<li><p>Fetch data directly (even from a database)</p>
</li>
<li><p>Never shipped to the browser</p>
</li>
<li><p>Great for performance and SEO</p>
</li>
<li><p>Can import other Server or Client components</p>
</li>
</ul>
<h3 id="heading-limitations">❌ Limitations:</h3>
<ul>
<li><p>No <code>useState</code>, <code>useEffect</code>, <code>useRef</code>, etc.</p>
</li>
<li><p>No access to <code>window</code>, <code>document</code>, or browser APIs</p>
</li>
<li><p>Cannot respond to client events like clicks</p>
</li>
</ul>
<h3 id="heading-example">🛠️ Example:</h3>
<pre><code class="lang-jsx"><span class="hljs-comment">// app/posts/[id]/page.jsx</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Post</span>(<span class="hljs-params">{ params }</span>) </span>{
  <span class="hljs-keyword">const</span> post = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">`https://api/posts/<span class="hljs-subst">${params.id}</span>`</span>).then(<span class="hljs-function"><span class="hljs-params">res</span> =&gt;</span> res.json())
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">article</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>{post.title}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{post.content}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">article</span>&gt;</span></span>
}
</code></pre>
<hr />
<h2 id="heading-what-are-client-components">🧩 What Are Client Components?</h2>
<p><strong>Client Components</strong> are rendered in the browser. They're interactive and dynamic.</p>
<h3 id="heading-capabilities-1">✅ Capabilities:</h3>
<ul>
<li><p>Use React hooks (<code>useState</code>, <code>useEffect</code>, etc.)</p>
</li>
<li><p>Handle user interactions</p>
</li>
<li><p>Access browser APIs (e.g., <code>localStorage</code>, <code>navigator</code>)</p>
</li>
</ul>
<h3 id="heading-limitations-1">❌ Limitations:</h3>
<ul>
<li><p>Need to be hydrated in the browser</p>
</li>
<li><p>Increase JS bundle size</p>
</li>
<li><p>Cannot directly fetch secure server-only data (without exposing it)</p>
</li>
</ul>
<h3 id="heading-example-1">🔥 Example:</h3>
<pre><code class="lang-jsx"><span class="hljs-string">'use client'</span>

<span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ThemeToggle</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [dark, setDark] = useState(<span class="hljs-literal">false</span>)
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> setDark(!dark)}&gt;
    {dark ? '🌙 Dark Mode' : '☀️ Light Mode'}
  <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
}
</code></pre>
<hr />
<h2 id="heading-real-world-usage-pattern">🎢 Real World Usage Pattern</h2>
<p>Most modern pages benefit from <strong>a mix of both</strong>. Server for content. Client for controls.</p>
<h3 id="heading-a-blog-page-might-use">📄 A Blog Page Might Use:</h3>
<ul>
<li><p><code>PostContent</code> → Server Component (fetches blog data)</p>
</li>
<li><p><code>LikeButton</code> → Client Component (handles user interaction)</p>
</li>
<li><p><code>CommentForm</code> → Client Component (interactive form)</p>
</li>
</ul>
<p>You <strong>compose them together</strong> like this:</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// Server Component</span>
<span class="hljs-keyword">import</span> PostContent <span class="hljs-keyword">from</span> <span class="hljs-string">'./PostContent'</span>
<span class="hljs-keyword">import</span> LikeButton <span class="hljs-keyword">from</span> <span class="hljs-string">'./LikeButton'</span> <span class="hljs-comment">// this is a client component</span>

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">BlogPost</span>(<span class="hljs-params">{ id }</span>) </span>{
  <span class="hljs-keyword">const</span> post = <span class="hljs-keyword">await</span> getPostData(id)

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">PostContent</span> <span class="hljs-attr">post</span>=<span class="hljs-string">{post}</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">LikeButton</span> <span class="hljs-attr">postId</span>=<span class="hljs-string">{id}</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  )
}
</code></pre>
<hr />
<h2 id="heading-technical-behind-the-scenes">🧪 Technical Behind-the-Scenes</h2>
<p>Here’s what really happens when you load a page:</p>
<ol>
<li><p><strong>Server Component</strong> renders HTML on the server and sends it to the browser.</p>
</li>
<li><p>If it includes <strong>Client Components</strong>, those components are <strong>hydrated</strong> (JavaScript is loaded to make them interactive).</p>
</li>
<li><p>The rest of the page stays static and fast.</p>
</li>
</ol>
<p>This architecture allows <strong>partial hydration</strong> — only interactive parts load JavaScript, saving time and resources.</p>
<hr />
<h2 id="heading-performance-benefits">📈 Performance Benefits</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Feature</td><td>Server Component</td><td>Client Component</td></tr>
</thead>
<tbody>
<tr>
<td>JavaScript bundle size</td><td>🔽 Smaller</td><td>🔼 Larger</td></tr>
<tr>
<td>Time to first byte (TTFB)</td><td>⚡ Faster</td><td>🐢 Slower</td></tr>
<tr>
<td>SEO</td><td>✅ Excellent</td><td>❌ Requires SSR or static</td></tr>
<tr>
<td>Access to React hooks</td><td>❌ No</td><td>✅ Yes</td></tr>
<tr>
<td>Access to browser APIs</td><td>❌ No</td><td>✅ Yes</td></tr>
</tbody>
</table>
</div><hr />
<h2 id="heading-design-philosophy-server-first">🧠 Design Philosophy: Server-First</h2>
<blockquote>
<p><strong>Use Server Components by default. Opt into Client Components only when needed.</strong></p>
</blockquote>
<p>This results in:</p>
<ul>
<li><p>Faster loading apps</p>
</li>
<li><p>Smaller bundles</p>
</li>
<li><p>More maintainable architecture</p>
</li>
</ul>
<hr />
<h2 id="heading-when-should-you-use-each">🎯 When Should You Use Each?</h2>
<h3 id="heading-use-server-components-for">🔧 Use Server Components for:</h3>
<ul>
<li><p>Static content (blogs, product pages, dashboards)</p>
</li>
<li><p>Data fetching (API, database, etc.)</p>
</li>
<li><p>SEO-critical pages</p>
</li>
<li><p>Markdown rendering</p>
</li>
<li><p>Reusable layout shells</p>
</li>
</ul>
<h3 id="heading-use-client-components-for">⚙️ Use Client Components for:</h3>
<ul>
<li><p>Buttons, sliders, dropdowns</p>
</li>
<li><p>Forms and inputs</p>
</li>
<li><p>Dynamic filters</p>
</li>
<li><p>Toasts, modals, UI animations</p>
</li>
<li><p>Theme toggles or localStorage logic</p>
</li>
</ul>
<hr />
<h2 id="heading-best-practices">🚀 Best Practices</h2>
<p>✅ Use <code>use client</code> only when necessary<br />✅ Keep Client Components small and focused<br />✅ Server-render as much as possible<br />✅ Compose Server + Client together for hybrid UIs<br />✅ Think of hydration cost: avoid wrapping everything in a Client Component</p>
<hr />
<h2 id="heading-final-analogy">🎁 Final Analogy</h2>
<blockquote>
<p>🍕 Server Components are like pre-baked pizzas delivered hot.<br />🧂 Client Components are the toppings you add yourself.</p>
</blockquote>
<p>Mix them wisely for the tastiest experience 🍽️</p>
<hr />
<h2 id="heading-tldr">🧵 TL;DR</h2>
<ul>
<li><p>Server Components: render once, ship fast, no interactivity.</p>
</li>
<li><p>Client Components: render in-browser, interactive, heavier.</p>
</li>
<li><p>Combine both for the best of performance and UX.</p>
</li>
<li><p>Default to Server → sprinkle in Client where needed.</p>
</li>
</ul>
]]></content:encoded></item></channel></rss>