# How to ship a FastAPI app on Vercel

**Author:** Ben Sabic

---

[FastAPI](https://fastapi.tiangolo.com/) is a high-performance Python web framework for building APIs. It uses standard Python type hints to give you request validation, serialization, and automatic interactive API docs, and it runs on the ASGI standard, so your endpoints can handle requests asynchronously.

On Vercel, you can deploy a FastAPI app with zero configuration: your app becomes a [Vercel Function](https://vercel.com/docs/functions) running on [Fluid compute](https://vercel.com/fluid), and you get response streaming, preview deployments, and observability without extra setup.

This guide walks you through deploying a FastAPI app to Vercel from a template, the [Vercel CLI](https://vercel.com/docs/cli), or a Git repository, then configuring features such as streaming, middleware, cron jobs, the Python version, and observability.

## Prerequisites

Before you begin, make sure you have:

- A [Vercel account](https://vercel.com/signup)
  
- Python 3.12 or later and a package manager (e.g., pip or uv)
  
- An existing FastAPI project, or a new one created from a [FastAPI template](https://vercel.com/templates?search=fastapi)
  
- A Git repository on GitHub, GitLab, or Bitbucket (if you want Git-based deployments)
  
- Vercel CLI installed (`npm i -g vercel`)
  

## How it works

When you deploy a FastAPI app, Vercel detects the framework from your dependencies and builds it for the Python runtime. Vercel looks for a FastAPI instance named `app` at a supported entrypoint and serves your whole app as a single Vercel Function, which runs on Fluid compute by default. Your app scales with traffic, and you pay only for the compute your function uses, not for idle time.

Because Vercel ships zero-configuration detection for FastAPI, you don't set a build command or output directory. Vercel reads your project, finds the file that exports your FastAPI `app`, and applies the correct build settings.

## Deploy your FastAPI app

You can ship a FastAPI app to Vercel in three ways. Choose the one that fits where your code lives today.

### Option 1: Deploy from a template

The fastest way to ship a FastAPI app is to start from a template. Pick a starter, then deploy it. Vercel clones the template to your Git provider, creates a project, and deploys it with zero configuration.

Templates to start from include:

- [**FastAPI Boilerplate**](https://vercel.com/templates/python/fastapi-python-boilerplate): A minimal FastAPI app that runs on the Python runtime and deploys with zero configuration. Start here if you're new to FastAPI on Vercel.
  
- [**AI SDK Python Streaming**](https://vercel.com/templates/next.js/ai-sdk-python-streaming): Streams chat completions from a FastAPI function and renders them with [AI SDK](https://ai-sdk.dev) `useChat` hook in a Next.js frontend.
  
- [**Next.js FastAPI Starter**](https://vercel.com/templates/next.js/nextjs-fastapi-starter): An AI chatbot with a Next.js frontend and a FastAPI backend.
  
- [**OpenAI Agents SDK with FastAPI**](https://vercel.com/templates/other/openai-agents-sdk-with-vercel-sandbox-fastapi): A FastAPI app that runs the OpenAI Agents SDK with [Vercel Sandbox](https://vercel.com/sandbox), spinning up an isolated microVM per request to give the agent shell access.
  
- [**Full-stack FastAPI template with Next.js**](https://vercel.com/templates/other/full-stack-fastapi-template-with-next-js): A full-stack starter that pairs a FastAPI backend with a Next.js frontend, with cookie-based auth and a Postgres database.
  

### Option 2: Start a new project with the Vercel CLI

To scaffold a new FastAPI project locally, use the [Vercel CLI init command](https://vercel.com/docs/cli/init). It clones Vercel's FastAPI example into a folder named `fastapi`.

1. Create the project:
   
   `vercel init fastapi`
   
2. Set up a virtual environment and install dependencies:
   
   `cd fastapi python -m venv .venv source .venv/bin/activate pip install -r requirements.txt`
   
3. Develop locally at `http://localhost:3000`. Use the Vercel CLI, so your app runs with the same `app` instance it uses in production:
   
   `vercel dev`
   
4. Create a [preview deployment](https://vercel.com/docs/deployments/environments#preview-environment-pre-production). The first run creates a Vercel project link:
   
   `vercel`
   
5. Promote your deployment to production:
   
   `vercel --prod`
   

### Option 3: Deploy an existing FastAPI app

If you already have a FastAPI app, deploy it from Git or from the command line.

From Git: Push your project to GitHub, GitLab, or Bitbucket, then import it at [vercel.com/new](https://vercel.com/new). Vercel detects FastAPI automatically and deploys it with zero configuration.

From the CLI: From your project's root directory, run `vercel` to create a preview deployment, then `vercel --prod` to go live. To pull project settings and environment variables for local development, run:

`vercel link vercel env pull`

For Vercel to detect your app, export a FastAPI instance named `app` from one of the recognized entry files, such as `app.py`, `index.py`, `server.py`, `main.py`, `wsgi.py`, or `asgi.py` at your project root or under `src/`, `app/`, or `api/`:

`from fastapi import FastAPI app = FastAPI() @app.get("/") def read_root(): return {"message": "Hello from FastAPI on Vercel"}`

To point Vercel to a FastAPI app in a custom module, set `tool.vercel.entrypoint` in `pyproject.toml`:

`[tool.vercel] entrypoint = "backend.server:app"` This tells Vercel to load the `app` variable from `./backend/server.py`. ## Use Vercel features with FastAPI After your app is deployed, you can layer Vercel features onto it. Some work automatically, and others take a few lines of configuration in `vercel.json`. ### Your app runs as a single Vercel Function Vercel serves your FastAPI app as a single [Vercel Function](https://vercel.com/docs/functions). This function uses Fluid compute by default, which runs multiple requests concurrently within a single instance to reduce cold starts and the cost of I/O-bound work such as API calls and database queries. You don't configure anything to get this behavior.

Because FastAPI exports a single `app`, Vercel sends every incoming request to that app and lets FastAPI's router match the path. Your route handlers, dependencies, middleware, and error handling all run inside the function.

### Stream responses

Vercel Functions on the Python runtime support streaming, so you can send data to the client as you produce it instead of waiting for the full response. Use FastAPI's `StreamingResponse` to stream text, server-sent events, or AI model output:

`import asyncio from fastapi import FastAPI from fastapi.responses import StreamingResponse app = FastAPI() @app.get("/stream") async def stream(): async def event_stream(): for chunk in ["Hello", " ", "from", " ", "FastAPI"]: yield chunk await asyncio.sleep(0.2) return StreamingResponse(event_stream(), media_type="text/plain")` Streaming pairs well with Fluid compute: while your function waits between chunks, the same instance can serve other requests. To stream model output to a frontend, pair your FastAPI endpoint with [AI SDK](https://vercel.com/kb/ai-sdk), as the [AI SDK Python Streaming](https://vercel.com/templates/next.js/ai-sdk-python-streaming) template shows.

### Combine FastAPI middleware with Vercel Routing Middleware

FastAPI and Vercel each have a middleware layer, and they solve different problems. FastAPI middleware runs inside your function, after the request reaches it. Use it for app-level concerns such as logging, CORS, and authentication:

`from fastapi import FastAPI, Request from fastapi.middleware.cors import CORSMiddleware app = FastAPI() app.add_middleware( CORSMiddleware, allow_origins=["https://example.com"], allow_methods=["*"], allow_headers=["*"], ) @app.middleware("http") async def log_requests(request: Request, call_next): response = await call_next(request) print(f"{request.method} {request.url.path} -> {response.status_code}") return response` [Vercel Routing Middleware](https://vercel.com/docs/routing-middleware) runs at the edge, before the request reaches your FastAPI app, and works with any framework. Use it for rewrites, redirects, and header changes that should happen before any function runs. Add a `middleware.ts` file at your project root:

`export default function middleware(request: Request) { const url = new URL(request.url); // Redirect an old path before the request reaches FastAPI if (url.pathname === "/old") { return Response.redirect(new URL("/new", request.url), 308); } }`

The two layers work together, with Routing Middleware shaping the request at the edge and FastAPI middleware handling it inside your app.

### Serve static assets from the CDN

To serve static files such as images, fonts, or a favicon, place them in the `public/**` directory. Vercel serves them through its [CDN](https://vercel.com/docs/cdn) using default [headers](https://vercel.com/docs/headers), which you can override in `vercel.json`. FastAPI's own `app.mount("/public", ...)` is not needed on Vercel, so rely on the `public` directory instead.

You can still define routes that point at those files. For example, redirect `/favicon.ico` to an asset in `public`:

`from fastapi import FastAPI from fastapi.responses import RedirectResponse app = FastAPI() @app.get("/favicon.ico", include_in_schema=False) async def favicon(): # /vercel.svg is served from the public/** directory return RedirectResponse("/vercel.svg", status_code=307)`

### Run scheduled tasks with cron jobs

Vercel [Cron Jobs](https://vercel.com/docs/cron-jobs) trigger a route on a schedule by sending an HTTP GET request to it. Define a route in your FastAPI app for the task, then register the schedule in `vercel.json`.

**Define the route:**

`import os from fastapi import FastAPI, Request from fastapi.responses import JSONResponse app = FastAPI() @app.get("/api/cron/cleanup") def cleanup(request: Request): if request.headers.get("authorization") != f"Bearer {os.environ.get('CRON_SECRET')}": return JSONResponse({"error": "Unauthorized"}, status_code=401) # Run your scheduled work here return {"ok": True}`

**Register the schedule:**

`{ "$schema": "https://openapi.vercel.sh/vercel.json", "crons": [{ "path": "/api/cron/cleanup", "schedule": "0 0 * * *" }] }` Vercel runs cron jobs only on production deployments. To stop anyone else from calling the route, set a `CRON_SECRET` environment variable in your [project settings](https://vercel.com/d?to=%2F%5Bteam%5D%2F%5Bproject%5D%2Fsettings%2Fenvironment-variables). Vercel sends it as a `Bearer` token in the `Authorization` header on every cron invocation, and your handler compares it before running the task.

### Set the Python version

FastAPI runs on Vercel's Python runtime, which defaults to Python 3.12. The available versions are 3.12 (default), 3.13, and 3.14. To pin a version, add a `.python-version` file at your project root:

`3.13`

You can also set the version in `pyproject.toml` or `Pipfile.lock`. If you don't define a supported version, Vercel uses the default.

### Manage startup and shutdown with lifespan events

Use [FastAPI lifespan events](https://fastapi.tiangolo.com/advanced/events/) to run setup and teardown logic, such as opening and closing database connections. Vercel runs the startup logic when your function starts and the shutdown logic when it stops:

`from contextlib import asynccontextmanager from fastapi import FastAPI @asynccontextmanager async def lifespan(app: FastAPI): # Startup logic await startup_tasks() yield # Shutdown logic await cleanup_tasks() app = FastAPI(lifespan=lifespan)`

Cleanup during shutdown is limited to 500 ms after your function receives the `SIGTERM` signal, and logs printed during shutdown don't appear in the Vercel dashboard. Keep teardown work short, and move anything longer to a [cron job](https://vercel.com/docs/cron-jobs) or [Vercel Workflow](https://vercel.com/docs/workflows).

### Monitor performance with Observability

[Vercel Observability](https://vercel.com/products/observability) tracks your deployed function automatically, with no setup. Open the [Observability page](https://vercel.com/d?to=%2F%5Bteam%5D%2F~%2Fobservability) in your project to see invocation counts, error rates, and duration for your FastAPI app, along with the requests your function makes to external APIs. On [Observability Plus](https://vercel.com/docs/observability/observability-plus), you also get longer retention and a latency breakdown by path.

## Best practices

### Define your app at a recognized entrypoint

Vercel finds your FastAPI app by looking for an `app` instance at a fixed set of locations: `app`, `index`, `server`, `main`, `wsgi`, or `asgi` (with a `.py` extension) at your project root or under `src/`, `app/`, or `api/`. Put your app at one of these paths so Vercel detects and deploys it correctly, or set `tool.vercel.entrypoint` in `pyproject.toml` to point at a custom module:

`from fastapi import FastAPI app = FastAPI() # Add your routes here`

### Develop with the Vercel CLI

Run `vercel dev` for local development instead of running Uvicorn directly. It serves your app the same way production does, using your `app` instance, so the behavior you test locally matches what you deploy. This also lets you exercise features such as cron routes before shipping.

### Keep your function bundle small

Python functions are not tree-shaken, so Vercel bundles every file reachable at build time, up to a 500 MB limit. List only the packages you need at runtime in `pyproject.toml` or `requirements.txt`, and exclude tests, fixtures, and other development files with `excludeFiles` in `vercel.json`:

`{ "$schema": "https://openapi.vercel.sh/vercel.json", "functions": { "api/**/*.py": { "excludeFiles": "{tests/**,**/*.test.py,fixtures/**}" } } }`

The pattern is a glob relative to your project root, so adjust it to match where your Python files live.

## Resources and next steps

- Read the full [FastAPI on Vercel documentation](https://vercel.com/docs/frameworks/backend/fastapi)
  
- Browse [backend templates](https://vercel.com/templates?type=backend) you can deploy in one step
  
- Learn how the [Python runtime](https://vercel.com/docs/functions/runtimes/python) runs your code
  
- Learn how [Vercel Functions](https://vercel.com/docs/functions) run your server code
  
- Understand pricing and scaling with [Fluid compute](https://vercel.com/docs/fluid-compute)
  
- Run code before requests with [Routing Middleware](https://vercel.com/docs/routing-middleware)
  
- Defer background work from your routes with [Vercel Queues](https://vercel.com/docs/queues), or orchestrate multi-step tasks with [Vercel Workflows](https://vercel.com/docs/workflows)

---

[View full KB sitemap](/kb/sitemap.md)
