The Best FastAPI Hosting Platforms in 2026
FastAPI hit the sweet spot: type hints give you validation and OpenAPI docs for free, and async gives you real concurrency without the ceremony. Writing one is a joy. Deploying one is where people quietly get it wrong — usually not because the platform is bad, but because the defaults of ASGI serving, worker counts, and background tasks interact with a platform's execution model in ways nobody documents together.
I'm Ajay, I build PandaStack, so treat this as a vendor's roundup — I cite concrete numbers only for my own platform and describe the others qualitatively from their public docs. What I want you to leave with is less 'which logo wins' and more 'which execution model matches the API I actually wrote.'
What actually decides fit for a FastAPI app
- Long-lived process or per-request invocation — FastAPI's async model assumes a process that stays up: connection pools, in-process caches, WebSockets, startup events. Serverless function platforms break some of those assumptions in ways that are invisible until traffic arrives.
- Background tasks — `BackgroundTasks` runs work after the response is sent, in the same process. On a platform that freezes or reclaims your container the moment the response goes out, that work silently doesn't happen.
- Cold starts — a Python API with pandas, SQLAlchemy, and a few ML libraries can take seconds to import. Whether that import cost is paid once at deploy or on every scale-from-zero event is the single biggest latency difference between platforms.
- Database proximity — an async API is only as fast as its connection pool. A managed Postgres two regions away undoes every microsecond FastAPI saved you.
- Idle cost — most internal APIs and side projects serve traffic a few hours a day and idle the rest. Whether you pay for that idle is a bigger line item than the per-request rate.
The 2026 field
Render and Railway
The default answer for good reason: connect a repo, set a start command, get a URL and a managed Postgres in the same click-path. Both run a long-lived process, so async, background tasks, and WebSockets behave the way FastAPI's docs assume. Pick either if your priority is 'stop thinking about infrastructure today.' The caveat on both is idle: a small always-on service bills continuously, and the free tiers that used to soak that up have narrowed across the industry.
Google Cloud Run
The strongest of the container-serverless options for FastAPI, because it scales to zero and still gives you a real container with a real process. The two things to internalize: you need a Dockerfile (or a buildpack), and the CPU-throttling behavior outside a request is what breaks background tasks — Cloud Run has settings to control this, but the default trips people. If you're comfortable with containers and want zero idle cost with real scale-out, it's an excellent fit.
AWS Lambda with Mangum
Yes, you can run FastAPI on Lambda by wrapping the ASGI app in an adapter. It works, and it's cheap for spiky, low-volume APIs. But you're mapping a long-lived async server onto a per-invocation model: background tasks are unreliable, WebSockets need a separate API Gateway path, connection pooling fights the execution model, and a heavy import tree makes cold starts painful. Good for webhooks and thin CRUD; a poor fit for anything stateful or latency-sensitive.
A plain VPS
systemd + uvicorn workers + nginx + certbot on a $6 box still works, still costs almost nothing, and still requires you to own OS patching, TLS renewal, deploys, and the 3am restart. Genuinely correct for a hobby API or an internal tool. It stops being correct the moment more than one person depends on it.
PandaStack
Ours: point it at a Git repo and it builds and runs your FastAPI app inside a Firecracker microVM — no Dockerfile, no container registry. Runtime version comes from your repo the idiomatic way (`.python-version`, `.tool-versions`, or `mise.toml`), dependencies install from whatever manager the repo actually uses (requirements.txt, Poetry, uv, or Pipenv), and the process runs long-lived, so async, startup events, and background tasks behave normally. It scales to zero between requests and bills nothing while asleep; an always-on app at 2 vCPU / 4 GiB is about $29/month at $0.004 per vCPU-hour plus $0.008 per GiB-hour.
# The start command that works on essentially every platform here.
# Bind 0.0.0.0 (not 127.0.0.1) and read $PORT from the environment --
# hardcoding either is the #1 reason a FastAPI deploy health-checks red.
uvicorn app.main:app --host 0.0.0.0 --port $PORT
# Multi-worker, for CPU-bound endpoints mixed into an async app:
gunicorn app.main:app \
--worker-class uvicorn.workers.UvicornWorker \
--workers 2 \
--bind 0.0.0.0:$PORTfrom pandastack import Client
ps = Client()
# A managed Postgres on the same substrate as the app. create() blocks
# until the database is ready and returns its connection credentials.
db = ps.databases.create(label="orders-db")
app = ps.apps.create(
name="orders-api",
git_url="https://github.com/acme/orders-api",
git_branch="main",
framework="python",
# Python is commands-first: install is inferred from your dependency
# manager, but the start command is yours to declare.
start_command="uvicorn app.main:app --host 0.0.0.0 --port $PORT",
port=8000,
env={"DATABASE_URL": db["connection_url"]},
)
deploy = ps.apps.deploy(app["id"])
for line in ps.apps.deploy_logs(app["id"], deploy["id"]):
print(line, end="")Four gotchas that bite every FastAPI deploy
These are platform-independent and they account for most of the 'it works locally' tickets I see.
- Binding to 127.0.0.1. Uvicorn's default host is localhost, which is unreachable from outside the container or VM. Every managed platform health-checks your app from somewhere else on the network, so a localhost bind reads as a dead app. Always `--host 0.0.0.0`.
- Worker count copied from a blog post. `workers = 2 * cores + 1` is Gunicorn-for-WSGI advice. An async FastAPI app handles concurrency inside one process; extra workers multiply your memory footprint and your database connections for little gain unless you have genuinely CPU-bound handlers. Start with one worker per core, measure, then change it.
- Connection pools sized per process, not per app. Every worker opens its own pool. Four workers with a pool of 20 is 80 connections from one service — enough to exhaust a small Postgres on its own, before your other services connect at all.
- Blocking calls in async handlers. One `requests.get()` or a synchronous ORM call inside an `async def` blocks the entire event loop, not just that request. Under load this looks exactly like 'the platform is slow.' Use `def` handlers (FastAPI runs them in a threadpool) or an async client.
Picking one
- Shipping today, don't want to think — Render or Railway.
- Already fluent in containers, want zero idle cost — Cloud Run.
- Spiky low-volume webhooks, cost-sensitive, no WebSockets or background work — Lambda with Mangum.
- Hobby project, total control, near-zero budget — a VPS.
- You want no Dockerfile, a long-lived process, zero-cost idle, and a Postgres on the same substrate — that's the PandaStack case.
The summary
The FastAPI hosting decision isn't really about hosting — it's about whether the platform's execution model matches the one FastAPI assumes. If your app relies on a process that stays alive between requests, pick something that gives you one. If it's genuinely stateless request-in, response-out, the serverless options get cheaper. And whatever you pick, bind 0.0.0.0, read $PORT, and size your connection pool per worker rather than per service.
Frequently asked questions
Do I need a Dockerfile to deploy FastAPI?
It depends on the platform. Cloud Run and most Kubernetes-based options effectively require a container image. Render, Railway, and PandaStack build from the repo directly — you declare a Python version the idiomatic way (a .python-version or .tool-versions file), the platform installs from your requirements.txt, Poetry, uv, or Pipenv setup, and runs the start command you give it. A Dockerfile is still useful when you need system packages beyond what the base image ships, but it isn't a prerequisite.
How many uvicorn workers should a FastAPI app run?
Start with one worker per CPU core and measure before changing it. The `2 * cores + 1` rule circulating in tutorials comes from synchronous WSGI deployments; an async FastAPI app already multiplexes many concurrent requests inside a single process, so extra workers mostly multiply memory usage and database connections. The exception is genuinely CPU-bound handlers, which do block the event loop and benefit from real parallelism — but the better fix there is usually moving that work off the request path entirely.
Why do FastAPI BackgroundTasks silently stop running in production?
Because BackgroundTasks executes after the response is sent but still inside the same process, and several platforms either throttle CPU or reclaim the instance once the response goes out. On per-invocation platforms like Lambda the instance can be frozen immediately; on container-serverless platforms CPU outside a request may be throttled by default. If the work matters, either run on a platform with a genuinely long-lived process, or move it to a real queue or scheduled job where completion is observable.
What is the cheapest way to host a FastAPI app that gets very little traffic?
For genuinely intermittent traffic, a platform that scales to zero beats a small always-on instance, because you stop paying for the many idle hours. The trade-off is the first request after an idle period pays a startup cost, and a Python API with a heavy import tree can make that noticeable. Snapshot-based platforms mitigate this by restoring a pre-warmed process image rather than re-importing from scratch. A cheap VPS is also perfectly reasonable at this scale if you're willing to own the operations.
Can I run FastAPI and its Postgres on the same platform?
On most of the options here, yes — Render, Railway, and PandaStack all offer managed Postgres alongside app hosting, which matters more than it sounds because network round-trips between your API and its database are usually the dominant latency in a CRUD service. Keeping both in the same region (ideally the same substrate) removes a class of latency you cannot optimize away in application code.
Keep reading
- Deploying a FastAPI app without Docker
- The best Python hosting platforms in 2026
- Connecting an app to managed Postgres with an ORM
- Scale-to-zero app hosting, explained
- Git-driven app hosting on PandaStack — no Dockerfile, long-lived process, scale to zero
49ms p50 cold start. Fork, snapshot, and scale to zero.