Compose independent server data fetches as siblings
When sections of a server-rendered page need independent data, give each section its own async Server Component and render them as siblings, instead of awaiting one section's data in a parent that renders the other.
Implementation
- Move each
awaitinto the component that uses the data. - Render components with independent data side by side, so they start fetching at the same time.
- When one fetch depends on another's result, keep them in sequence; this rule is about independent data.
- Combine this with
Suspenseboundaries so each section can stream when its data arrives.
Rationale
A child Server Component does not start rendering until its parent returns it. If the parent awaits its own data first, the child's fetch waits for the parent's, even when the two are unrelated. Siblings start rendering together, so their fetches overlap.
Examples
Incorrect (counterexample):
export default async function Page() {
const header = await fetchHeader();
return (
<div>
<div>{header}</div>
<Sidebar />
</div>
);
}
async function Sidebar() {
const items = await fetchSidebarItems();
return <nav>{items.map(renderItem)}</nav>;
}
fetchSidebarItems starts only after fetchHeader finishes.
Correct:
async function Header() {
const header = await fetchHeader();
return <div>{header}</div>;
}
export default function Page() {
return (
<div>
<Header />
<Sidebar />
</div>
);
}
Header and Sidebar render as siblings, so both fetches start together.
Validation
Trace the page's data requests with server timing or logs and check that independent requests overlap.
Sequential fetches where one needs the other's result are not a violation.