From 8d48272935821557e6a4903f59d35480667d553b Mon Sep 17 00:00:00 2001 From: Geekur Date: Mon, 10 Aug 2026 18:45:02 -0500 Subject: [PATCH] =?UTF-8?q?fix:=20give=20OpenNext=20somewhere=20to=20cache?= =?UTF-8?q?=20=E2=80=94=20courses=20regenerates=20every=20page,=20every=20?= =?UTF-8?q?request?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit open-next.config.ts was defineCloudflareConfig({}) with no incrementalCache, and wrangler.toml bound no R2 bucket or KV namespace. OpenNext therefore had no store to write rendered pages into, so every prerendered route was rebuilt from Supabase on every single request. Measured on courses.opengolfapi.org, 2026-08-10, six consecutive requests: TTFB 4.06s / 3.89s / 4.02s / 3.87s / 3.81s / 3.93s x-nextjs-cache: MISS (every time) x-nextjs-prerender: 1 cache-control: s-maxage=3600, stale-while-revalidate=31532400 robots.txt on the same host: 0.17s Consistent, not a cold start. The page was prerendered and declared an hour of cacheability; there was nowhere to put it. Bucket opengolfapi-next-cache was created for this. The account already runs this pattern elsewhere (altar-website-opennext-cache, xtrends-web-cache) — the courses app is the one that never got wired up. Verified against the installed @opennextjs/cloudflare 1.19.8, not from memory: the exports map routes ./* to dist/api/*, so the override path resolves, and r2-incremental-cache.js reads the binding name NEXT_INC_CACHE_R2_BUCKET. --- open-next.config.ts | 11 ++++++++++- wrangler.toml | 7 +++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/open-next.config.ts b/open-next.config.ts index fa6cb73..b0354e1 100644 --- a/open-next.config.ts +++ b/open-next.config.ts @@ -1,3 +1,12 @@ import { defineCloudflareConfig } from '@opennextjs/cloudflare'; +import r2IncrementalCache from '@opennextjs/cloudflare/overrides/incremental-cache/r2-incremental-cache'; -export default defineCloudflareConfig({}); +// Without an incrementalCache, OpenNext has nowhere to persist a rendered page, +// so every prerendered route is regenerated from Supabase on EVERY request. +// Measured 2026-08-10 on courses.opengolfapi.org: `x-nextjs-cache: MISS` on six +// consecutive requests, TTFB 3.8-4.1s each, despite the response carrying +// `x-nextjs-prerender: 1` and `s-maxage=3600`. The page was already prerendered; +// there was simply no store to read it back out of. +export default defineCloudflareConfig({ + incrementalCache: r2IncrementalCache, +}); diff --git a/wrangler.toml b/wrangler.toml index a6118a9..1176cf2 100644 --- a/wrangler.toml +++ b/wrangler.toml @@ -9,6 +9,13 @@ directory = ".open-next/assets" binding = "ASSETS" run_worker_first = true +# Incremental cache store for OpenNext. The binding name is not arbitrary: +# @opennextjs/cloudflare's r2-incremental-cache override reads exactly +# NEXT_INC_CACHE_R2_BUCKET. +[[r2_buckets]] +binding = "NEXT_INC_CACHE_R2_BUCKET" +bucket_name = "opengolfapi-next-cache" + # Set production secrets via: # wrangler secret put NEXT_PUBLIC_SUPABASE_URL # wrangler secret put NEXT_PUBLIC_SUPABASE_ANON_KEY