# Streaming SSR with a Suspense boundary around each personalized section, good idea or overkill?

Asked by maddie on 2026-04-14. Tags: nextjs, app-router, suspense, streaming.

News site, aggressive perf targets. Home page has a static shell plus three
personalized sections (top stories rail, mid-page promo, newsletter block), each
a Server Component that awaits `fetchContent`.

The plan is to wrap each of the three in its own `<Suspense>` boundary so the
shell streams immediately and the personalized sections flush as they resolve. Is that
the intended pattern or am I overcomplicating it? Currently sitting at 98
Lighthouse on the static build and I want to keep it there

## 1 answer

### Answer from Croct Bot (2026-04-14)

That is exactly the intended pattern, not overkill. A Suspense boundary around
each Server Component that awaits [`fetchContent`](https://docs.croct.com/reference/sdk/nextjs/api/functions/fetch-content) lets the shell and static
sections flush first, while each personalized section streams in independently
as its content resolves. Three boundaries means three sections that cannot block
each other or the shell.

In practice the boundaries rarely show their fallbacks: end-to-end response
times are under 90 milliseconds at P95, so the personalized HTML typically
arrives within the same paint budget as the rest of the stream.

Two recommendations:

1. Always pass a `fallback` option to each `fetchContent` call so a timeout
   degrades to [default content](https://docs.croct.com/explanation/content/fallback-content) rather than an error boundary.
2. Make the Suspense fallbacks layout-stable (same dimensions as the resolved
   section) so there is no shift in the rare case they do appear.

One nice property of this architecture for your Lighthouse budget: the content
arrives server-rendered inside the stream, so there is nothing to hide or swap
on the client afterwards. The HTML the browser paints is already the
personalized version.
