Appixel logoAPPIXEL
Back to Blog
Web 4 min readSeptember 15, 2024

Next.js App Router in Enterprise: A 6-Month Production Report

After migrating four enterprise clients from Pages Router to App Router, here's the honest breakdown of wins, losses, and caveats.

G

Gokul C

Founder & Lead Engineer

Next.js App Router in Enterprise: A 6-Month Production Report

We have migrated four enterprise clients from the Next.js Pages Router to the App Router over the past six months. The results are genuinely nuanced. The App Router is the right direction and we would choose it again — but the migration path and its production characteristics have surprised us in ways the documentation does not fully prepare you for.

This is the honest report we wish we had read before starting: what got dramatically better, what got harder, and where you should budget more time than your instincts suggest.

Server Components change how you think

The largest shift is conceptual, not syntactic. Moving from "fetch data in getServerSideProps and pass it down as props" to "fetch data directly inside the component tree" takes about a week to internalize and then meaningfully simplifies your architecture.

In the Pages Router, data fetching lived at the page boundary, and every component below it received data through prop drilling or context. With Server Components, a deeply nested component can fetch exactly what it needs, on the server, without a client-side request and without threading props through five layers. For complex, data-heavy page hierarchies — the kind enterprise dashboards are made of — this is a real reduction in accidental complexity.

The mental adjustment worth making early: think of the server/client boundary as a deliberate design decision, not an afterthought. Keep components on the server by default and push "use client" as far down the tree as possible.

Streaming is transformative for perceived performance

The Pages Router had an all-or-nothing rendering model. The server assembled the entire page, and until it was ready, the user stared at a blank screen.

The App Router, with Suspense boundaries, lets you stream the page in pieces. The shell and above-the-fold content appear immediately while slower, data-dependent sections resolve and stream in behind loading skeletons. For content-heavy enterprise dashboards — where one slow query used to block the entire render — this is a material, user-visible improvement, not a micro-optimization.

The practical technique: wrap slow, independent sections in their own Suspense boundaries so a single expensive query cannot hold the whole page hostage.

Caching is the footgun

This is the part that cost us the most debugging time, and the part you should approach with the most caution.

The App Router's caching system is powerful but opaque. There are several overlapping caches — the Request Memoization, the Data Cache, the Full Route Cache, and the Router Cache — and their interactions are not obvious. We repeatedly lost time to the same class of bug: why is this component showing stale data?

A few hard-won lessons:

  • The default caching behavior is aggressive. You will opt out — with no-store, revalidate, or dynamic settings — far more often than you expect.
  • Be explicit about data freshness at the fetch site rather than trusting defaults. Ambiguity here is where stale-data bugs breed.
  • Test caching behavior in a production build, not just in dev, because the caches behave differently between the two.

None of this is a reason to avoid the App Router. It is a reason to treat caching as something you configure deliberately, with your eyes open.

Third-party compatibility is still a real concern

Several libraries we relied on in the Pages Router either did not work in Server Components or required non-trivial configuration changes to coexist with them. Anything that assumes a browser environment, relies on React Context at the root, or ships without "use client" boundaries can create friction.

Before committing to a migration, audit your dependency tree. Identify which libraries are client-only, wrap them appropriately, and confirm your critical dependencies have caught up with the App Router. This audit is cheap to do up front and expensive to discover mid-migration.

Should you migrate?

Our net assessment, after four production migrations:

  • For new projects: start on the App Router without hesitation. It is the right foundation and the direction the ecosystem is moving.
  • For existing Pages Router apps: the migration is worth it for most production applications, but it is not free. Budget more time than you expect specifically for the caching model and third-party library compatibility — those two account for the majority of the surprises.

The App Router is a better architecture. It just asks you to be more deliberate than the Pages Router ever did, and that deliberateness is precisely where teams underestimate the effort. Go in with a realistic timeline and it is one of the best infrastructure investments you can make.

Topics

Next.jsApp RouterEnterprise

Want to build something like this?

Tell us about your project and we will get back to you within 4 hours.

Start a project