A Next.js MVP is deceptively easy to get right. Static generation makes the marketing pages fast, client components make the interactive bits feel snappy, and everything demos beautifully on a fast connection with one user in the tab.
The first real crack usually isn't performance — it's data-fetching patterns that quietly turned into a waterfall. A page that fetches, then fetches again based on that result, then again, adds up fast once it's real network latency instead of localhost. The fix is almost always co-locating fetches or moving them server-side, not a bigger instance.
The second is caching decisions made by default rather than on purpose. Next.js caches aggressively unless told otherwise, which is great until a client asks why their dashboard is showing yesterday's numbers. Every fetch needs a deliberate answer to "how fresh does this need to be" — not the framework's default answer.
The third is bundle size creeping up one dependency at a time. Nothing individually looks expensive; the cumulative weight is what slows first load on a real device on real mobile data, which is usually where a client's own customers actually are.
None of these show up in a demo. All of them show up in the first month of real usage — which is exactly why they're worth designing for before that month starts, not after a client asks what happened.