Skip to content

Proxy: stop paying a Supabase round trip on every request - #172

Merged
nessed merged 1 commit into
mainfrom
claude/youthful-einstein-jlaait
Oct 2, 2026
Merged

nessed merged 1 commit into
mainfrom
claude/youthful-einstein-jlaait

Conversation

@nessed

@nessed nessed commented Oct 2, 2026

Copy link
Copy Markdown
Owner

Vercel emailed that the Hobby team is at 75% of the Fluid provisioned memory allowance (360 GB-hrs). Every page is client-rendered, so proxy.ts is close to the only server work, and it was awaiting supabase.auth.getUser() (a network call to Supabase Auth) on every matched request. That covered public pages, every MCP call, and static files like the manifest and fonts. Provisioned memory gets billed for all the time spent waiting on that call.

  • Public paths other than / and /auth now return before any Supabase client gets created. The MCP connector and the OAuth routes do their own auth.
  • getUser() is now getClaims(). It still verifies the JWT signature and refreshes tokens that are about to expire. When the project uses asymmetric signing keys it does the check locally against the cached JWKS, with no Auth round trip.
  • The matcher now skips any path with a file extension. isPublicPath already let those through, so matching them just cost a function call each.

Private routes behave the same as before: no session means a redirect to /auth, the no-store header is still set, and signed-in visits to / or /auth still go to /dashboard.

Checks: npm run typecheck and npm run lint pass. I also tested the new matcher regex against the main paths (/dashboard, /api/mcp, /opengraph-image match; /robots.txt, /manifest.webmanifest, fonts and _next/static don't).

🤖 Generated with Claude Code

https://claude.ai/code/session_011hdAG7Aq4BQEH7NVpMAiQP


Generated by Claude Code

Vercel flagged 75% of the Hobby Fluid provisioned memory allowance. Every
page is client-rendered, so the proxy is nearly the only server work, and
it awaited supabase.auth.getUser() (a network call to Auth) on every
matched request, public or not, including every MCP call and static files
like the manifest and fonts.

- Public paths other than '/' and '/auth' return before any Supabase
  client is made. The MCP connector and OAuth routes do their own auth.
- getUser() becomes getClaims(), which verifies the JWT locally against
  the cached JWKS when the project uses asymmetric signing keys.
- The matcher skips anything with a file extension; isPublicPath already
  waved those through.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_011hdAG7Aq4BQEH7NVpMAiQP
@vercel

vercel Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
akada Ready Ready Preview Oct 2, 2026 7:15pm UTC

@nessed
nessed merged commit e02328a into main Oct 2, 2026
4 checks passed

This branch was successfully deployed

1 active deployment
Preview — 218ad051 Deployed Oct 2, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants