<?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>Forem: Sibasish Mohanty</title>
    <description>The latest articles on Forem by Sibasish Mohanty (@sibasishm).</description>
    <link>https://forem.com/sibasishm</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F601069%2F34116366-bb46-4d16-b7e5-c22042f2d043.jpeg</url>
      <title>Forem: Sibasish Mohanty</title>
      <link>https://forem.com/sibasishm</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/sibasishm"/>
    <language>en</language>
    <item>
      <title>Real-Time Systems: Making Data Flow Live</title>
      <dc:creator>Sibasish Mohanty</dc:creator>
      <pubDate>Mon, 15 Sep 2025 07:51:38 +0000</pubDate>
      <link>https://forem.com/sibasishm/real-time-systems-making-data-flow-live-37m9</link>
      <guid>https://forem.com/sibasishm/real-time-systems-making-data-flow-live-37m9</guid>
      <description>&lt;p&gt;In the final part of our System Design series, we’re focusing on how to deliver real-time data effectively, balancing complexity, latency, and reliability.&lt;/p&gt;

&lt;p&gt;We’ll cover:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Serialization – JSON, Avro, Proto&lt;/li&gt;
&lt;li&gt;Real-Time Delivery – Polling, SSE, WebSockets&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. Serialization
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Choose the right format to balance speed, size, and compatibility.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;JSON:&lt;/strong&gt; Easy to debug, human-readable, but large and slow to parse.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avro:&lt;/strong&gt; Compact, schema evolution support, good for Kafka.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Protobuf:&lt;/strong&gt; Highly efficient, strict schema, widely used in gRPC.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Example:&lt;/strong&gt; Use Protobuf for high-throughput internal RPC between microservices, JSON for external APIs.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Interview tie-in:&lt;/strong&gt; &lt;em&gt;"Why not use JSON everywhere?"&lt;/em&gt; — Size and parsing speed trade-offs.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Real-Time Delivery
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Choose the right mechanism based on use case and scale.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Polling:&lt;/strong&gt; Simple but inefficient; periodic client requests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Server-Sent Events (SSE):&lt;/strong&gt; Server pushes updates over HTTP, uni-directional.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WebSockets:&lt;/strong&gt; Full-duplex communication, ideal for bidirectional interaction.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Example:&lt;/strong&gt; Stock trading platform uses WebSockets for real-time price updates. Simple dashboards use SSE for infrequent updates.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Interview tie-in:&lt;/strong&gt; &lt;em&gt;"When would you use SSE over WebSockets?"&lt;/em&gt; — SSE for simple streaming, WebSockets for interactive apps.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Pick &lt;strong&gt;serialization format&lt;/strong&gt; based on throughput, compatibility, and schema evolution.&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;polling only if absolutely necessary&lt;/strong&gt;; prefer SSE or WebSockets for real-time.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;💡 &lt;strong&gt;Practice Question:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;"Design a live sports score app that supports thousands of concurrent users. How do you handle real-time updates efficiently and ensure message order?"&lt;/p&gt;

</description>
      <category>json</category>
      <category>systemdesign</category>
      <category>microservices</category>
      <category>eventdriven</category>
    </item>
    <item>
      <title>From Deployment to Architecture: Designing for Change and Scale</title>
      <dc:creator>Sibasish Mohanty</dc:creator>
      <pubDate>Mon, 15 Sep 2025 07:48:09 +0000</pubDate>
      <link>https://forem.com/sibasishm/from-deployment-to-architecture-designing-for-change-and-scale-1lo3</link>
      <guid>https://forem.com/sibasishm/from-deployment-to-architecture-designing-for-change-and-scale-1lo3</guid>
      <description>&lt;p&gt;In part 8 of our System Design series, we’ll explore the practices and patterns that help systems evolve, stay resilient, and simplify operations over time.&lt;/p&gt;

&lt;p&gt;We’ll cover:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Service Discovery – Dynamic endpoints, central config&lt;/li&gt;
&lt;li&gt;Deployment Strategies – Canary, blue/green, rollbacks&lt;/li&gt;
&lt;li&gt;Monolith vs Microservices – Split only if ops cost justified&lt;/li&gt;
&lt;li&gt;Distributed Transactions – Use sagas, avoid 2PC&lt;/li&gt;
&lt;li&gt;Event Sourcing &amp;amp; CQRS – Append-only logs, splitting models&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. Service Discovery
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Don’t hardcode service endpoints; let services find each other dynamically.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Central Registry (e.g., Consul, Eureka): Services register and clients query the registry.&lt;/li&gt;
&lt;li&gt;Client-side Discovery: Clients load balance by querying registry.&lt;/li&gt;
&lt;li&gt;Server-side Discovery: Load balancer handles discovery logic.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Example: Kubernetes services use DNS and service mesh proxies (e.g., Envoy).&lt;/p&gt;

&lt;p&gt;👉 Interview tie-in: &lt;em&gt;"How does a service find other services in a dynamic environment?"&lt;/em&gt; — Central registry approach.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Deployment Strategies
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Minimize risk during releases.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Blue/Green Deployment: Deploy to parallel environment, then switch traffic.&lt;/li&gt;
&lt;li&gt;Canary Deployment: Gradually expose new version to a subset of users.&lt;/li&gt;
&lt;li&gt;Rollbacks: Always have a plan to revert to stable version.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Example: New feature rolled out to 5% of users first, monitor errors, then full rollout.&lt;/p&gt;

&lt;p&gt;👉 Interview tie-in: &lt;em&gt;"How do you minimize deployment risk in production?"&lt;/em&gt; — Canary or blue/green deployment.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Monolith vs Microservices
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Don’t microservice just because it sounds trendy.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Monolith: Simple to develop but harder to scale as code grows.&lt;/li&gt;
&lt;li&gt;Microservices: Independent scaling and deployments but added complexity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Example: Start monolithic, split when ops bottlenecks emerge.&lt;/p&gt;

&lt;p&gt;👉 Interview tie-in: &lt;em&gt;"When would you split a monolith?"&lt;/em&gt; — Ops complexity or team size grows.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Distributed Transactions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Avoid 2PC; prefer sagas.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;2PC (Two-Phase Commit): Strong consistency, high latency.&lt;/li&gt;
&lt;li&gt;Sagas: Local transactions with compensating actions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Example: Order triggers inventory decrement and payment; if payment fails, inventory rollback occurs.&lt;/p&gt;

&lt;p&gt;👉 Interview tie-in: &lt;em&gt;"How do you handle cross-service transactions?"&lt;/em&gt; — Sagas.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Event Sourcing &amp;amp; CQRS
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Append-only logs with separate read/write models.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Event Sourcing: Store all events immutably.&lt;/li&gt;
&lt;li&gt;CQRS: Separate models for reads and writes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Example: Event store keeps actions history; read model serves queries.&lt;/p&gt;

&lt;p&gt;👉 Interview tie-in: &lt;em&gt;"Why use Event Sourcing over CRUD?"&lt;/em&gt; — Auditability and state rebuilds.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;service discovery&lt;/strong&gt; for dynamic environments&lt;/li&gt;
&lt;li&gt;Deploy safely with &lt;strong&gt;blue/green or canary strategies&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Microservices make sense only if &lt;strong&gt;ops cost justified&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Implement &lt;strong&gt;sagas over 2PC&lt;/strong&gt; for distributed transactions&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;Event Sourcing &amp;amp; CQRS&lt;/strong&gt; when audit and performance matter&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;💡 &lt;strong&gt;Practice Question:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;"Design a booking system where inventory, payment, and notification services coordinate. How do you ensure eventual consistency without 2PC?"&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>systemdesign</category>
      <category>microservices</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Event-Driven Systems: Building for Scale and Decoupling</title>
      <dc:creator>Sibasish Mohanty</dc:creator>
      <pubDate>Thu, 11 Sep 2025 08:34:53 +0000</pubDate>
      <link>https://forem.com/sibasishm/event-driven-systems-building-for-scale-and-decoupling-3mk3</link>
      <guid>https://forem.com/sibasishm/event-driven-systems-building-for-scale-and-decoupling-3mk3</guid>
      <description>&lt;p&gt;In part 7 of our System Design series, we’re focusing on &lt;strong&gt;asynchronous communication patterns&lt;/strong&gt; that help systems scale, remain resilient, and avoid tight coupling.&lt;/p&gt;

&lt;p&gt;We’ll cover:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Queues &amp;amp; Streams&lt;/strong&gt; – Kafka, RabbitMQ; smoothing spikes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backpressure&lt;/strong&gt; – Managing slow consumers and load shedding&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Delivery Semantics&lt;/strong&gt; – At-most-once, at-least-once, exactly-once&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. Queues &amp;amp; Streams
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Decouple producers from consumers to handle traffic spikes and processing delays.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Message Queues:&lt;/strong&gt; RabbitMQ, SQS – good for task-based workloads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Event Streams:&lt;/strong&gt; Kafka, Kinesis – append-only logs, useful for event sourcing and replay.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Example:&lt;/strong&gt; Order placement publishes events to a queue; different consumers handle billing, inventory update, and notification separately.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Interview tie-in:&lt;/strong&gt; &lt;em&gt;"Why use a queue instead of direct HTTP calls?"&lt;/em&gt; — Decoupling improves resilience and scales better under spikes.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Backpressure
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Don’t let slow consumers cause system meltdown.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Load Shedding:&lt;/strong&gt; Drop low-priority messages when overwhelmed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Buffer Limits:&lt;/strong&gt; Fixed queue sizes prevent uncontrolled memory growth.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consumer Throttling:&lt;/strong&gt; Consumers signal readiness to receive data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Example:&lt;/strong&gt; Kafka pauses sending data to a consumer when it’s overloaded until the consumer catches up.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Interview tie-in:&lt;/strong&gt; &lt;em&gt;"How do you handle a slow consumer in a messaging system?"&lt;/em&gt; — Implement backpressure strategies.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Delivery Semantics
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Pick the right guarantee based on business needs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;At-most-once:&lt;/strong&gt; Risk of message loss, but no duplicates (good for non-critical notifications).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;At-least-once:&lt;/strong&gt; Duplicates possible; consumers must be idempotent (e.g., order processing).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exactly-once:&lt;/strong&gt; Hard to implement; requires complex coordination (Kafka Streams offers it in some cases).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Example:&lt;/strong&gt; Payment processing must be exactly-once; use unique transaction IDs to avoid duplication.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Interview tie-in:&lt;/strong&gt; &lt;em&gt;"Which delivery guarantee would you pick for sending email notifications?"&lt;/em&gt; — At-most-once is acceptable since duplicates are harmless.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;queues and streams&lt;/strong&gt; to decouple and scale&lt;/li&gt;
&lt;li&gt;Implement &lt;strong&gt;backpressure&lt;/strong&gt; to prevent system overload&lt;/li&gt;
&lt;li&gt;Choose the right &lt;strong&gt;delivery semantics&lt;/strong&gt; based on business criticality&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;💡 &lt;strong&gt;Practice Question:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;"Design a video processing pipeline where users upload videos and get them transcoded. How do you handle spikes and ensure each video is processed exactly once?"&lt;/p&gt;

</description>
      <category>systemdesign</category>
      <category>interview</category>
      <category>database</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Don’t Trust, Just Verify: Auth, Faults, and Monitoring</title>
      <dc:creator>Sibasish Mohanty</dc:creator>
      <pubDate>Thu, 11 Sep 2025 08:32:48 +0000</pubDate>
      <link>https://forem.com/sibasishm/dont-trust-just-verify-auth-faults-and-monitoring-43od</link>
      <guid>https://forem.com/sibasishm/dont-trust-just-verify-auth-faults-and-monitoring-43od</guid>
      <description>&lt;p&gt;In part 6 of our System Design series, we’ll tackle the critical pillars of system reliability and security that keep services running smoothly and securely.&lt;/p&gt;

&lt;p&gt;We’ll cover:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;AuthN &amp;amp; AuthZ&lt;/strong&gt; – OAuth2, JWT, RBAC/ABAC&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resilience&lt;/strong&gt; – Circuit breakers, timeouts, retries&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observability&lt;/strong&gt; – Logs, metrics, traces, SLI/SLO&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Health Checks&lt;/strong&gt; – Detect failures, auto-replace&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redundancy&lt;/strong&gt; – Avoid single points of failure (SPOFs); multi-AZ/region&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. AuthN &amp;amp; AuthZ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Authentication proves identity, Authorization checks permissions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OAuth2:&lt;/strong&gt; Delegated authorization, useful for third-party apps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JWT (JSON Web Tokens):&lt;/strong&gt; Stateless, signed tokens for identity verification.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RBAC (Role-Based Access Control):&lt;/strong&gt; Permissions based on roles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ABAC (Attribute-Based Access Control):&lt;/strong&gt; Fine-grained control based on attributes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Example:&lt;/strong&gt; User logs in → receives a JWT → Access to &lt;code&gt;/orders&lt;/code&gt; endpoint is verified using claims in the JWT.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Interview tie-in:&lt;/strong&gt; &lt;em&gt;"How would you design auth for a multi-tenant SaaS app?"&lt;/em&gt; — Use OAuth2 + scoped JWTs.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Resilience
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Systems must fail gracefully.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Circuit Breakers:&lt;/strong&gt; Stop calling a failing service to prevent cascading failure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Timeouts:&lt;/strong&gt; Don’t wait forever for a response.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retries:&lt;/strong&gt; Retry transient failures with exponential backoff.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Example:&lt;/strong&gt; Payment service calls third-party gateway; use circuit breaker to avoid repeated failures.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Interview tie-in:&lt;/strong&gt; &lt;em&gt;"What happens when a downstream service is down?"&lt;/em&gt; — Circuit breaker opens, fallback or error is returned.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Observability
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; If you can’t measure it, you can’t improve it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Logs:&lt;/strong&gt; For detailed debugging&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metrics:&lt;/strong&gt; Quantitative measures (e.g., QPS, error rate)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Traces:&lt;/strong&gt; End-to-end request flow (distributed tracing)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SLI (Service Level Indicator):&lt;/strong&gt; Measured metric (e.g., 99.9% requests &amp;lt; 200ms)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SLO (Service Level Objective):&lt;/strong&gt; Target (e.g., 99.9% of requests &amp;lt; 200ms)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Example:&lt;/strong&gt; Grafana dashboard shows error rates and latency percentiles.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Interview tie-in:&lt;/strong&gt; &lt;em&gt;"How do you monitor a microservice-based architecture?"&lt;/em&gt; — Combine logs, metrics, and tracing.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Health Checks
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Detect problems early and recover automatically.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Liveness Check:&lt;/strong&gt; Is the process alive?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Readiness Check:&lt;/strong&gt; Can it handle requests?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Example:&lt;/strong&gt; Kubernetes probes services every few seconds and restarts if unhealthy.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Interview tie-in:&lt;/strong&gt; &lt;em&gt;"How do you prevent traffic to unhealthy services?"&lt;/em&gt; — Use readiness probes + service discovery.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Redundancy
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; No SPOFs. Multi-AZ or Multi-Region deployments for resilience.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Example:&lt;/strong&gt; Primary DB in us-east-1, replica in us-west-1.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Interview tie-in:&lt;/strong&gt; &lt;em&gt;"How do you handle data center failure?"&lt;/em&gt; — Multi-region replication, failover mechanisms.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Design &lt;strong&gt;auth flows&lt;/strong&gt; with security and scalability in mind&lt;/li&gt;
&lt;li&gt;Build resilience using &lt;strong&gt;circuit breakers, timeouts, retries&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Implement &lt;strong&gt;observability&lt;/strong&gt;: logs, metrics, traces, SLI/SLO&lt;/li&gt;
&lt;li&gt;Health checks prevent serving requests from unhealthy instances&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;redundancy&lt;/strong&gt; to avoid SPOFs and enable disaster recovery&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;💡 &lt;strong&gt;Practice Question:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;"Design an auth system for an API gateway in a microservices architecture. How do you enforce per-service access control and trace requests end-to-end?"&lt;/p&gt;

</description>
      <category>systemdesign</category>
      <category>authjs</category>
      <category>monitoring</category>
      <category>interview</category>
    </item>
    <item>
      <title>Systems Under Pressure: Race Conditions, Rate Limits, and Recovery</title>
      <dc:creator>Sibasish Mohanty</dc:creator>
      <pubDate>Wed, 10 Sep 2025 06:55:55 +0000</pubDate>
      <link>https://forem.com/sibasishm/systems-under-pressure-race-conditions-rate-limits-and-recovery-4bkb</link>
      <guid>https://forem.com/sibasishm/systems-under-pressure-race-conditions-rate-limits-and-recovery-4bkb</guid>
      <description>&lt;p&gt;In part 5 of our System Design series, we’re focusing on how systems behave under load and concurrency challenges. These are critical topics that often trip up engineers in interviews and production.&lt;/p&gt;

&lt;p&gt;We’ll cover:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Concurrency&lt;/strong&gt; – Locks, MVCC, retries&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multithreading&lt;/strong&gt; – Pools, contention, switching&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Idempotency&lt;/strong&gt; – Same request, same effect&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate Limiting&lt;/strong&gt; – Fairness and protection&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. Concurrency
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Multiple operations happening at once? Protect shared data and avoid races.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Locks (mutexes):&lt;/strong&gt; Simple but can cause deadlocks and performance issues.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MVCC (Multi-Version Concurrency Control):&lt;/strong&gt; Every write creates a new version; readers never block writers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retries:&lt;/strong&gt; Optimistic concurrency by retrying on conflict.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Example:&lt;/strong&gt; Bank transfer between accounts uses locks to prevent double spending.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Interview tie-in:&lt;/strong&gt; &lt;em&gt;"How do you handle concurrent writes to the same data?"&lt;/em&gt; — Answer with locking strategies or MVCC.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Multithreading
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Parallelism needs control.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Thread pools:&lt;/strong&gt; Pre-allocated worker threads to handle tasks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contention:&lt;/strong&gt; Avoid too many threads competing for the same resource.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context switching:&lt;/strong&gt; Expensive if overused.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Example:&lt;/strong&gt; Web server uses a thread pool to handle incoming HTTP requests, limiting concurrency to prevent overload.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Interview tie-in:&lt;/strong&gt; &lt;em&gt;"Why not just spawn a new thread per request?"&lt;/em&gt; — Explain thread pool and resource limits.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Idempotency
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Repeating the same request should have the same effect.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Why important:&lt;/strong&gt; Retries due to network errors should not cause duplicate side effects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Example:&lt;/strong&gt; HTTP PUT &lt;code&gt;/users/123/profile&lt;/code&gt; is idempotent; POST &lt;code&gt;/orders&lt;/code&gt; is not, unless you provide a unique order ID.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Interview tie-in:&lt;/strong&gt; &lt;em&gt;"Design a payment API that handles retries safely."&lt;/em&gt; — Focus on idempotent design using unique transaction IDs.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Rate Limiting
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Prevent abuse and manage fair usage.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Strategies:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fixed window (e.g., 100 requests per minute)&lt;/li&gt;
&lt;li&gt;Sliding window&lt;/li&gt;
&lt;li&gt;Token bucket (allows bursts)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Example:&lt;/strong&gt; Twitter limits API usage per developer key.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Interview tie-in:&lt;/strong&gt; &lt;em&gt;"How do you prevent a single client from overloading your system?"&lt;/em&gt; — Implement rate limiting with sliding window or token bucket.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Protect shared data using &lt;strong&gt;locks or MVCC&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;thread pools&lt;/strong&gt; to control parallelism&lt;/li&gt;
&lt;li&gt;Ensure APIs are &lt;strong&gt;idempotent&lt;/strong&gt; to handle retries&lt;/li&gt;
&lt;li&gt;Implement &lt;strong&gt;rate limiting&lt;/strong&gt; to avoid abuse and spikes&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;💡 &lt;strong&gt;Practice Question:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;"Design an API for sending SMS messages. How do you ensure idempotency and rate limits are enforced?"&lt;/p&gt;

</description>
      <category>systemdesign</category>
      <category>interview</category>
      <category>backend</category>
      <category>programming</category>
    </item>
    <item>
      <title>From Simplicity to Complexity: My Love-Hate Journey with Next.js</title>
      <dc:creator>Sibasish Mohanty</dc:creator>
      <pubDate>Tue, 09 Sep 2025 03:13:41 +0000</pubDate>
      <link>https://forem.com/sibasishm/from-simplicity-to-complexity-my-love-hate-journey-with-nextjs-3do0</link>
      <guid>https://forem.com/sibasishm/from-simplicity-to-complexity-my-love-hate-journey-with-nextjs-3do0</guid>
      <description>&lt;p&gt;I remember the day I started using Next.js like it was yesterday. It was version 8. And honestly? It was love at first sight. I bootstraped our new project in Nextjs despite my CTOs hesitation and made my teammates who never wrote a single line of code in React, learn Nextjs and ship with confidence.&lt;/p&gt;

&lt;p&gt;File-based routing.&lt;br&gt;
SSR. SSG. ISR.&lt;br&gt;
Zero config.&lt;br&gt;
You slapped a file in the &lt;code&gt;pages/&lt;/code&gt; folder, and boom—you had a route.&lt;br&gt;
Simple, elegant, almost… magical.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// pages/about.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;About&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;About&lt;/span&gt; &lt;span class="nx"&gt;us&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It did what React should have done out of the box but didn’t. I was sold.&lt;br&gt;
Deploy it, forget about webpack configs, no client-side routing hacks. Just productivity.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Shift: Enter Next.js 13 &amp;amp; The App Router Madness
&lt;/h2&gt;

&lt;p&gt;Then Next.js 13 hit, and things changed.&lt;br&gt;
Suddenly, &lt;code&gt;pages/&lt;/code&gt; was &lt;em&gt;optional&lt;/em&gt;. Enter the &lt;code&gt;app/&lt;/code&gt; directory. Layouts. Templates. Nested routing. React Server Components. &lt;code&gt;use client&lt;/code&gt; directives.&lt;/p&gt;

&lt;p&gt;It felt… like betrayal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/layout.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Layout&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;layout&lt;/span&gt;&lt;span class="dl"&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;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why?&lt;br&gt;
Because the mental model shifted from “Page = Route” to “Segment = Route + Layout + Data Layer + Responsibility Split.”&lt;br&gt;
Now I had to think in terms of route segments and where data should live: server component vs client component vs fetch cache vs what the hell.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Mental Model Shift Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;Before, I thought:&lt;br&gt;
“I add a file, it’s a route. Done.”&lt;/p&gt;

&lt;p&gt;Now I have to ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is this a server component or client component?&lt;/li&gt;
&lt;li&gt;Should data fetching happen in &lt;code&gt;generateStaticParams&lt;/code&gt; or inline in the component?&lt;/li&gt;
&lt;li&gt;Where does this layout go?&lt;/li&gt;
&lt;li&gt;Is this a template or a layout?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s not just about writing code anymore.&lt;br&gt;
It’s about architecting for Next.js’s new ecosystem.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/products/[id]/page.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ProductPage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;params&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;
  &lt;span class="c1"&gt;// Do I fetch here? Should this be a server component?&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fun, right?&lt;/p&gt;




&lt;h2&gt;
  
  
  Love, But With Conditions
&lt;/h2&gt;

&lt;p&gt;Let me be clear: I love the power.&lt;br&gt;
Server Components are a &lt;em&gt;huge&lt;/em&gt; win.&lt;br&gt;
Nested layouts? Clean.&lt;br&gt;
Improved routing flexibility? Great.&lt;br&gt;
Performance optimizations baked in? Finally.&lt;/p&gt;

&lt;p&gt;But…&lt;/p&gt;

&lt;p&gt;It feels overengineered.&lt;br&gt;
Every simple use case now requires reading three different RFCs.&lt;br&gt;
Constantly wondering if you’re doing it “the Next Way™” or just making a hack that’ll break in the next release.&lt;/p&gt;




&lt;h2&gt;
  
  
  Should You Care?
&lt;/h2&gt;

&lt;p&gt;If you’re building large, scalable apps or deeply care about performance, yes.&lt;br&gt;
Next.js App Router is awesome when you’ve got the bandwidth to understand it.&lt;/p&gt;

&lt;p&gt;If you just want to ship stuff, fast and simple…&lt;br&gt;
Stick to &lt;code&gt;pages/&lt;/code&gt;. Forget Server Components. Forget complicated layouts.&lt;br&gt;
Use Next.js like the framework it used to be.&lt;/p&gt;




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

&lt;p&gt;Next.js is amazing at scale.&lt;br&gt;
Next.js is terrible when you want simplicity.&lt;/p&gt;

&lt;p&gt;It’s like loving a Swiss Army knife, but sometimes you just need a plain old screwdriver.&lt;br&gt;
And now, the screwdriver has a dozen attachments you don’t care about.&lt;/p&gt;

&lt;p&gt;Still, I’m in.&lt;br&gt;
Because I know the payoff exists…&lt;br&gt;
If I survive the learning curve.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Distributed Systems Without the Buzzwords</title>
      <dc:creator>Sibasish Mohanty</dc:creator>
      <pubDate>Mon, 08 Sep 2025 05:50:24 +0000</pubDate>
      <link>https://forem.com/sibasishm/distributed-systems-without-the-buzzwords-5d8o</link>
      <guid>https://forem.com/sibasishm/distributed-systems-without-the-buzzwords-5d8o</guid>
      <description>&lt;p&gt;In part 4 of our System Design series, we’re exploring the &lt;strong&gt;building blocks of distributed systems&lt;/strong&gt;. These are the principles that separate toy apps from production-grade platforms.&lt;/p&gt;

&lt;p&gt;We’ll cover:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;CDN &amp;amp; Edge&lt;/strong&gt; – serve static content near users&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sharding&lt;/strong&gt; – hash, range, geo; handling hot keys&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Replication&lt;/strong&gt; – sync/async, leader/follower, read replicas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistency Models&lt;/strong&gt; – strong, eventual, causal&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CAP Theorem&lt;/strong&gt; – in partition, pick A or C&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. CDN &amp;amp; Edge
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Put content closer to users to cut latency.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CDN (Content Delivery Network):&lt;/strong&gt; Caches static assets (images, CSS, JS) at edge locations worldwide.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edge computing:&lt;/strong&gt; Pushes logic (e.g., auth, personalization) closer to users.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Example:&lt;/strong&gt; Netflix streams video chunks from servers near your city, not across the ocean.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Interview tie-in:&lt;/strong&gt; &lt;em&gt;“How would you reduce latency for global users?”&lt;/em&gt; — CDN is step 1.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Sharding
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Split data across multiple nodes for scale.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hash-based:&lt;/strong&gt; Even distribution, but rebalancing is tricky.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Range-based:&lt;/strong&gt; Easy for range queries, but hotspots form.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Geo-sharding:&lt;/strong&gt; Route users to nearest region.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Problem:&lt;/strong&gt; &lt;em&gt;Hot keys&lt;/em&gt; — a celebrity account with 10M followers can overload one shard.&lt;br&gt;
👉 &lt;strong&gt;Solution:&lt;/strong&gt; Key-splitting, consistent hashing, or virtual shards.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Interview tie-in:&lt;/strong&gt; &lt;em&gt;“How do you handle scale in a key-value store?”&lt;/em&gt; — talk sharding.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Replication
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Keep multiple copies of data for durability &amp;amp; scale.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Leader/follower (primary/replica):&lt;/strong&gt; One leader handles writes, replicas handle reads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Synchronous:&lt;/strong&gt; Safer, but higher latency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Asynchronous:&lt;/strong&gt; Faster, but risk of data loss on failure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Example:&lt;/strong&gt; MySQL read replicas to scale reads, leader for writes.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Interview tie-in:&lt;/strong&gt; &lt;em&gt;“How do you scale database reads?”&lt;/em&gt; — use replicas.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Consistency Models
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Tradeoff between user experience and performance.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Strong consistency:&lt;/strong&gt; Every read sees the latest write.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Eventual consistency:&lt;/strong&gt; Reads may lag but converge over time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Causal consistency:&lt;/strong&gt; Preserves cause-effect order.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Example:&lt;/strong&gt; Banking needs strong consistency. Social feeds tolerate eventual.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Interview tie-in:&lt;/strong&gt; Expect &lt;em&gt;“Would you use strong or eventual consistency here?”&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  5. CAP Theorem
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; In a network partition, you must choose between Consistency (C) and Availability (A).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CP systems:&lt;/strong&gt; Choose consistency, sacrifice availability (e.g., Zookeeper).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AP systems:&lt;/strong&gt; Choose availability, tolerate stale reads (e.g., DynamoDB).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Interview tie-in:&lt;/strong&gt; They love asking &lt;em&gt;“Which side of CAP would you pick?”&lt;/em&gt; — always tie your answer back to the product requirements.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;CDN/edge&lt;/strong&gt; to cut latency for global users&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shard&lt;/strong&gt; for scale, but handle hot keys carefully&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Replicate&lt;/strong&gt; for durability and read scaling&lt;/li&gt;
&lt;li&gt;Know when to pick &lt;strong&gt;strong vs eventual consistency&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;CAP isn’t academic — it’s the heart of distributed tradeoffs&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;💡 &lt;strong&gt;Practice Question:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;"Design a globally available chat app. How would you shard user messages, and what consistency model would you choose?"&lt;/p&gt;

</description>
      <category>programming</category>
      <category>distributedsystems</category>
      <category>systemdesign</category>
      <category>interview</category>
    </item>
    <item>
      <title>My Recent Debugging Adventure: The Case of the Disappearing Stylesheets</title>
      <dc:creator>Sibasish Mohanty</dc:creator>
      <pubDate>Thu, 04 Sep 2025 14:32:03 +0000</pubDate>
      <link>https://forem.com/sibasishm/my-recent-debugging-adventure-the-case-of-the-disappearing-stylesheets-5dbb</link>
      <guid>https://forem.com/sibasishm/my-recent-debugging-adventure-the-case-of-the-disappearing-stylesheets-5dbb</guid>
      <description>&lt;p&gt;You know those days where a tiny bug eats half your brainpower, and then when you finally solve it, you feel like both an idiot and a wizard? Yeah. This is one of those stories.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Setup: Performance Optimization Gone Wrong
&lt;/h2&gt;

&lt;p&gt;Like any good frontend engineer, I wanted to optimize stylesheet loading. So instead of letting stylesheets block render, I tagged them like this:&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;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;media=&lt;/span&gt;&lt;span class="s"&gt;"print"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/assets/css/base.css"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The trick here: browsers skip applying &lt;code&gt;media="print"&lt;/code&gt; styles until you explicitly flip it to &lt;code&gt;all&lt;/code&gt;. That way, the stylesheet downloads in the background, but doesn’t block rendering.&lt;/p&gt;

&lt;p&gt;And then I had a little script to flip the switch:&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="nb"&gt;document&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;link[rel="stylesheet"][media="print"]&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;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;enableMedia&lt;/span&gt; &lt;span class="o"&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;link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;media&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;all&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;load&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;enableMedia&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;link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sheet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;enableMedia&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;link&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="s1"&gt;load&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;enableMedia&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;Beautiful, right? Except … nothing happened. Stylesheets never applied. My page looked naked. Not in a good way 😜.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bug: CSP Meets Timing
&lt;/h2&gt;

&lt;p&gt;First instinct: CSP. I had a pretty strict Content Security Policy with &lt;code&gt;script-src 'self' 'strict-dynamic'&lt;/code&gt;. Inline hacks were out, so the loader script was external.&lt;/p&gt;

&lt;p&gt;But then I noticed something curious: my script was being &lt;strong&gt;deferred&lt;/strong&gt;.&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;script &lt;/span&gt;&lt;span class="na"&gt;defer&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/static/js/stylesheetloader.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;defer&lt;/code&gt; means &lt;em&gt;“wait until HTML parsing is done before running this script”&lt;/em&gt;. By then, the browser had already seen my &lt;code&gt;&amp;lt;link media="print"&amp;gt;&lt;/code&gt; tags, queued them, and … didn’t trigger &lt;code&gt;load&lt;/code&gt; the way I expected. My script showed up too late to catch the party.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fix: Async to the Rescue
&lt;/h2&gt;

&lt;p&gt;The fix was almost laughably simple:&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;script &lt;/span&gt;&lt;span class="na"&gt;async&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/static/js/stylesheetloader.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Switching &lt;code&gt;defer&lt;/code&gt; to &lt;code&gt;async&lt;/code&gt; made the script run as soon as it was available, before the render pipeline locked things down. Boom 💥. Stylesheets applied perfectly.&lt;/p&gt;

&lt;p&gt;Sometimes all it takes is one attribute flip to go from “WTF why is CSS broken” to “I am a genius.”&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Works
&lt;/h2&gt;

&lt;p&gt;Let’s zoom out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;defer&lt;/code&gt;&lt;/strong&gt; scripts wait until after HTML parsing is complete, keeping order intact.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;async&lt;/code&gt;&lt;/strong&gt; scripts run as soon as they’re downloaded, ignoring order.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In my case, I didn’t care about execution order. I just needed the loader to run ASAP. Async was the perfect fit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Performance hacks are sharp knives.&lt;/strong&gt; Using &lt;code&gt;media="print"&lt;/code&gt; for async stylesheets works, but you need to manage timing carefully.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CSP adds invisible complexity.&lt;/strong&gt; With inline scripts off the table, your timing depends entirely on how you load external JS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;defer&lt;/code&gt; vs &lt;code&gt;async&lt;/code&gt; actually matters.&lt;/strong&gt; Don’t just cargo-cult &lt;code&gt;defer&lt;/code&gt; everywhere. Think about &lt;em&gt;when&lt;/em&gt; you need the script to run.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Generalizing the Problem
&lt;/h2&gt;

&lt;p&gt;This isn’t just about my stylesheet loader. It’s a broader lesson about script execution timing under CSP:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you have critical scripts that need to act &lt;strong&gt;before rendering decisions&lt;/strong&gt; (like stylesheet toggles, dynamic meta updates, etc.), use &lt;code&gt;async&lt;/code&gt; or preload strategies.&lt;/li&gt;
&lt;li&gt;If execution order matters (like multiple polyfills), then &lt;code&gt;defer&lt;/code&gt; is safer.&lt;/li&gt;
&lt;li&gt;If you’re battling CSP, externalize your hacks, don’t rely on inline event handlers (&lt;code&gt;onload="..."&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Alternatives Worth Considering
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;&amp;lt;link rel="preload"&amp;gt;&lt;/code&gt;&lt;/strong&gt;: preload stylesheets and apply later.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modern bundlers (Rsbuild, Vite)&lt;/strong&gt;: can inline critical CSS and lazy-load the rest.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JS-based style injection&lt;/strong&gt;: less common, but some teams prefer runtime style injection for full control.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wrap-up
&lt;/h2&gt;

&lt;p&gt;Sometimes, a bug isn’t about broken code. It’s about &lt;strong&gt;tiny mismatches in timing and browser behavior&lt;/strong&gt;. This one was a perfect storm of CSP, &lt;code&gt;defer&lt;/code&gt;, and stylesheet loading tricks.&lt;/p&gt;

&lt;p&gt;I wasted hours chasing ghosts, but in the end, flipping one attribute fixed everything. The kind of debugging adventure that keeps you humble … and slightly amused.&lt;/p&gt;

&lt;p&gt;So next time your CSS looks naked, check your &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; attributes. 😉&lt;/p&gt;

</description>
      <category>css</category>
      <category>javascript</category>
      <category>security</category>
      <category>react</category>
    </item>
    <item>
      <title>Cache Me If You Can: Design Patterns for Performance</title>
      <dc:creator>Sibasish Mohanty</dc:creator>
      <pubDate>Wed, 03 Sep 2025 04:00:23 +0000</pubDate>
      <link>https://forem.com/sibasishm/cache-me-if-you-can-design-patterns-for-performance-4ag0</link>
      <guid>https://forem.com/sibasishm/cache-me-if-you-can-design-patterns-for-performance-4ag0</guid>
      <description>&lt;p&gt;In part 3 of our System Design series, we’re tackling &lt;strong&gt;caching and load balancing&lt;/strong&gt; — the unsung heroes of performance. Without them, systems crumble under scale.&lt;/p&gt;

&lt;p&gt;We’ll cover:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Caching&lt;/strong&gt; – App/DB/CDN; write-through/write-back, TTLs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache Invalidation&lt;/strong&gt; – TTLs, versioning, stampede protection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Load Balancing&lt;/strong&gt; – L4/L7, round-robin, least-connections, hashing&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. Caching
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Caching is your first lever for scale. Use it everywhere, but know the trade-offs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;App cache:&lt;/strong&gt; In-memory (Redis, Memcached). Ultra-fast but volatile.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DB cache:&lt;/strong&gt; Query or object cache to offload hot queries.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CDN cache:&lt;/strong&gt; Push static assets near users.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Strategies:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Write-through:&lt;/strong&gt; Write to cache + DB simultaneously (safe, consistent, slower writes)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write-back:&lt;/strong&gt; Write to cache first, sync to DB later (fast, risky if cache crashes)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TTL (Time To Live):&lt;/strong&gt; Expire stale data automatically&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Example:&lt;/strong&gt; A news homepage caches top stories for 30s — thousands of requests saved.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Interview tie-in:&lt;/strong&gt; “How would you scale a read-heavy service?” — caching is the first answer.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Cache Invalidation
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; The hardest part of caching isn’t caching — it’s invalidation.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;TTL:&lt;/strong&gt; Safe default, but may serve stale data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Versioning:&lt;/strong&gt; Change cache key when data updates (e.g., &lt;code&gt;user:v2:123&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stampede protection:&lt;/strong&gt; Use locking or request coalescing so multiple clients don’t hammer the DB when cache expires.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Example:&lt;/strong&gt; If 1M users refresh when a cache expires, that’s a &lt;strong&gt;cache stampede&lt;/strong&gt;. Use jittered TTLs or async refresh.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Interview tie-in:&lt;/strong&gt; They’ll ask &lt;em&gt;“What’s the hardest part about caching?”&lt;/em&gt; — answer: &lt;strong&gt;invalidation and consistency.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Load Balancing
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Load balancers spread requests across servers and hide failures.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;L4 (Transport):&lt;/strong&gt; Balances based on IP/port. Simple, fast.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;L7 (Application):&lt;/strong&gt; Smarter — routes based on headers, cookies, paths.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Algorithms:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Round Robin:&lt;/strong&gt; Even distribution&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Least Connections:&lt;/strong&gt; Send to the server with fewest active requests&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hashing:&lt;/strong&gt; Sticky sessions (e.g., same user → same server)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Example:&lt;/strong&gt; E-commerce app uses L7 LB to route &lt;code&gt;/images&lt;/code&gt; → CDN, &lt;code&gt;/checkout&lt;/code&gt; → payment cluster.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Interview tie-in:&lt;/strong&gt; “How do you handle uneven traffic across servers?” — least-connections or weighted load balancing.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Cache where it hurts most: &lt;strong&gt;hot queries, static assets, read-heavy endpoints&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Invalidation is the &lt;strong&gt;real challenge&lt;/strong&gt;; plan strategies upfront&lt;/li&gt;
&lt;li&gt;Load balancing is critical for &lt;strong&gt;fairness, resilience, and routing logic&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;💡 &lt;strong&gt;Practice Question:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;"Design the caching strategy for a Twitter timeline. How would you avoid cache stampede during trending events?"&lt;/p&gt;

</description>
      <category>systemdesign</category>
      <category>interview</category>
      <category>performance</category>
      <category>programming</category>
    </item>
    <item>
      <title>Data Design That Doesn't Crumble at Scale</title>
      <dc:creator>Sibasish Mohanty</dc:creator>
      <pubDate>Thu, 28 Aug 2025 05:34:24 +0000</pubDate>
      <link>https://forem.com/sibasishm/data-design-that-doesnt-crumble-at-scale-334j</link>
      <guid>https://forem.com/sibasishm/data-design-that-doesnt-crumble-at-scale-334j</guid>
      <description>&lt;p&gt;The second part of our System Design series dives into &lt;strong&gt;data fundamentals&lt;/strong&gt;. Most systems fail not because of code, but because of &lt;em&gt;bad data modeling decisions&lt;/em&gt;. Let’s break down four pillars:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;SQL vs NoSQL&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Data Modeling&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Indexing&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Normalization&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. SQL vs NoSQL
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Pick based on &lt;em&gt;access patterns&lt;/em&gt;, not hype.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SQL (Relational):&lt;/strong&gt; Strong consistency, structured schema, powerful joins. Great for transactions (e.g., payments).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NoSQL:&lt;/strong&gt; Flexible schema, horizontal scale, eventual consistency. Great for unstructured or high-write workloads (e.g., social feeds).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Rule of thumb:&lt;/strong&gt; If you need joins and ACID, use SQL. If you need scale and flexibility, lean toward NoSQL.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Interview tie-in:&lt;/strong&gt; &lt;em&gt;“Design Twitter feed storage.”&lt;/em&gt; Likely NoSQL, with denormalized fan-out.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Data Modeling
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Always model data &lt;strong&gt;around your hot queries&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Think backwards: What queries will dominate traffic?&lt;/li&gt;
&lt;li&gt;Denormalize or restructure tables/collections for those.&lt;/li&gt;
&lt;li&gt;Optimize for reads if the system is read-heavy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Example:&lt;/strong&gt; In an e-commerce app, &lt;code&gt;Orders&lt;/code&gt; table needs fast lookup by &lt;code&gt;userId&lt;/code&gt;. That index matters more than less-frequent joins.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Interview tie-in:&lt;/strong&gt; They want to see that you &lt;em&gt;don’t design schemas in a vacuum&lt;/em&gt; — you design for usage.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Indexing
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; The right index makes queries fly; the wrong one makes writes crawl.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Primary index:&lt;/strong&gt; Natural row identifier (e.g., &lt;code&gt;id&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secondary indexes:&lt;/strong&gt; Speed up queries but slow down writes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Composite indexes:&lt;/strong&gt; Useful when filtering on multiple fields&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Example:&lt;/strong&gt; &lt;code&gt;WHERE userId = 123 AND status = 'ACTIVE'&lt;/code&gt; → composite index on &lt;code&gt;(userId, status)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Interview tie-in:&lt;/strong&gt; Expect questions like &lt;em&gt;“Why is this query slow despite indexing?”&lt;/em&gt; — hint: wrong index or low selectivity.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Normalization
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Normalize for writes, denormalize for reads.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Normalization:&lt;/strong&gt; Reduce redundancy, avoid anomalies (great for OLTP)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Denormalization:&lt;/strong&gt; Duplicate data to speed up queries (great for OLAP)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Example:&lt;/strong&gt; User profile data normalized in &lt;code&gt;Users&lt;/code&gt; table. For faster feed rendering, duplicate username and avatar in &lt;code&gt;Posts&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Interview tie-in:&lt;/strong&gt; “Would you normalize user data in a news feed?” — no, you’d denormalize for speed.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Choose SQL vs NoSQL based on &lt;strong&gt;workload, not dogma&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model around hot queries&lt;/strong&gt;, not theoretical schemas&lt;/li&gt;
&lt;li&gt;Use indexes wisely — they’re a &lt;strong&gt;double-edged sword&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Normalize for &lt;strong&gt;writes&lt;/strong&gt;, denormalize for &lt;strong&gt;reads&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;💡 &lt;strong&gt;Practice Question:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;"Design the database schema for Instagram posts, likes, and comments. Which parts would you normalize, and which would you denormalize?"&lt;/p&gt;

</description>
      <category>programming</category>
      <category>systemdesign</category>
      <category>database</category>
      <category>interview</category>
    </item>
    <item>
      <title>Scaling Isn’t Magic: Fundamentals They Expect You to Know</title>
      <dc:creator>Sibasish Mohanty</dc:creator>
      <pubDate>Tue, 26 Aug 2025 15:51:46 +0000</pubDate>
      <link>https://forem.com/sibasishm/scaling-isnt-magic-fundamentals-they-expect-you-to-know-ka9</link>
      <guid>https://forem.com/sibasishm/scaling-isnt-magic-fundamentals-they-expect-you-to-know-ka9</guid>
      <description>&lt;p&gt;System Design interviews can feel overwhelming, but they always boil down to a few &lt;em&gt;first principles&lt;/em&gt;. In this post, we’ll cover four foundational topics:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt; – Vertical vs Horizontal&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Latency &amp;amp; Throughput&lt;/strong&gt; – P50, P95, P99&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Capacity Estimation&lt;/strong&gt; – QPS, storage, bandwidth&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Networking Basics&lt;/strong&gt; – TCP, HTTP/HTTPS, TLS, UDP, DNS&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. Scalability: Vertical vs Horizontal
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Scale vertically until you hit diminishing returns, then go horizontal. Default to &lt;strong&gt;stateless services&lt;/strong&gt; for easy horizontal scaling.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vertical scaling:&lt;/strong&gt; Bigger machine (more CPU, RAM, disk). Easy but capped. Expensive and risk of single point of failure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Horizontal scaling:&lt;/strong&gt; More machines (stateless servers behind a load balancer). Harder to manage but scales better.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Interview tie-in:&lt;/strong&gt; They’ll ask &lt;em&gt;“How would you scale this system to handle 10x users?”&lt;/em&gt; Answer with horizontal scaling + stateless services.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Latency &amp;amp; Throughput
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Latency = how long one request takes. Throughput = how many requests per unit time.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Latency percentiles:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;P50 (median): What most users see&lt;/li&gt;
&lt;li&gt;P95: The "tail" – 5% of users worse than this&lt;/li&gt;
&lt;li&gt;P99: Worst case for 1% of users, often drives design&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tradeoff:&lt;/strong&gt; Optimizing tail latency may hurt throughput, and vice versa.&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Analogy:&lt;/strong&gt; Coffee shop.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Latency = how long it takes to serve one customer.&lt;/li&gt;
&lt;li&gt;Throughput = how many coffees per minute.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Interview tie-in:&lt;/strong&gt; "We want 95% of requests under 200ms." That’s &lt;strong&gt;P95 latency target&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Capacity Estimation
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Always &lt;em&gt;estimate&lt;/em&gt; load before designing. Even rough math is better than guessing.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;QPS (Queries Per Second):&lt;/strong&gt; How many requests per second your service must handle.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storage:&lt;/strong&gt; How much data accumulates per day/month/year.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bandwidth:&lt;/strong&gt; How much data moves across the network.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1M daily active users&lt;/li&gt;
&lt;li&gt;Each makes 10 requests/day → ~115 QPS&lt;/li&gt;
&lt;li&gt;Each request ~1KB → ~10MB/day traffic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Interview tie-in:&lt;/strong&gt; They’ll push you to "estimate scale" before proposing an architecture. Show your math, even if it’s rough.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Networking Basics
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Most systems fail because people ignore networking bottlenecks.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;TCP:&lt;/strong&gt; Reliable, ordered, connection-based&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UDP:&lt;/strong&gt; Fast, connectionless, may drop packets (used for video/games)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTP/HTTPS:&lt;/strong&gt; Request-response on top of TCP; HTTPS adds TLS encryption&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DNS:&lt;/strong&gt; Resolves &lt;code&gt;google.com&lt;/code&gt; → IP address&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TLS handshake:&lt;/strong&gt; Extra latency on first connection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Interview tie-in:&lt;/strong&gt; Expect questions like &lt;em&gt;"Why use UDP for video streaming instead of TCP?"&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Prefer &lt;strong&gt;stateless horizontal scaling&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Measure both &lt;strong&gt;latency (P95)&lt;/strong&gt; and &lt;strong&gt;throughput&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Always &lt;strong&gt;estimate capacity&lt;/strong&gt; before proposing a design&lt;/li&gt;
&lt;li&gt;Know your &lt;strong&gt;networking trade-offs&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;💡 &lt;strong&gt;Practice Question:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;"Design a URL shortener for 50M users. How many requests/sec do you expect? What’s your scaling plan?"&lt;/p&gt;

</description>
      <category>systemdesign</category>
      <category>softwaredevelopment</category>
      <category>interview</category>
      <category>career</category>
    </item>
    <item>
      <title>Stop Fetching Data in useEffect: Redux Edition</title>
      <dc:creator>Sibasish Mohanty</dc:creator>
      <pubDate>Tue, 29 Jul 2025 06:45:20 +0000</pubDate>
      <link>https://forem.com/sibasishm/stop-fetching-data-in-useeffect-redux-edition-4gb4</link>
      <guid>https://forem.com/sibasishm/stop-fetching-data-in-useeffect-redux-edition-4gb4</guid>
      <description>&lt;p&gt;In &lt;a href="https://dev.to/sibasishm/stop-fetching-data-in-useeffect-youre-not-writing-jquery-anymore-2mb2"&gt;Part 1&lt;/a&gt;, we talked about why fetching data directly inside useEffect is a flawed approach — tightly coupling component lifecycle to data-fetching logic, leading to unmanageable side effects, broken UX, and stale state bugs. We compared it to jQuery’s imperative data flows and showed how React in 2025 demands a more declarative mental model.&lt;/p&gt;

&lt;p&gt;But the story doesn’t end there.&lt;/p&gt;

&lt;p&gt;In this second part, we tackle an even more common anti-pattern, especially in Redux-heavy codebases:&lt;br&gt;
&lt;strong&gt;Dispatching async thunks&lt;/strong&gt; from &lt;code&gt;useEffect&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fetchUserData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It might look cleaner than raw &lt;code&gt;fetch()&lt;/code&gt;, but it inherits the same rot underneath.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Pattern Still Exists
&lt;/h2&gt;

&lt;p&gt;Before React Hooks, data fetching in Redux apps happened in &lt;code&gt;componentDidMount()&lt;/code&gt;, with connected components via &lt;code&gt;connect()&lt;/code&gt; HOCs. That &lt;a href="https://react-redux.js.org/api/connect" rel="noopener noreferrer"&gt;lifecycle-to-dispatch model&lt;/a&gt; was &lt;strong&gt;normative&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When hooks arrived with &lt;code&gt;useEffect&lt;/code&gt;, developers naturally ported this over. This became the de facto pattern. Even the official React-Redux docs &lt;a href="https://react-redux.js.org/api/hooks#usedispatch" rel="noopener noreferrer"&gt;show this&lt;/a&gt; for simple use cases.&lt;/p&gt;

&lt;p&gt;It was a one-to-one migration. And at the time, it made sense.&lt;/p&gt;

&lt;p&gt;You needed to kick off a thunk or saga somewhere, and &lt;code&gt;useEffect&lt;/code&gt; was the hammer for all side-effect nails.&lt;/p&gt;

&lt;p&gt;But Redux evolved.&lt;/p&gt;

&lt;p&gt;As &lt;a href="https://x.com/acemarke?lang=en" rel="noopener noreferrer"&gt;Mark Erikson&lt;/a&gt; (Redux maintainer) has repeatedly &lt;a href="https://blog.isquaredsoftware.com/2020/05/blogged-answers-a-mostly-complete-guide-to-react-rendering-behavior/#react-redux-and-rendering-behavior" rel="noopener noreferrer"&gt;emphasized&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"You probably don’t need &lt;code&gt;useEffect&lt;/code&gt;. And if you're dispatching from it, it's likely a code smell."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yet, many codebases (even recent ones) still cling to the old &lt;code&gt;dispatch-in-useEffect&lt;/code&gt; dance. Let’s unpack why that’s a problem.&lt;/p&gt;

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

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

&lt;ul&gt;
&lt;li&gt;Delays data availability until after first render&lt;/li&gt;
&lt;li&gt;Forces you to manage loading and error state manually&lt;/li&gt;
&lt;li&gt;Ties async logic to the lifecycle, not the state graph&lt;/li&gt;
&lt;li&gt;Doesn’t support SSR or Suspense&lt;/li&gt;
&lt;li&gt;Is verbose, hard to test, and easy to misuse&lt;/li&gt;
&lt;li&gt;Encourages repetition (every page/component reimplements fetch logic)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Worse, this makes your components &lt;strong&gt;non-composable&lt;/strong&gt;. You can’t reuse this logic in another component without copy-pasting or lifting.&lt;/p&gt;

&lt;p&gt;You're not modeling &lt;strong&gt;data&lt;/strong&gt; — you're modeling &lt;strong&gt;timing&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  But Isn’t Redux Still Useful?
&lt;/h3&gt;

&lt;p&gt;It is — but not for remote server data.&lt;/p&gt;

&lt;p&gt;Redux is &lt;a href="https://blog.isquaredsoftware.com/2021/01/context-redux-differences/" rel="noopener noreferrer"&gt;great&lt;/a&gt; for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Global, non-remote state (auth, UI toggles, preferences)&lt;/li&gt;
&lt;li&gt;Workflow state (multi-step forms, undo/redo, complex user flows)&lt;/li&gt;
&lt;li&gt;Cross-cutting logic (feature flags, permission checks)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fetching lists&lt;/li&gt;
&lt;li&gt;User profiles&lt;/li&gt;
&lt;li&gt;Paginated feeds&lt;/li&gt;
&lt;li&gt;Notifications&lt;/li&gt;
&lt;li&gt;Dashboard metrics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;...classic Redux is &lt;em&gt;too much ceremony&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;You don’t need reducers, actions, thunks, and selectors just to load some damn data.&lt;/p&gt;

&lt;p&gt;You need a &lt;strong&gt;query layer&lt;/strong&gt; — not a state machine factory.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is dispatch() in useEffect() Always Wrong?
&lt;/h3&gt;

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

&lt;p&gt;Sometimes you genuinely need to dispatch on mount, maybe to initialize a websocket, fire a metrics event, or pre-warm a cache.&lt;/p&gt;

&lt;p&gt;But when you're fetching &lt;strong&gt;render-critical data&lt;/strong&gt;, dispatching inside &lt;code&gt;useEffect&lt;/code&gt; means you're reacting &lt;strong&gt;too late&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You’ve already rendered once.&lt;br&gt;
You’ve already missed the chance to prefetch or SSR.&lt;br&gt;
You’ve already broken the declarative contract.&lt;/p&gt;
&lt;h2&gt;
  
  
  If You &lt;em&gt;Have&lt;/em&gt; to Use Classic Redux
&lt;/h2&gt;

&lt;p&gt;Encapsulate the dispatch logic in a custom hook to decouple data orchestration from your component:&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;useUserData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dispatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useDispatch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useSelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userId&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;loading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useSelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fetchUserData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;loading&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;Then use declaratively:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useUserData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;Your component stays declarative&lt;/li&gt;
&lt;li&gt;The effect logic is testable and reusable&lt;/li&gt;
&lt;li&gt;You reduce boilerplate inside the view layer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Still far from ideal — but survivable.&lt;/p&gt;

&lt;h2&gt;
  
  
  So What Should You Do Instead?
&lt;/h2&gt;

&lt;p&gt;Data fetching deserves better than a &lt;code&gt;useEffect&lt;/code&gt; hack job. If your mental model is still stuck in 2019, it's time for a reset.&lt;/p&gt;

&lt;p&gt;In Part 3, we’ll explore a *&lt;em&gt;declarative routing-first approach *&lt;/em&gt; to data fetching using loader, useLoaderData, and compare that with popular solutions like RTK Query, TanStack Query, swr and even emerging Suspense APIs. We'll also address how to gracefully migrate away from this legacy pattern in large codebases.&lt;/p&gt;

&lt;p&gt;And yes — there’s a way to do all this without ditching Redux if you don’t want to.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;useEffect is not a data-fetching tool&lt;/li&gt;
&lt;li&gt;Dispatching async thunks in useEffect is an outdated, fragile pattern&lt;/li&gt;
&lt;li&gt;This made sense in pre-RTK Redux, but should be retired&lt;/li&gt;
&lt;li&gt;Redux already solved this. It’s called RTK Query.&lt;/li&gt;
&lt;li&gt;RTK Query, TanStack Query, and Loader APIs offer better abstractions&lt;/li&gt;
&lt;li&gt;Declarative data &amp;gt; lifecycle-driven orchestration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re still writing async thunks just to get a list of users, it’s time to ask yourself why.&lt;/p&gt;

&lt;p&gt;You’re still not writing jQuery.&lt;br&gt;
And now — you shouldn't be writing it with Redux either.&lt;/p&gt;

</description>
      <category>react</category>
      <category>redux</category>
      <category>discuss</category>
      <category>frontend</category>
    </item>
  </channel>
</rss>
