<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Roshan singh</title>
    <description>The latest articles on DEV Community by Roshan singh (@roshan_singh_dd54d52bbaa7).</description>
    <link>https://dev.to/roshan_singh_dd54d52bbaa7</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%2F3839420%2F5e120b67-904e-4b10-96a3-9bc665b0a71b.png</url>
      <title>DEV Community: Roshan singh</title>
      <link>https://dev.to/roshan_singh_dd54d52bbaa7</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/roshan_singh_dd54d52bbaa7"/>
    <language>en</language>
    <item>
      <title># 🚀 Important React Interview Questions Every Developer Must Know</title>
      <dc:creator>Roshan singh</dc:creator>
      <pubDate>Fri, 08 May 2026 06:28:56 +0000</pubDate>
      <link>https://dev.to/roshan_singh_dd54d52bbaa7/-important-react-interview-questions-every-developer-must-know-26fp</link>
      <guid>https://dev.to/roshan_singh_dd54d52bbaa7/-important-react-interview-questions-every-developer-must-know-26fp</guid>
      <description>&lt;p&gt;If you're preparing for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React interviews&lt;/li&gt;
&lt;li&gt;frontend roles&lt;/li&gt;
&lt;li&gt;full stack interviews&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;these are the &lt;strong&gt;most important React concepts&lt;/strong&gt; you should know.&lt;/p&gt;

&lt;p&gt;This guide covers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;core React fundamentals&lt;/li&gt;
&lt;li&gt;hooks&lt;/li&gt;
&lt;li&gt;rendering&lt;/li&gt;
&lt;li&gt;state management&lt;/li&gt;
&lt;li&gt;optimization concepts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;in a beginner-friendly way.&lt;/p&gt;




&lt;h1&gt;
  
  
  ✅ 1. What is Virtual DOM?
&lt;/h1&gt;

&lt;p&gt;The &lt;strong&gt;Virtual DOM&lt;/strong&gt; is a lightweight JavaScript copy of the real DOM.&lt;/p&gt;

&lt;p&gt;Instead of directly updating the browser DOM:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;React creates a new Virtual DOM&lt;/li&gt;
&lt;li&gt;compares it with the old one&lt;/li&gt;
&lt;li&gt;updates only changed parts in the real DOM&lt;/li&gt;
&lt;/ol&gt;

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

&lt;h1&gt;
  
  
  ⚡ Reconciliation / Diffing
&lt;/h1&gt;




&lt;h2&gt;
  
  
  ✅ Why is Virtual DOM Fast?
&lt;/h2&gt;

&lt;p&gt;Because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;comparing JavaScript objects is fast&lt;/li&gt;
&lt;li&gt;real DOM operations are expensive&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;React minimizes direct DOM manipulation.&lt;/p&gt;




&lt;h1&gt;
  
  
  ✅ 2. What is useState?
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;useState&lt;/code&gt; is a React Hook used for managing component state.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```jsx id="jlwmn"&lt;br&gt;
const [count, setCount] = useState(0);&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


* `count` → current state
* `setCount` → updates state

When state changes:

# React re-renders the component

---

# ✅ 3. What is useEffect?

`useEffect` handles:

* API calls
* timers
* subscriptions
* event listeners
* side effects



```jsx id="jlwmm"
useEffect(() =&amp;gt; {
  fetchData();
}, []);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ✅ Important Point
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;useEffect&lt;/code&gt; runs:&lt;/p&gt;
&lt;h1&gt;
  
  
  AFTER component render
&lt;/h1&gt;


&lt;h2&gt;
  
  
  ✅ Dependency Array
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dependency&lt;/th&gt;
&lt;th&gt;Behavior&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;No array&lt;/td&gt;
&lt;td&gt;Runs every render&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;[]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Runs once&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;[count]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Runs when count changes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h1&gt;
  
  
  ✅ 4. Props vs State
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Props&lt;/th&gt;
&lt;th&gt;State&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Passed from parent&lt;/td&gt;
&lt;td&gt;Managed inside component&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Read-only&lt;/td&gt;
&lt;td&gt;Mutable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Used for communication&lt;/td&gt;
&lt;td&gt;Used for dynamic data&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h1&gt;
  
  
  ✅ 5. What is Redux Toolkit?
&lt;/h1&gt;

&lt;p&gt;Redux Toolkit is used for:&lt;/p&gt;
&lt;h1&gt;
  
  
  Global State Management
&lt;/h1&gt;

&lt;p&gt;It helps avoid:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;prop drilling&lt;/li&gt;
&lt;li&gt;deeply nested state passing&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  ✅ Main Concepts
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Store&lt;/li&gt;
&lt;li&gt;Slice&lt;/li&gt;
&lt;li&gt;Reducer&lt;/li&gt;
&lt;li&gt;Dispatch&lt;/li&gt;
&lt;/ul&gt;


&lt;h1&gt;
  
  
  ✅ 6. What is RTK Query?
&lt;/h1&gt;

&lt;p&gt;RTK Query simplifies API integration in Redux Toolkit.&lt;/p&gt;

&lt;p&gt;It automatically handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;caching&lt;/li&gt;
&lt;li&gt;loading state&lt;/li&gt;
&lt;li&gt;errors&lt;/li&gt;
&lt;li&gt;refetching
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;```jsx id="jlwml"&lt;br&gt;
const { data } = useGetUsersQuery();&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


---

# ✅ 7. Component Lifecycle

React components have 3 lifecycle phases:

1. Mounting
2. Updating
3. Unmounting

Handled using `useEffect`.

---

## ✅ Mount Example



```jsx id="jlwmk"
useEffect(() =&amp;gt; {}, []);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ✅ Cleanup Example
&lt;/h2&gt;



&lt;p&gt;```jsx id="jlwmj"&lt;br&gt;
useEffect(() =&amp;gt; {&lt;br&gt;
  return () =&amp;gt; {&lt;br&gt;
    console.log("cleanup");&lt;br&gt;
  };&lt;br&gt;
}, []);&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


---

# ✅ 8. Controlled vs Uncontrolled Components

---

## ✅ Controlled Component

React controls input state.



```jsx id="jlwmi"
&amp;lt;input value={name} onChange={handleChange} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ✅ Uncontrolled Component
&lt;/h2&gt;

&lt;p&gt;DOM controls input using refs.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```jsx id="jlwmh"&lt;br&gt;
&lt;/p&gt;

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


---

# ✅ 9. What is useRef?

`useRef` stores mutable values without causing re-renders.

Commonly used for:

* DOM access
* focusing inputs
* timers
* previous values



```jsx id="jlwmg"
const inputRef = useRef();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  ✅ 10. API Integration in React
&lt;/h1&gt;

&lt;p&gt;Usually done using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;fetch&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;axios&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Inside &lt;code&gt;useEffect&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```jsx id="jlwmf"&lt;br&gt;
useEffect(() =&amp;gt; {&lt;br&gt;
  axios.get("/api/users");&lt;br&gt;
}, []);&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


---

# ✅ fetch vs axios

| fetch               | axios                  |
| ------------------- | ---------------------- |
| Built into browser  | External library       |
| Manual JSON parsing | Automatic JSON parsing |
| More boilerplate    | Cleaner syntax         |

---

# ✅ 11. What is Lifting State Up?

Lifting state up means:

# Moving shared state to the nearest common parent component.

Used when sibling components need same data.

---

# ✅ Example



```jsx id="jlwme"
&amp;lt;ChildA count={count} /&amp;gt;
&amp;lt;ChildB setCount={setCount} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  ✅ 12. What is Context API?
&lt;/h1&gt;

&lt;p&gt;Context API helps avoid:&lt;/p&gt;
&lt;h1&gt;
  
  
  Prop Drilling
&lt;/h1&gt;

&lt;p&gt;It allows components to access shared data directly.&lt;/p&gt;


&lt;h2&gt;
  
  
  ✅ Example
&lt;/h2&gt;



&lt;p&gt;```jsx id="jlwmd"&lt;br&gt;
const user = useContext(UserContext);&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


---

# ✅ 13. What is React.memo?

`React.memo` prevents unnecessary component re-renders.

It uses:

# Shallow Prop Comparison



```jsx id="jlwmc"
export default React.memo(Child);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  ✅ 14. What is useMemo?
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;useMemo&lt;/code&gt; memoizes expensive calculations or values.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```jsx id="jlwmb"&lt;br&gt;
const value = useMemo(() =&amp;gt; calculate(), [dep]);&lt;/p&gt;

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


Recalculates only when dependencies change.

---

# ✅ 15. What is useCallback?

`useCallback` memoizes function references.



```jsx id="jlwma"
const handleClick = useCallback(() =&amp;gt; {}, []);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Helps prevent unnecessary child re-renders.&lt;/p&gt;




&lt;h1&gt;
  
  
  🔥 Most Important React Optimization Concept
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;React.memo&lt;/code&gt; alone is often NOT enough.&lt;/p&gt;

&lt;p&gt;Because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;functions&lt;/li&gt;
&lt;li&gt;arrays&lt;/li&gt;
&lt;li&gt;objects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;create new references every render.&lt;/p&gt;

&lt;p&gt;So:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;useCallback&lt;/code&gt; preserves function reference&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;useMemo&lt;/code&gt; preserves value reference&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h1&gt;
  
  
  ✅ React.memo work effectively
&lt;/h1&gt;




&lt;h1&gt;
  
  
  📊 Difference Between React.memo, useMemo, useCallback
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;React.memo&lt;/th&gt;
&lt;th&gt;useMemo&lt;/th&gt;
&lt;th&gt;useCallback&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Used For&lt;/td&gt;
&lt;td&gt;Component&lt;/td&gt;
&lt;td&gt;Value&lt;/td&gt;
&lt;td&gt;Function&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prevents&lt;/td&gt;
&lt;td&gt;Re-render&lt;/td&gt;
&lt;td&gt;Recalculation&lt;/td&gt;
&lt;td&gt;Function recreation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h1&gt;
  
  
  🎯 Final Interview Tips
&lt;/h1&gt;

&lt;p&gt;For React interviews:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;focus on concepts&lt;/li&gt;
&lt;li&gt;understand rendering&lt;/li&gt;
&lt;li&gt;know how hooks work internally&lt;/li&gt;
&lt;li&gt;explain WHY optimizations are needed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most interviewers care more about:&lt;/p&gt;

&lt;h1&gt;
  
  
  understanding
&lt;/h1&gt;

&lt;p&gt;than memorizing syntax.&lt;/p&gt;




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

&lt;p&gt;React becomes much easier once you understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;rendering&lt;/li&gt;
&lt;li&gt;component lifecycle&lt;/li&gt;
&lt;li&gt;state management&lt;/li&gt;
&lt;li&gt;memoization&lt;/li&gt;
&lt;li&gt;re-renders&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Master these concepts properly and you’ll already know most of the important React interview topics.&lt;/p&gt;

</description>
      <category>interview</category>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>React.memo vs useMemo vs useCallback — Complete Guide</title>
      <dc:creator>Roshan singh</dc:creator>
      <pubDate>Fri, 08 May 2026 06:25:26 +0000</pubDate>
      <link>https://dev.to/roshan_singh_dd54d52bbaa7/reactmemo-vs-usememo-vs-usecallback-complete-guide-5cdh</link>
      <guid>https://dev.to/roshan_singh_dd54d52bbaa7/reactmemo-vs-usememo-vs-usecallback-complete-guide-5cdh</guid>
      <description>&lt;p&gt;If you're learning React, you've probably heard these terms everywhere:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;React.memo&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;useMemo&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;useCallback&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At first, they look confusing.&lt;/p&gt;

&lt;p&gt;But all three solve &lt;strong&gt;one major problem&lt;/strong&gt;:&lt;/p&gt;

&lt;h1&gt;
  
  
  ⚡ &lt;strong&gt;Unnecessary Re-renders &amp;amp; Performance Issues&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;This guide explains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what each one does&lt;/li&gt;
&lt;li&gt;why they exist&lt;/li&gt;
&lt;li&gt;how they are connected&lt;/li&gt;
&lt;li&gt;when to use them&lt;/li&gt;
&lt;li&gt;interview explanations&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  🤔 &lt;strong&gt;Why Do These Exist?&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;In React, components re-render very frequently.&lt;/p&gt;

&lt;p&gt;A component re-renders when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;state changes&lt;/li&gt;
&lt;li&gt;props change&lt;/li&gt;
&lt;li&gt;parent component re-renders&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most of the time this is fine.&lt;/p&gt;

&lt;p&gt;But in large applications:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;expensive calculations&lt;/li&gt;
&lt;li&gt;recreated functions&lt;/li&gt;
&lt;li&gt;unnecessary child renders&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;can slow down the application.&lt;/p&gt;

&lt;p&gt;That’s why React provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;React.memo&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;useMemo&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;useCallback&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;for optimization.&lt;/p&gt;




&lt;h1&gt;
  
  
  🧠 &lt;strong&gt;First Understand One Important Thing&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;In React:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Rendered&lt;/span&gt;&lt;span class="dl"&gt;"&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Hello&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&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;Whenever React re-renders:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the &lt;strong&gt;ENTIRE component function runs again&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;variables get recreated&lt;/li&gt;
&lt;li&gt;functions get recreated&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the root reason why memoization exists.&lt;/p&gt;




&lt;h1&gt;
  
  
  1️⃣ &lt;strong&gt;React.memo&lt;/strong&gt;
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ✅ &lt;strong&gt;What is React.memo?&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;React.memo&lt;/code&gt; prevents unnecessary component re-renders.&lt;/p&gt;




&lt;h1&gt;
  
  
  ❌ &lt;strong&gt;Problem Without React.memo&lt;/strong&gt;
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Child&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Child rendered&lt;/span&gt;&lt;span class="dl"&gt;"&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Child Component&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Parent&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;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&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="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&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="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        Increment
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Child&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;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;h1&gt;
  
  
  🔍 &lt;strong&gt;What Happens Here?&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;When button is clicked:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Parent re-renders&lt;/li&gt;
&lt;li&gt;Child ALSO re-renders&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even though:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Child props didn't change&lt;/li&gt;
&lt;li&gt;Child state didn't change&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;❌ &lt;strong&gt;This is an unnecessary re-render.&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  ✅ &lt;strong&gt;Solution Using React.memo&lt;/strong&gt;
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Child&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;memo&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Child rendered&lt;/span&gt;&lt;span class="dl"&gt;"&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Child Component&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&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;Now React remembers the previous render.&lt;/p&gt;

&lt;p&gt;If props are unchanged:&lt;/p&gt;

&lt;h1&gt;
  
  
  ✅ &lt;strong&gt;Child render is skipped&lt;/strong&gt;
&lt;/h1&gt;




&lt;h1&gt;
  
  
  ⚙️ &lt;strong&gt;How React.memo Works Internally&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;React performs:&lt;/p&gt;

&lt;h1&gt;
  
  
  👉 &lt;strong&gt;Shallow Comparison&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;It compares:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;old props&lt;/li&gt;
&lt;li&gt;new props&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If props are same:&lt;br&gt;
✅ React skips rendering.&lt;/p&gt;


&lt;h1&gt;
  
  
  📌 &lt;strong&gt;Important Point&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;React.memo&lt;/code&gt; works best with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;strings&lt;/li&gt;
&lt;li&gt;numbers&lt;/li&gt;
&lt;li&gt;booleans&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But NOT always with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;functions&lt;/li&gt;
&lt;li&gt;arrays&lt;/li&gt;
&lt;li&gt;objects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because they create new references every render.&lt;/p&gt;

&lt;p&gt;That’s where &lt;code&gt;useCallback&lt;/code&gt; and &lt;code&gt;useMemo&lt;/code&gt; help.&lt;/p&gt;


&lt;h1&gt;
  
  
  2️⃣ &lt;strong&gt;useCallback&lt;/strong&gt;
&lt;/h1&gt;
&lt;h1&gt;
  
  
  ✅ &lt;strong&gt;What is useCallback?&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;useCallback&lt;/code&gt; memoizes functions.&lt;/p&gt;

&lt;p&gt;It prevents function recreation on every render.&lt;/p&gt;


&lt;h1&gt;
  
  
  ❌ &lt;strong&gt;Problem Without useCallback&lt;/strong&gt;
&lt;/h1&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Parent&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;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&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;handleClick&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Clicked&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Child&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&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;Looks normal, right?&lt;/p&gt;

&lt;p&gt;But here's the hidden issue:&lt;/p&gt;
&lt;h1&gt;
  
  
  🚨 &lt;strong&gt;A NEW function gets created on every render&lt;/strong&gt;
&lt;/h1&gt;


&lt;h1&gt;
  
  
  🤯 &lt;strong&gt;Why?&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Because in JavaScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;a&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;b&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;both functions have different memory references&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  🚨 &lt;strong&gt;Why This Causes Re-renders&lt;/strong&gt;
&lt;/h1&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Child&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;memo&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Child rendered&lt;/span&gt;&lt;span class="dl"&gt;"&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Click&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&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;Even with &lt;code&gt;React.memo&lt;/code&gt;,&lt;br&gt;
Child STILL re-renders because:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;oldFunction&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;newFunction&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;React thinks:&lt;/p&gt;

&lt;h1&gt;
  
  
  ❌ &lt;strong&gt;Prop changed&lt;/strong&gt;
&lt;/h1&gt;




&lt;h1&gt;
  
  
  ✅ &lt;strong&gt;Solution Using useCallback&lt;/strong&gt;
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleClick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Clicked&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now React stores:&lt;/p&gt;

&lt;h1&gt;
  
  
  ✅ &lt;strong&gt;SAME function reference&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;between renders.&lt;/p&gt;

&lt;p&gt;So:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Child gets same prop&lt;/li&gt;
&lt;li&gt;React.memo works properly&lt;/li&gt;
&lt;li&gt;unnecessary render avoided&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  🧠 &lt;strong&gt;Behind The Scenes&lt;/strong&gt;
&lt;/h1&gt;

&lt;h2&gt;
  
  
  ❌ &lt;strong&gt;Without useCallback&lt;/strong&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Render&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;
&lt;span class="nf"&gt;Render&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;
&lt;span class="nf"&gt;Render&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ✅ &lt;strong&gt;With useCallback&lt;/strong&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Render&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nx"&gt;create&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;
&lt;span class="nf"&gt;Render&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nx"&gt;reuse&lt;/span&gt; &lt;span class="nx"&gt;same&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;
&lt;span class="nf"&gt;Render&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nx"&gt;reuse&lt;/span&gt; &lt;span class="nx"&gt;same&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  3️⃣ &lt;strong&gt;useMemo&lt;/strong&gt;
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ✅ &lt;strong&gt;What is useMemo?&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;useMemo&lt;/code&gt; memoizes values or expensive calculations.&lt;/p&gt;




&lt;h1&gt;
  
  
  ❌ &lt;strong&gt;Problem Without useMemo&lt;/strong&gt;
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filteredUsers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;active&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;h1&gt;
  
  
  🚨 &lt;strong&gt;On EVERY render&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Even when unrelated state changes.&lt;/p&gt;




&lt;h1&gt;
  
  
  🤯 &lt;strong&gt;Example&lt;/strong&gt;
&lt;/h1&gt;

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

&lt;ul&gt;
&lt;li&gt;theme changes&lt;/li&gt;
&lt;li&gt;modal opens&lt;/li&gt;
&lt;li&gt;input typing happens&lt;/li&gt;
&lt;/ul&gt;

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

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

&lt;/div&gt;



&lt;p&gt;runs again.&lt;/p&gt;

&lt;p&gt;For large data:&lt;br&gt;
❌ performance issue.&lt;/p&gt;


&lt;h1&gt;
  
  
  ✅ &lt;strong&gt;Solution Using useMemo&lt;/strong&gt;
&lt;/h1&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filteredUsers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMemo&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;active&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;users&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now calculation runs ONLY when:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;users&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;changes.&lt;/p&gt;




&lt;h1&gt;
  
  
  ⚙️ &lt;strong&gt;How useMemo Works Internally&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;React stores:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;previous dependencies&lt;/li&gt;
&lt;li&gt;previous calculated value&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If dependencies don't change:&lt;/p&gt;

&lt;h1&gt;
  
  
  ✅ &lt;strong&gt;Cached value is returned&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;No recalculation happens.&lt;/p&gt;




&lt;h1&gt;
  
  
  🔥 &lt;strong&gt;MOST IMPORTANT — How All Three Are Connected&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;This is where most beginners get confused.&lt;/p&gt;




&lt;h1&gt;
  
  
  ❌ &lt;strong&gt;React.memo Alone Is NOT Enough&lt;/strong&gt;
&lt;/h1&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Child&lt;/span&gt;
  &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;filteredUsers&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even with &lt;code&gt;React.memo&lt;/code&gt;,&lt;br&gt;
Child may STILL re-render because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;handleClick&lt;/code&gt; creates new function&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;filteredUsers&lt;/code&gt; creates new array/object&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;React sees:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;oldProp&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;newProp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;because references changed.&lt;/p&gt;




&lt;h1&gt;
  
  
  ✅ &lt;strong&gt;That’s Why We Need:&lt;/strong&gt;
&lt;/h1&gt;

&lt;h2&gt;
  
  
  👉 &lt;strong&gt;useCallback&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;to preserve function reference&lt;/p&gt;

&lt;p&gt;AND&lt;/p&gt;

&lt;h2&gt;
  
  
  👉 &lt;strong&gt;useMemo&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;to preserve value/object/array reference&lt;/p&gt;

&lt;p&gt;So that:&lt;/p&gt;

&lt;h1&gt;
  
  
  ✅ &lt;strong&gt;React.memo can ACTUALLY skip rendering&lt;/strong&gt;
&lt;/h1&gt;




&lt;h1&gt;
  
  
  🧩 &lt;strong&gt;Simple Mental Model&lt;/strong&gt;
&lt;/h1&gt;

&lt;h2&gt;
  
  
  ✅ &lt;strong&gt;React.memo&lt;/strong&gt;
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“Skip component render if props are same.”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ✅ &lt;strong&gt;useCallback&lt;/strong&gt;
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“Keep same function reference.”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ✅ &lt;strong&gt;useMemo&lt;/strong&gt;
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“Keep same calculated value/reference.”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  📊 &lt;strong&gt;Final Difference Between All Three&lt;/strong&gt;
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;React.memo&lt;/th&gt;
&lt;th&gt;useMemo&lt;/th&gt;
&lt;th&gt;useCallback&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Used For&lt;/td&gt;
&lt;td&gt;Component&lt;/td&gt;
&lt;td&gt;Value&lt;/td&gt;
&lt;td&gt;Function&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prevents&lt;/td&gt;
&lt;td&gt;Re-render&lt;/td&gt;
&lt;td&gt;Recalculation&lt;/td&gt;
&lt;td&gt;Function recreation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Returns&lt;/td&gt;
&lt;td&gt;Memoized component&lt;/td&gt;
&lt;td&gt;Memoized value&lt;/td&gt;
&lt;td&gt;Memoized function&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Common Use&lt;/td&gt;
&lt;td&gt;Child optimization&lt;/td&gt;
&lt;td&gt;Expensive calculations&lt;/td&gt;
&lt;td&gt;Stable callbacks&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h1&gt;
  
  
  🚫 &lt;strong&gt;When NOT To Use Them&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Do NOT overuse memoization.&lt;/p&gt;

&lt;p&gt;These hooks also have overhead.&lt;/p&gt;

&lt;p&gt;Use them only when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;unnecessary renders are causing issues&lt;/li&gt;
&lt;li&gt;calculations are expensive&lt;/li&gt;
&lt;li&gt;components are large/heavy&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  🎯 &lt;strong&gt;Interview Summary&lt;/strong&gt;
&lt;/h1&gt;

&lt;h2&gt;
  
  
  ✅ &lt;strong&gt;React.memo&lt;/strong&gt;
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Prevents unnecessary component re-renders using shallow prop comparison.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ✅ &lt;strong&gt;useMemo&lt;/strong&gt;
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Memoizes calculated values and recalculates only when dependencies change.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ✅ &lt;strong&gt;useCallback&lt;/strong&gt;
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Memoizes function references to prevent unnecessary function recreation and child re-renders.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  🏁 &lt;strong&gt;Final Thoughts&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Most developers memorize:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;syntax&lt;/li&gt;
&lt;li&gt;definitions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But the REAL understanding is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;React.memo&lt;/code&gt; depends on stable references.&lt;br&gt;
&lt;code&gt;useMemo&lt;/code&gt; and &lt;code&gt;useCallback&lt;/code&gt; help maintain those stable references.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once this connection clicks, React rendering behavior becomes much easier to understand.&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>performance</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>Scaling Redis in Distributed Systems: From Local Cache Problems to Redis Cluster</title>
      <dc:creator>Roshan singh</dc:creator>
      <pubDate>Wed, 06 May 2026 12:04:05 +0000</pubDate>
      <link>https://dev.to/roshan_singh_dd54d52bbaa7/scaling-redis-in-distributed-systems-from-local-cache-problems-to-redis-cluster-37if</link>
      <guid>https://dev.to/roshan_singh_dd54d52bbaa7/scaling-redis-in-distributed-systems-from-local-cache-problems-to-redis-cluster-37if</guid>
      <description>&lt;p&gt;**When building scalable backend systems, one common question arises:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“If we scale our application using multiple instances, how should caching work?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This becomes especially important when using Redis in distributed architectures.&lt;/p&gt;

&lt;p&gt;Let’s understand the problem step by step and then move toward advanced scaling concepts like &lt;strong&gt;sharding&lt;/strong&gt; and &lt;strong&gt;replication&lt;/strong&gt;.**&lt;/p&gt;




&lt;h1&gt;
  
  
  🚨 The Problem with Local Redis per Instance
&lt;/h1&gt;

&lt;p&gt;Suppose we scale our backend application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Load Balancer
     ↓
 ┌───────────┐
 │ Instance1 │
 └───────────┘
       │
   Local Redis 1

 ┌───────────┐
 │ Instance2 │
 └───────────┘
       │
   Local Redis 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first glance, this looks fine.&lt;/p&gt;

&lt;p&gt;But here’s the issue.&lt;/p&gt;

&lt;p&gt;Imagine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User data gets updated through &lt;strong&gt;Instance 2&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Local Redis 2 gets updated&lt;/li&gt;
&lt;li&gt;Local Redis 1 still contains old cached data&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Requests routed to Instance 1 return stale data&lt;/li&gt;
&lt;li&gt;Requests routed to Instance 2 return fresh data&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Cache inconsistency&lt;/li&gt;
&lt;li&gt;Synchronization complexity&lt;/li&gt;
&lt;li&gt;Stale reads&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  ❌ Why Syncing Local Redis is Difficult
&lt;/h1&gt;

&lt;p&gt;To keep multiple local Redis caches synchronized, we need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pub/Sub systems&lt;/li&gt;
&lt;li&gt;Event broadcasting&lt;/li&gt;
&lt;li&gt;Cache invalidation messaging&lt;/li&gt;
&lt;li&gt;Distributed coordination&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This becomes very complex at scale.&lt;/p&gt;

&lt;p&gt;That’s why production systems usually avoid separate Redis instances per application server.&lt;/p&gt;




&lt;h1&gt;
  
  
  ✅ The Correct Approach: Centralized Redis
&lt;/h1&gt;

&lt;p&gt;Instead of separate caches, all backend instances use a &lt;strong&gt;shared Redis layer&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                        ┌─────────────────┐
Client → Load Balancer  → App Instances
                        └─────────────────┘
                              ↓
                     Shared Redis Cluster
                              ↓
                         PostgreSQL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;All instances read/write from the same Redis&lt;/li&gt;
&lt;li&gt;Any update becomes immediately visible everywhere&lt;/li&gt;
&lt;li&gt;No synchronization problem&lt;/li&gt;
&lt;/ul&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;updateUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;del&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`user:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the cache is invalidated:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Any instance fetching the data gets the latest value&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This architecture is simple, scalable, and production-friendly.&lt;/p&gt;




&lt;h1&gt;
  
  
  🤔 But What Happens When Redis Itself Needs Scaling?
&lt;/h1&gt;

&lt;p&gt;A single Redis server has limitations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Limited memory&lt;/li&gt;
&lt;li&gt;Limited CPU&lt;/li&gt;
&lt;li&gt;Single point of failure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For very large systems, we need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Horizontal scaling&lt;/li&gt;
&lt;li&gt;Fault tolerance&lt;/li&gt;
&lt;li&gt;High availability&lt;/li&gt;
&lt;/ul&gt;

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




&lt;h1&gt;
  
  
  🔥 Redis Cluster
&lt;/h1&gt;

&lt;p&gt;A Redis Cluster distributes data across multiple Redis nodes.&lt;/p&gt;

&lt;p&gt;It uses two important concepts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sharding&lt;/li&gt;
&lt;li&gt;Replication&lt;/li&gt;
&lt;/ol&gt;




&lt;h1&gt;
  
  
  1️⃣ Sharding — Scaling Redis Horizontally
&lt;/h1&gt;

&lt;h2&gt;
  
  
  What is Sharding?
&lt;/h2&gt;

&lt;p&gt;Sharding means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Splitting data across multiple Redis nodes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead of storing all data in one Redis server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Redis Node 1
→ All users
→ All movies
→ All bookings
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Redis distributes keys across multiple nodes.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user:101    → Node 1
movie:201   → Node 2
booking:301 → Node 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Important:&lt;br&gt;
Redis does NOT shard by entity type.&lt;/p&gt;

&lt;p&gt;It shards based on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hash calculation of keys&lt;/li&gt;
&lt;/ul&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HASH(key) % 16384 = slot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each node owns a range of hash slots.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Node 1 → Slots 0–5000
Node 2 → Slots 5001–10000
Node 3 → Slots 10001–16383
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  ✅ Why Sharding is Important
&lt;/h1&gt;

&lt;p&gt;Sharding helps with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Memory scaling&lt;/li&gt;
&lt;li&gt;Traffic distribution&lt;/li&gt;
&lt;li&gt;Better performance&lt;/li&gt;
&lt;li&gt;Horizontal scalability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without sharding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One Redis server becomes overloaded&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  2️⃣ Replication — High Availability &amp;amp; Failover
&lt;/h1&gt;

&lt;h2&gt;
  
  
  What is Replication?
&lt;/h2&gt;

&lt;p&gt;Replication means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Creating copies of Redis data on replica nodes.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Master 1 → Replica 1
Master 2 → Replica 2
Master 3 → Replica 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Master 2 crashes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Redis automatically promotes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Replica 2 → New Master
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;Automatic failover&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  ✅ Why Replication is Needed
&lt;/h1&gt;

&lt;p&gt;Sharding distributes data,&lt;br&gt;
but it does NOT protect against node failure.&lt;/p&gt;

&lt;p&gt;Without replication:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If a node crashes,&lt;/li&gt;
&lt;li&gt;Data on that shard becomes unavailable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Replication provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;High availability&lt;/li&gt;
&lt;li&gt;Fault tolerance&lt;/li&gt;
&lt;li&gt;Backup copies&lt;/li&gt;
&lt;li&gt;Reduced downtime&lt;/li&gt;
&lt;/ul&gt;


&lt;h1&gt;
  
  
  ⚔️ Sharding vs Replication
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Sharding&lt;/th&gt;
&lt;th&gt;Replication&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Purpose&lt;/td&gt;
&lt;td&gt;Scalability&lt;/td&gt;
&lt;td&gt;High Availability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data&lt;/td&gt;
&lt;td&gt;Split&lt;/td&gt;
&lt;td&gt;Copied&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Increases Memory Capacity&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Handles Node Failure&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Improves Performance&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h1&gt;
  
  
  🏗️ Final Production Architecture
&lt;/h1&gt;

&lt;p&gt;Production systems usually combine both:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                Redis Cluster

Master 1 → Replica 1
Master 2 → Replica 2
Master 3 → Replica 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Masters handle sharded data&lt;/li&gt;
&lt;li&gt;Replicas provide failover protection&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  🎯 Final Thoughts
&lt;/h1&gt;

&lt;p&gt;When scaling distributed systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Avoid local Redis per instance&lt;/li&gt;
&lt;li&gt;Use centralized Redis&lt;/li&gt;
&lt;li&gt;Scale Redis using sharding&lt;/li&gt;
&lt;li&gt;Ensure reliability using replication&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This architecture helps achieve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Low latency&lt;/li&gt;
&lt;li&gt;High scalability&lt;/li&gt;
&lt;li&gt;High availability&lt;/li&gt;
&lt;li&gt;Fault tolerance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Which is exactly what modern distributed systems require.&lt;/p&gt;

</description>
      <category>redis</category>
      <category>systemdesign</category>
      <category>backend</category>
      <category>distributedsystems</category>
    </item>
    <item>
      <title># How to Build a Complete CI/CD Pipeline with GitHub Actions and Docker Hub</title>
      <dc:creator>Roshan singh</dc:creator>
      <pubDate>Wed, 25 Mar 2026 07:16:44 +0000</pubDate>
      <link>https://dev.to/roshan_singh_dd54d52bbaa7/-how-to-build-a-complete-cicd-pipeline-with-github-actions-and-docker-hub-1dda</link>
      <guid>https://dev.to/roshan_singh_dd54d52bbaa7/-how-to-build-a-complete-cicd-pipeline-with-github-actions-and-docker-hub-1dda</guid>
      <description>&lt;p&gt;&lt;strong&gt;## Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this tutorial, I'll show you how to set up a complete CI/CD pipeline that automatically builds Docker images, pushes them to Docker Hub, and deploys your application to a production server - all triggered by a simple git push!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;## What You'll Learn&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setting up GitHub Actions for automated builds&lt;/li&gt;
&lt;li&gt;Building and pushing Docker images to Docker Hub&lt;/li&gt;
&lt;li&gt;Deploying containerized applications to a remote server&lt;/li&gt;
&lt;li&gt;Version tagging with Git commit SHAs&lt;/li&gt;
&lt;li&gt;Zero-downtime deployments with Docker Compose&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;## Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before we start, make sure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A GitHub repository with your application code&lt;/li&gt;
&lt;li&gt;A Docker Hub account&lt;/li&gt;
&lt;li&gt;A remote server (VPS/Cloud VM) with Docker and Docker Compose installed&lt;/li&gt;
&lt;li&gt;SSH access to your server&lt;/li&gt;
&lt;li&gt;Basic understanding of Docker and Docker Compose&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;## Architecture Overview&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Our CI/CD pipeline consists of two main jobs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Build &amp;amp; Push&lt;/strong&gt;: Build Docker images and push them to Docker Hub&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deploy&lt;/strong&gt;: Pull the new images on the server and restart containers
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Git Push → GitHub Actions → Build Images → Docker Hub → Deploy to Server → Live!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;## Step 1: Project Structure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here's what your project structure should look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;your-project/
├── .github/
│   └── workflows/
│       └── deploy.yml          # CI/CD workflow
├── backend/
│   ├── Dockerfile              # Backend Docker image
│   └── ... (your backend code)
├── frontend/
│   ├── Dockerfile              # Frontend Docker image
│   └── ... (your frontend code)
├── docker-compose.prod.yml     # Production deployment config
└── nginx.conf                  # Nginx configuration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;## Step 2: Create Dockerfiles&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;### Backend Dockerfile Example&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# backend/Dockerfile&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:18-alpine&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package*.json ./&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm ci &lt;span class="nt"&gt;--only&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 5000&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["node", "server.js"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;*&lt;em&gt;### Frontend Dockerfile Example&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# frontend/Dockerfile&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;node:18-alpine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package*.json ./&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm ci

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm run build

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; nginx:alpine&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build /app/dist /usr/share/nginx/html&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; nginx.conf /etc/nginx/conf.d/default.conf&lt;/span&gt;

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 80&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["nginx", "-g", "daemon off;"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
yaml&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;## Step 3: Create Docker Compose Production File&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# docker-compose.prod.yml&lt;/span&gt;
&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.8'&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;backend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yourdockerhub/crm-backend:${CRM_BACKEND_TAG:-latest}&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;crm-backend&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;NODE_ENV=production&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;DATABASE_URL=${DATABASE_URL}&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;5000:5000"&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;app-network&lt;/span&gt;

  &lt;span class="na"&gt;frontend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yourdockerhub/crm-frontend:${CRM_FRONTEND_TAG:-latest}&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;crm-frontend&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3000:80"&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;backend&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;app-network&lt;/span&gt;

  &lt;span class="na"&gt;nginx&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx:alpine&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx-proxy&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;80:80"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;443:443"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./nginx.conf:/etc/nginx/nginx.conf:ro&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;frontend&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;backend&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;app-network&lt;/span&gt;

&lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app-network&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;driver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bridge&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;## Step 4: Create GitHub Actions Workflow&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create &lt;code&gt;.github/workflows/deploy.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build and Deploy to Production&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build-and-push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build and push Docker images&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout repository&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Log in to Docker Hub&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker/login-action@v3&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.DOCKERHUB_USERNAME }}&lt;/span&gt;
          &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.DOCKERHUB_TOKEN }}&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Generate image tags&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tag&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;echo "full=${GITHUB_SHA}" &amp;gt;&amp;gt; "$GITHUB_OUTPUT"&lt;/span&gt;
          &lt;span class="s"&gt;echo "short=${GITHUB_SHA:0:7}" &amp;gt;&amp;gt; "$GITHUB_OUTPUT"&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build and push backend image&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker/build-push-action@v5&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./backend&lt;/span&gt;
          &lt;span class="na"&gt;file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./backend/Dockerfile&lt;/span&gt;
          &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
          &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;yourdockerhub/crm-backend:latest&lt;/span&gt;
            &lt;span class="s"&gt;yourdockerhub/crm-backend:${{ steps.tag.outputs.full }}&lt;/span&gt;
            &lt;span class="s"&gt;yourdockerhub/crm-backend:${{ steps.tag.outputs.short }}&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build and push frontend image&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker/build-push-action@v5&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./frontend&lt;/span&gt;
          &lt;span class="na"&gt;file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./frontend/Dockerfile&lt;/span&gt;
          &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
          &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;yourdockerhub/crm-frontend:latest&lt;/span&gt;
            &lt;span class="s"&gt;yourdockerhub/crm-frontend:${{ steps.tag.outputs.full }}&lt;/span&gt;
            &lt;span class="s"&gt;yourdockerhub/crm-frontend:${{ steps.tag.outputs.short }}&lt;/span&gt;

  &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to production server&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;build-and-push&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout repository&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Copy configuration files to server&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;appleboy/scp-action@v0.1.7&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.SSH_HOST }}&lt;/span&gt;
          &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.SSH_USER }}&lt;/span&gt;
          &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.SSH_KEY }}&lt;/span&gt;
          &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;docker-compose.prod.yml,nginx.conf"&lt;/span&gt;
          &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;~/crm-app"&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy application&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;appleboy/ssh-action@v1.0.0&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.SSH_HOST }}&lt;/span&gt;
          &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.SSH_USER }}&lt;/span&gt;
          &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.SSH_KEY }}&lt;/span&gt;
          &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;cd ~/crm-app&lt;/span&gt;
            &lt;span class="s"&gt;TAG="${{ github.sha }}"&lt;/span&gt;

            &lt;span class="s"&gt;# Clean up old images&lt;/span&gt;
            &lt;span class="s"&gt;sudo docker image prune -a -f&lt;/span&gt;

            &lt;span class="s"&gt;# Pull new images&lt;/span&gt;
            &lt;span class="s"&gt;sudo docker compose -f docker-compose.prod.yml pull backend frontend&lt;/span&gt;

            &lt;span class="s"&gt;# Recreate containers with new images&lt;/span&gt;
            &lt;span class="s"&gt;sudo CRM_BACKEND_TAG="$TAG" CRM_FRONTEND_TAG="$TAG" \&lt;/span&gt;
              &lt;span class="s"&gt;docker compose -f docker-compose.prod.yml up -d \&lt;/span&gt;
              &lt;span class="s"&gt;--force-recreate --no-deps backend frontend&lt;/span&gt;

            &lt;span class="s"&gt;# Restart nginx&lt;/span&gt;
            &lt;span class="s"&gt;sudo docker compose -f docker-compose.prod.yml restart nginx&lt;/span&gt;

            &lt;span class="s"&gt;# Final cleanup&lt;/span&gt;
            &lt;span class="s"&gt;sudo docker image prune -a -f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;## Step 5: Configure GitHub Secrets&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Go to your GitHub repository → Settings → Secrets and variables → Actions&lt;/p&gt;

&lt;p&gt;Add the following secrets:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;DOCKERHUB_USERNAME&lt;/strong&gt;: Your Docker Hub username&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DOCKERHUB_TOKEN&lt;/strong&gt;: Docker Hub access token&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSH_HOST&lt;/strong&gt;: Your server IP address or domain&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSH_USER&lt;/strong&gt;: SSH username&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSH_KEY&lt;/strong&gt;: Your private SSH key&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;## Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You now have a fully automated CI/CD pipeline! Every push to main will automatically build, test, and deploy your application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tags&lt;/strong&gt;: #docker #cicd #githubactions #devops #automation&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Questions? Drop them in the comments below! 👇&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>automation</category>
      <category>productivity</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
