getStaticProps vs. getServerSideProps in Next.js

In Brief
In the Next.js Pages Router, getStaticProps prepares shared page data at build time or during revalidation, whilst getServerSideProps runs for every request and can use request‑specific context. Prefer static generation when the same result can be reused; choose server‑side rendering when freshness, authentication or request data genuinely requires it. Neither API applies to the App Router.
Once Next.js made page rendering strategies more explicit, one of the next practical questions became:
Which data‑fetching function should this page use?
For many Pages Router applications, that decision comes down to two familiar names:
getStaticPropsgetServerSideProps
They can look similar on the surface because both provide props to a page. But the timing of when they run changes the behaviour of the page quite significantly.
getStaticProps prepares reusable static output
getStaticProps normally runs during the build. Dynamic routes using getStaticPaths with fallback: true can also generate a missing page after a request. Next.js 9.4 introduced background revalidation as a beta feature, so the function is not necessarily limited to one build‑time call.
Here is a simple TypeScript/TSX page that uses the build‑time case:
import React from 'react';
import type { ReactElement } from 'react';
import type { GetStaticProps } from 'next';
type HomePageProps = {
message: string;
};
export const getStaticProps: GetStaticProps<HomePageProps> = async () => {
return {
props: {
message: 'Hello from build time',
},
};
};
const HomePage = ({ message }: HomePageProps): ReactElement => {
return <h1>{message}</h1>;
};
export default HomePage;This example prepares its message during the build. On‑demand generation and revalidation are additional policies to configure when the page needs them.
getServerSideProps runs on every request
If a page exports getServerSideProps, Next.js runs that function when the request arrives:
import React from 'react';
import type { ReactElement } from 'react';
import type { GetServerSideProps } from 'next';
type DashboardPageProps = {
message: string;
};
export const getServerSideProps: GetServerSideProps<
DashboardPageProps
> = async () => {
return {
props: {
message: 'Hello from the server',
},
};
};
const DashboardPage = ({ message }: DashboardPageProps): ReactElement => {
return <h1>{message}</h1>;
};
export default DashboardPage;Now the data can reflect the current request more directly.
The Important Difference is Timing
That is the core of the whole choice.
This is not just a naming exercise, either. On the Nando’s UK & Ireland Replatform, those rendering choices had direct consequences for cacheability, editorial workflows, and how quickly different parts of the site could respond to change.
getStaticProps asks:
"Can this route share generated data across visitors, with an appropriate policy for generating or refreshing it?"
getServerSideProps asks:
"Does this page need request‑time work?"
Everything else follows from that distinction.
getStaticProps is ideal when the data is stable enough
Good fits often include:
- marketing pages
- blog posts
- documentation
- landing pages
- content that changes infrequently
If the data does not need to be fetched freshly on every request, build‑time generation is usually a strong option because it reduces server work and often makes the page faster to serve.
getServerSideProps is better for request‑specific pages
This is a better fit when the content genuinely depends on the incoming request:
- authenticated pages
- account dashboards
- request‑specific search results
- personalised content
- pages requiring fresh server data for every request
In these cases, build‑time generation would either be wrong or too limited.
The Functions May Look Similar, but Their Operational Cost is Not
This is easy to underestimate.
getStaticProps prepares shared output during the build, during on‑demand generation, or when configured background revalidation runs. In Next.js 9.4, revalidation is still a beta feature using unstable_revalidate.
getServerSideProps does the work again and again as requests arrive.
That does not make server‑side rendering bad. It simply means it should be reserved for pages that truly need it rather than used by default because it feels more dynamic.
getServerSideProps also receives request context
Because it runs at request time, it can access context tied to the incoming request, such as query parameters, params, headers, and cookies.
That is one of the reasons it suits personalised or protected pages more naturally.
getStaticProps does not receive the same request‑specific context, even when a request triggers generation. Its result is intended to be reused across visitors.
It Helps to Think in Terms of Page Contracts
Ask what promise the page makes to the user.
If the page promise is:
"Show me the latest request‑specific information for this visitor right now,"
then getServerSideProps may be the right tool.
If the page promise is:
"Show me the current published content for this route,"
then getStaticProps may be a better match.
That framing usually leads to better choices than just asking which API feels newer or more powerful.
A Content Page Example
Suppose we are building a guide page from a CMS.
A published guide read by many visitors is a good candidate for getStaticProps when its output can be shared. Decide whether a rebuild is enough to refresh it or whether the application needs the available generation and revalidation options.
This is one of the areas where Next.js feels especially strong.
A Dashboard Example
Now consider a signed‑in customer dashboard showing account‑specific orders.
That page depends on:
- who the user is
- what their current data is
- details only known at request time
That makes getServerSideProps much more sensible. Trying to force it into build‑time generation would be working against the nature of the page.
Faster is Not the Only Question
Developers sometimes reduce the conversation to "static is faster" and leave it there.
That is incomplete.
Static generation often is faster to serve, but correctness matters more than raw speed. A page that is very quick and structurally wrong for the request is not a success.
The better question is whether the performance profile matches the data needs honestly.
This is Also About Infrastructure Shape
Choosing getServerSideProps means committing to request‑time execution. That has implications for:
- how it behaves under load
- caching
- latency
- deployment cost
Again, these trade‑offs may be entirely justified. The point is simply that they exist and should be deliberate.
Do Not Choose Server‑Side Rendering Out of Caution Alone
Many teams instinctively reach for request‑time rendering because it feels safer: "at least the data will always be fresh."
Sometimes that is true, but it can also lead to unnecessary work on every request for pages that could have been generated once up front with no meaningful downside.
Next.js is most effective when we use its flexibility to reduce waste, not when we default to the heaviest option.
If you want the broader rendering‑model version of this discussion, I broke that out separately in Static Generation vs. Server‑Side Rendering in Next.js. This piece is really about the data‑fetching functions that sit on top of that choice.
Choose Based on When the Page Should Exist
Both functions return props, but they make different promises. getStaticProps generates reusable output, with build‑time, on‑demand and beta revalidation options in this June 2020 context. getServerSideProps runs for each request and can use that request's data. Choose according to how the page may be shared and how fresh it needs to be.
Once that distinction is clear, the API names stop feeling confusing and start feeling descriptive.
Postscript
July 2020: Next.js 9.5 made Incremental Static Regeneration stable, replacing the beta unstable_revalidate option with revalidate. A time interval makes a page eligible for background regeneration on a later request; it does not guarantee that the content is never older than that interval. This builds on the beta behaviour available when the article was first published in June.