Issues with Nextjs Cached Components 16 app router
Unanswered
Ariegeois posted this in #help-forum
AriegeoisOP
1. Bundle: ~4.1MB gzipped overall (~940KB on
2. Hard Load:
3. Waterfall:
4. Shared Access: Cross-org lookups take up to 5 serial queries (vs 0 for direct owners).
/projects).2. Hard Load:
DashboardShell awaits session + 5-query eager wave before rendering children.3. Waterfall:
projects/[id] units key needs project.archivedAt (2 serial DB reads).4. Shared Access: Cross-org lookups take up to 5 serial queries (vs 0 for direct owners).
15 Replies
AriegeoisOP
Stack & Structure
• Stack: Bun, Turborepo, Next 16 (App Router), React 19, Supabase, Drizzle, TanStack Query, Tailwind 4
• Apps:
• Packages:
Data Flow & Fetching
• Logic: All logic lives in
• Reads (
• Writes: Standard POST Server Actions via
• Caching: TanStack Query is the sole transactional cache (
RSCs & Auth
• RSCs: Pages
• Auth: Local ES256 JWKS token verification via
• Security Chain: Middleware JWT verify → Page guards →
• Org Claim:
Database & Storage
• DB: Supavisor pooler (
• Storage: Batch-signs URLs where possible. Transformed thumbnails flatten arrays page-wide before signing to prevent N+1 calls.
• Stack: Bun, Turborepo, Next 16 (App Router), React 19, Supabase, Drizzle, TanStack Query, Tailwind 4
• Apps:
dashboard (app + Vercel crons/workflows), admin, website• Packages:
db, auth, supabase, ui, i18n, apiData Flow & Fetching
• Logic: All logic lives in
defineQuery / defineAction wrappers (packages/auth). Handles session, RBAC, billing locks, and audit logging.• Reads (
GET /api/q/[name]): Custom GET endpoints via allow-list (lib/query/registry.ts). Bypasses React's single-threaded Server Action queue for parallel browser fetches without router cache busts.• Writes: Standard POST Server Actions via
useActionMutation with client-side optimistic updates.• Caching: TanStack Query is the sole transactional cache (
staleTime: 60s, gcTime: 15m). Zero server-side DB caching ("use cache" is only for static/ref data).RSCs & Auth
• RSCs: Pages
await only one primary query via prefetchQuery; secondary queries use void prefetchQuery(...) to stream via Suspense.• Auth: Local ES256 JWKS token verification via
getClaims() (no network round trips). defineQuery runs an uncached getFreshAccountStatus check for instant org suspension across deployments.• Security Chain: Middleware JWT verify → Page guards →
defineQuery → Supabase RLS.• Org Claim:
active_org_id is baked into the JWT. Switching orgs calls ensureOrgClaim to force-refresh tokens and avoid Storage 403s.Database & Storage
• DB: Supavisor pooler (
:6543 runtime) + direct (:5432 DDL). warmConnection() runs on boot to skip the ~200ms cold TCP/TLS hit.• Storage: Batch-signs URLs where possible. Transformed thumbnails flatten arrays page-wide before signing to prevent N+1 calls.
any idea? is our setup wrong?
AriegeoisOP
hekllo?
@Ariegeois hekllo?
Polar bear
What is your actual problem?
What error is Next.js giving you when enabling cache components exactly?
AriegeoisOP
😂
@Polar bear What is your actual problem?
AriegeoisOP
U are not reading it
Performance issues
Slow
Navigating loading data
@Ariegeois U are not reading it
Polar bear
I did read it.. you just shared your tech stack and that you're dealing with a waterfall, hard load, etc. That's not much to go off.
How slow is it? Do you have timing data? Have you confirmed it's not your database query, etc.
How slow is it? Do you have timing data? Have you confirmed it's not your database query, etc.
Your bundle size also cannot be resolved by cache components and isn't related
That comes down to how much "use client" you're doing
For dashboards with user auth I follow this pattern:
and you put a
export default async function DashboardPage() {
const user = await verifyCurrentUser()
prefetch(
trpc.guild.guilds.queryOptions(
{},
{
staleTime: Infinity,
refetchOnMount: false,
refetchOnWindowFocus: false,
refetchOnReconnect: false,
}
)
)
return (
<HydrateClient>
...
</HydrateClient>
)
}and you put a
loading.tsx so that it's all wrapped in React.SuspenseThen from there you have your shell and move "use client" and Suspense boundaries as deep as possible