Back to Blog

Building Scalable Next.js Apps

Learn the key principles and patterns I've used to build Next.js applications that scale to millions of users, with insights from real-world production systems.

Next.jsArchitecturePerformanceReact
February 7, 2026
4 min read

Building Scalable Next.js Apps

Over the past few years, I've had the opportunity to architect and build several Next.js applications that serve millions of users. Through this journey, I've learned valuable lessons about what works—and what doesn't—when it comes to building truly scalable applications.

The Foundation: App Router vs Pages Router

With Next.js 13+, the App Router introduces a new paradigm for building React applications. Here's what I've learned about when to use each:

App Router Benefits

  • Server Components by default - Dramatically reduces client-side JavaScript
  • Streaming and Suspense - Better user experience with progressive loading
  • Nested layouts - Reduced code duplication and better composition

Key Principles for Scalability

1. Optimize Data Fetching

The most common performance bottleneck I see is inefficient data fetching. Here are the patterns that work:

typescript
// Good: Fetch data at the layout/page level
async function getData() {
const data = await fetch('https://api.example.com/data', {
next: { revalidate: 3600 } // Cache for 1 hour
});
return data.json();
}

export default async function Page() {
const data = await getData();
return <Component data={data} />;
}

2. Use Server Components Strategically

Not everything needs to be a client component. My rule of thumb:

  • Server Components for data fetching, heavy computations, and static content
  • Client Components only for interactivity (forms, click handlers, hooks)

3. Image Optimization

Next.js Image component is powerful, but requires proper configuration:

typescript
import Image from 'next/image';

<Image
src="/hero.jpg"
alt="Hero image"
width={1200}
height={600}
priority // For above-the-fold images
quality={85} // Balance quality and size
/>

Database and API Layer

Connection Pooling

For applications at scale, proper database connection management is critical:

  • Use connection pooling (PgBouncer for PostgreSQL)
  • Implement edge caching with Vercel's Data Cache or Redis
  • Consider read replicas for heavy read workloads

API Route Optimization

typescript
export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
const id = searchParams.get('id');

// Use proper caching headers
return NextResponse.json(data, {
headers: {
'Cache-Control': 'public, s-maxage=60, stale-while-revalidate=30',
},
});
}

Monitoring and Observability

You can't scale what you can't measure. Essential metrics:

  • Core Web Vitals - LCP, FID, CLS
  • Server Response Times - Track API and SSR performance
  • Error Rates - Monitor client and server errors
  • Database Query Performance - Identify slow queries early

Deployment Best Practices

Incremental Static Regeneration (ISR)

For content-heavy sites, ISR is a game-changer:

typescript
export const revalidate = 3600; // Revalidate every hour

export default async function Page() {
const data = await fetch('https://api.example.com/posts');
return <Posts data={data} />;
}

Edge Functions

For global applications, edge functions reduce latency:

typescript
export const runtime = 'edge';

export async function GET(request: Request) {
// This runs on edge locations near your users
return new Response('Hello from the edge!');
}

Real-World Performance Numbers

Here are some metrics from a production Next.js app I built that serves 5M+ users:

  • Lighthouse Score: 95+ (Performance)
  • LCP: < 1.2s
  • FID: < 100ms
  • CLS: < 0.1
  • Server Response Time: < 200ms (p95)

Key Takeaways

  1. Start with Server Components - Only reach for Client Components when needed
  2. Implement proper caching at every layer (CDN, API, Database)
  3. Monitor everything - Use tools like Vercel Analytics, Sentry, and custom dashboards
  4. Optimize images and fonts - These are often the biggest performance bottlenecks
  5. Use ISR for semi-static content - Best of both worlds: static speed with dynamic updates

What's Next?

I'm planning to dive deeper into specific topics in upcoming posts:

  • Advanced caching strategies with Redis and CDN
  • Building real-time features at scale
  • Microservices architecture with Next.js
  • Cost optimization for high-traffic applications

Have questions or want to share your own experiences? Feel free to reach out on LinkedIn or Twitter.


About the Author: Muhammad Khan is a Principal Full Stack Engineer with 9+ years of experience building scalable web and mobile applications. He currently architects systems serving millions of users and loves sharing knowledge with the developer community.