Next.js cookbook · Beginner
Avoid data-fetching waterfalls in Server Components
A dashboard page is slow because it awaits user, stats and notifications one after another.
Approach
Start independent requests at the same time with Promise.all (or start promises early and await them later). Deduplicate repeated reads in one render with React cache(), and push slow, non-critical sections behind Suspense so they stream later.
Solution
import { cache } from "react";
import { Suspense } from "react";
// Deduplicated within a single server render
export const getUser = cache(async (id: string) => db.user.findUnique({ where: { id } }));
export default async function DashboardPage() {
const session = await verifySession();
// BUG: Waterfall: ~ t(user) + t(stats) + t(projects)
// const user = await getUser(session.userId);
// const stats = await getStats(session.userId);
// const projects = await getProjects(session.userId);
// FIX: Parallel: ~ max(t(user), t(stats), t(projects))
const [user, stats, projects] = await Promise.all([
getUser(session.userId),
getStats(session.userId),
getProjects(session.userId),
]);
return (
<main>
<Header user={user} />
<StatsCards stats={stats} />
<ProjectList projects={projects} />
<Suspense fallback={<ActivitySkeleton />}>
<ActivityFeed userId={session.userId} /> {/* slow, streamed */}
</Suspense>
</main>
);
}
Pitfalls
- Fetching in nested components that each await before rendering children (component waterfalls).
Promise.allfailing the whole page for one optional section (useallSettledor Suspense boundaries).- Calling your own API routes over HTTP from Server Components.
Variations
- Preload pattern: call
void getUser(id)early in a parent to warm the cache.
Further reading: Next.js: Parallel data fetching
Go deeper: The Browser Side: React and Vue Page Loads in the Request Lifecycle course traces this step of the request, with a production bug and a runnable simulation.
Reference: https://nextjs.org/docs/app/getting-started/fetching-data#parallel-data-fetching
More Next.js recipes
- Add a Content Security Policy with nonces in Next.js
- Add dark mode to Next.js without a flash
- Add SEO metadata, Open Graph and sitemaps
- Build a validated JSON API with Route Handlers
- Create encrypted session cookies in Next.js
- Handle errors and 404s in the App Router
- Handle forms with Server Actions and validation
- Keep secrets and server code out of the client bundle