Ask

Jo Petrakis

@wrangler_dev_jo

Junior-ish developer, about eighteen months in, building a side product on D1 and Queues. I ask more questions than I answer and I try to write up whatever finally worked.

0 credit Newcomer

From answers
0
From questions
0

Joined September 17, 2025 · 0 followers · 0 following

next 15 upgrade turned every fetch uncached and my pricing api bill went 16x

Separate from fixing the config: if that vendor charges per call, do not let a framework cache be the only thing between you and the invoice. Stick a small cache in front that you own - KV, Redis, a table, anything with an explicit TTL you can read at 3am. Framework caching defaults are going to keep changing across majors and your vendor contract is not.

18 · in/app-router ·

middleware runs twice per navigation and my rate limiter 429s real users

Both. Exclude prefetches now, then move the limiter.

The matcher takes missing, so you can keep prefetch requests out entirely:

export const config = {
  matcher: [{
    source: '/dashboard/:path*',
    missing: [{ type: 'header', key: 'next-router-prefetch' }]
  }]
}

But the deeper issue is that you are counting page views, and page views are not the thing you are protecting. Nobody abuses your app by looking at the dashboard. Put the limiter on the route handlers and server actions that write or that call something expensive, keyed on the user id rather than the IP, and let navigation be free. Your office customers behind one NAT will thank you too.

44 · in/app-router ·

vercel or a $12 vps for an app router app at 300k requests a month

Three things bite, in this order:

  1. ISR cache is on local disk by default. One box, fine. The moment you run two containers for a zero-downtime deploy they each have their own cache and users see pages flip between two versions. You need a shared cache handler pointed at Redis, which is another service to run.
  2. Image optimisation is CPU and disk. sharp will happily eat a whole vCPU resizing a 4000px phone photo, and the optimised images accumulate on disk until something fills up at 2am. Cap the sizes you allow and put a real cache in front.
  3. You become the person who renews the certificate. Caddy makes that mostly automatic, which is why I use it over nginx for this exact setup.

None of it is hard. It is about two evenings up front and an hour a month afterwards. If that hour is worth more to you than $20, stay managed.

38 · in/app-router ·