Skip to main content
Blog

From 2GB to 200MB: How I Cut Down Our Next.js Build Without Writing A Single Custom API

ByVartika Dhoot
July 11th . 5 min read
From 2GB to 200MB How I Cut Down Our Next.js Build Without Writing A Single Custom API

We were building a website using Next.js for the frontend and Strapi for the backend. Everything was smooth until we noticed something odd: our build size was exploding. It reached almost 2GB, and the build time was 30+ minutes.

Initially, it looked like we’d have to write custom APIs just to reduce the data being fetched. But we didn’t. We achieved this without writing a single custom API, just by learning how to use Strapi efficiently.

In this blog, I’ll walk you through:

  • Why build and page size matter

  • What was going wrong and the changes we made

  • And finally, how those changes brought 2GB → 200MB and 30 mins → 3 mins builds

What is Build Size and Why Does It Matter?

When you use static site generation in Next.js, your build process pre-generates every page with the data it needs. This data, fetched during getStaticProps or similar methods, is included in the final .html, .json, and .js files.

If you're pulling unnecessary data from your backend, it doesn’t just affect that API call, it bloats your static files and increases:

Build size: Heavier pages, more storage required Build time: Longer CI/CD processes and delays in deployment So, when the backend sends a lot more than needed, your entire app suffers. That was our exact issue.

What was going wrong, and what changes did we make?

After digging into our API calls and what was getting rendered during the build, I found a few key issues:

  • Using populate=deep everywhere.

At first, it felt convenient- just fetch everything. But the problem with populate=deep is that it recursively populates all nested fields and relations by default. So, if a single field contains multiple nested components or dynamic zones, they all get pulled in. Even if you’re not using them on the frontend.

And all that unnecessary data? It was going straight into our static pages. This silently bloated the build, page after page, layer after layer.

  • The header and footer APIs were huge. Since they’re used across all pages, even a small improvement here makes a big impact. But these weren’t small at all, each was sending around 3–4MB of data.

We were fetching everything. Media. Metadata. Nested components. Blocks we weren’t even rendering.

By leveraging Strapi’s query options and requesting only the fields we needed, we managed to bring both the header and footer APIs down to about ~30KB each.

  • Going too deep. For pages where writing field-specific queries wasn’t practical, we used:
populate=deep,N

N stands for the number of levels here

This reduced the depth of the nested population (in my case) to just 2 or 3 levels. It gave enough data for rendering while avoiding unnecessary nested blobs.

  • Understanding how Strapi's populate actually works helped a lot. This part is underrated. Once I fully understood how nested population works in query parameters, writing efficient queries became easy.

Here’s an example:

populate[items][populate][example_media]=*

What this does:

populate[items]: Populate the items field (a component or relation) populate[items][populate][example_media]=: Inside each item, populate its example_media relation. =: Means fetch all fields from example_media.

You can even go more specific

populate[items][populate][example_media][fields][0]=url

This will populate only the URL field of the media object, skipping metadata you don’t need.

Results

  • Build size dropped from ~2GB → ~200MB

  • Build time dropped from ~30 minutes → ~3 minutes

  • API responses were cleaner and faster

  • No custom APIs were written — just used Strapi the way it was meant to be used

Final Thoughts:

The root cause wasn’t Strapi. It was how we were using it. Once we understood:

  • How populate works

  • When to use fields

  • When to use depth-level control (deep,N)

  • How to skip unnecessary relations

…we saw a massive improvement.

No hacks. No new endpoints. Just smarter queries.

Share:
0
+0