The simplest data path
Server Components are async functions. You await data and render. There's no useEffect, no loading state machine, no client cache to invalidate.
Two ways to read data
fetch()— for HTTP/JSON sources. Caching is controlled per call (we'll cover that in the data-fetching track).- Direct DB / SDK calls — Prisma, Drizzle, Postgres clients, internal services.
Parallel by default; waterfall on purpose
Independent fetches should be in Promise.all. The framework will not magically parallelize your sequential awaits — that's a JavaScript reality, not a framework one. Sequential is fine when the second fetch genuinely depends on the first.
Where to fetch
Fetch in the component that uses the data. Don't drill props from the page through three layers; have the leaf component fetch what it needs. The framework deduplicates identical fetch() calls during a single render pass, so two siblings asking for the same URL trigger one network request.