Skip to main content

Command Palette

Search for a command to run...

SSR vs SSG vs ISR — Part 0: Same Same But Different

What Actually Happens — delivering HTML.

Published
3 min read
SSR vs SSG vs ISR —  Part 0: Same Same But Different

This Is Not Another Definition Post

I’ve read the official documentation.
I’ve read blog posts.
I’ve seen the diagrams:

  • SSR → renders on every request

  • SSG → renders at build time

  • ISR → static but revalidates

I understood the definitions.

But I still had confusion.

Not about what they are called —
but about how they actually work and when to choose one over the other.

Questions like:

  • Why exactly does SSR increase TTFB?

  • Why does SSG feel instant?

  • What is ISR really doing behind the scenes?

  • What does Next.js use by default?

Instead of reading more explanations, I decided to observe the behaviour directly.

So I built a small controlled experiment.

Link to Repository

What This Project Actually Is

This repository is not a real application.

It is a simple demo web app designed to demonstrate the differences between SSR, SSG, and ISR in a measurable way.

Each route in the project:

  • Simulates an 800ms data fetch

  • Displays a Generated At timestamp

  • Uses exactly one rendering strategy

Everything else remains constant.

  • Same UI

  • Same data

  • Same artificial delay

The only variable that changes is the rendering model.

This allows us to observe the impact of each strategy purely at the network and execution level.

For the best understanding, I recommend cloning the repository and running it locally.
If you prefer not to, I will include screenshots throughout the series so you can still follow the analysis.

What We Are Actually Comparing

We are not comparing APIs.

We are not comparing router styles.

We are comparing one fundamental question:

When is the HTML generated?

That is the only axis that truly matters.

Strategy When HTML Is Generated
SSR At request time
SSG At build time
ISR At build time + background regeneration

Everything else — performance, freshness, scalability — flows from that decision.

For deeper clarity, the examples in this project are implemented using both the Pages Router and the App Router.
This helps separate rendering strategy from router implementation details.

How to Explore the Repository

To properly understand what is happening, do not just read the code.

Open DevTools.

For each route:

  1. Go to Network

  2. Filter by Doc

  3. Click the document request

  4. Open the Timing tab

Observe:

  • Waiting for server response (TTFB)

  • Content download time

  • Total request duration

  • Timestamp behaviour across refreshes

Do not rely only on the UI output.

Observe the network waterfall.

That is where the execution model becomes clear.

The Structure of This Series

We will start from the definition level and progressively go deeper.

This series is divided into three focused parts.

Part 1 — The Request (SSR)

We will analyze:

  • Why every refresh costs ~800ms

  • Why TTFB increases

  • What “render per request” truly means

  • What the Network tab reveals about server blocking

Part 2 — The Build (SSG & ISR)

We will examine:

  • Why SSG appears instant

  • Why development mode can mislead you

  • How ISR regeneration actually works

  • What happens after the revalidation window expires

Part 3 — The Hybrid Reality

Finally, we connect everything to real-world architecture:

  • Why most production apps use hybrid rendering

  • Why confusion happens in real projects

  • How to choose the correct strategy intentionally