Vercel Now Serves FastAPI Static Files and Frontends from the CDN
Vercel now promotes FastAPI app.frontend() and StaticFiles routes to its CDN at build time — requests for those paths never touch your Vercel Function. Python apps finally get the same static-path treatment Next.js has had for years.
What shipped
At build time, Vercel's FastAPI adapter walks your route declarations and promotes anything declared as a frontend (app.frontend("/", directory="dist")) or a StaticFiles mount to edge cache. The changelog's key sentence: requests for those paths "are served directly from the CDN, without invoking your Vercel Function."
What changed — and the math
This is a billing-category swap, not just a speedup. Function invocations are usage-based beyond your included quota — Hobby includes 1 million invocations per month alongside 100 GB of fast data transfer, Pro includes 1 TB (per Vercel's plan limits docs). Every asset a function served was burning the scarcest quota on the Hobby plan. CDN-served responses don't invoke the function at all, so a static-heavy FastAPI app can drop from tens of thousands of billed invocations a day to near zero.
The gotchas are where you'll lose money or sleep:
- Declaration order wins. A route declared before a StaticFiles mount takes precedence over the CDN file at the same path. If a stale
@app.get("/static/manifest.json")sits above your mount, it silently keeps every request on the function — full price, no cache. - Guarded routes silently stay on the function. Frontends behind dependencies and static files behind middleware are not promoted — the CDN can't run your dependency checks. That's correct behavior, but it's invisible: you think you're getting CDN pricing and you're not.
- Escapes exist.
tool.vercel.fastapi.static.cdn = trueforces promotion past guards;.exclude = truedrops promoted directories from the function bundle so runtime code can't read them;= falseopts out entirely. Promoted dirs stay in the bundle by default — you're shipping both copies.
Why a builder cares
The trap is silent downgrades. Route precedence and dependency guards both quietly keep traffic on the function, and nothing in the dashboard screams at you — you just keep paying invocation overages you assumed you'd escaped. After deploying, check your Observability invocation graph: if static paths still spike it, a route above your mount or a middleware dependency is the culprit. This lands a day after Vercel's flat-rate CDN pricing hit GA on Pro, which reads as one coherent push: make static Python delivery a CDN problem, not a compute problem.
FAQ
Does Vercel serve FastAPI static files from the CDN now?
Yes. As of September 10, 2026, FastAPI app.frontend() directories and StaticFiles mounts are promoted to the Vercel CDN at build time, and requests for those paths are served from the CDN without invoking your Vercel Function.
Why would my FastAPI static files still invoke the Vercel Function?
Two reasons: a route declared before the StaticFiles mount takes precedence over the CDN file at that path, and frontends behind dependencies or static files behind middleware are deliberately kept on the function because the CDN cannot evaluate those checks. Both are silent — verify with your invocation metrics.
Does this reduce Vercel costs for FastAPI apps?
It can. Hobby plans include 1 million function invocations per month and Pro includes 1 TB of fast data transfer; CDN-served static requests consume neither. Promoting static traffic to the CDN removes those requests from usage-based function billing entirely.