What is the best FastAPI hosting in 2026?
FastAPI is an ASGI application, so what matters is long-lived connections, a worker count you choose yourself, and a database pool that does not multiply per worker. Render's free tier is the easiest place to put an API someone else has to call, and $7/month buys the smallest paid instance; Fly.io keeps one online from roughly $2/month; Cloud Run charges nothing while a mostly-idle JSON API waits.
Granite — our own platform — is $9/month with $15 of usage credits, and fits when the API has managed Postgres, a Valkey and a worker behind it, with the pool opening inside the same private network.
Last updated 1 September 2026
Every platform below will run FastAPI. What differs is everything around the event loop: whether a websocket survives more than a minute, whether the managed Postgres in the next box has enough connections for the number of workers you are about to start, and where the background job goes once you accept that BackgroundTasks is not a queue.
It is also worth being honest about cost. FastAPI is lighter than Django and heavier than Go. Async means one process can hold thousands of idle connections, but it does not make the interpreter smaller: each uvicorn worker still loads Python, your application and, on a typical API, Pydantic and SQLAlchemy behind it. You size the plan by worker count, exactly as you would for gunicorn — you simply need fewer workers for the same amount of concurrency.
The short version: Render is the easiest free place to put an API someone else needs to call, Fly.io is the cheapest way to keep one online, Cloud Run fits a JSON API that is idle most of the day, and Granite — our own platform — fits when the API has a Postgres, a Valkey and a worker behind it. If your service is a single stateless endpoint with no database, several options here are cheaper than we are, and the table says so.
One absence worth explaining: PythonAnywhere appears on our Django and Flask comparisons and not here. Its ASGI support is still an explicitly experimental, command-line-only feature, which is not where a production API belongs.
How much does FastAPI hosting cost?
| Provider | From /mo | Free tier | Managed DB | Persistent disk | Deploy from |
|---|---|---|---|---|---|
| Fly.io | ~$2 | Postgres (unmanaged app) | Dockerfile, buildpack | ||
| Railway | $5 | yes ($1 credits) | Git, Dockerfile, template | ||
| Render | $7 | yes (spins down) | Git, Dockerfile | ||
| Granite | $9 | from Advanced | Git, Docker image | ||
| Koyeb | $29 | limited | Serverless Postgres | Git, Dockerfile | |
| Google Cloud Run | usage-based | yes (monthly allowance) | via Cloud SQL | no (use GCS) | Container image |
Entry prices as published by each provider on 1 September 2026, sorted cheapest first. Usage, bandwidth and databases are billed on top almost everywhere — treat this column as a starting point, not a monthly bill.
PaaS, serverless or a plain VPS?
A VPS is always cheaper per gigabyte. What a platform sells you is everything around uvicorn: TLS and its renewal, zero-downtime rollouts, log collection, and Postgres backups someone else is responsible for restoring. For an API that other systems depend on, the last one is usually the whole argument.
Serverless fits FastAPI better than it fits Django and worse than it fits a compiled binary. Booting Python and importing your application takes a second or two rather than milliseconds — survivable for an internal API, noticeable on a public one. The harder limit is structural: request-driven platforms bound a connection by the request, so websockets and server-sent events, the two things people most often reach for FastAPI to build, are exactly what does not fit.
A managed platform is where most production FastAPI ends up, for an unglamorous reason. The API is rarely alone: there is a database, usually a Redis or Valkey, and usually a worker consuming the jobs the API refuses to do inline. The value is in having them in one project with one deploy, not in shaving two dollars off the web tier.
The API is backed by a database, and probably holds websockets or SSE open
Managed platform
API, worker and Postgres in one project, with connections nobody closes for you.
Granite · Railway · Render
Plain request/response JSON, bursty or mostly idle, nothing long-lived
Serverless
Free while idle — at the price of a cold start and a connection pool per instance.
Cloud Run · Koyeb
Latency to users decides, or you would rather own the machine
Fly.io or a VPS
Closest to the caller, or cheapest per gigabyte with the operations kept in-house.
Fly.io · Hetzner · DigitalOcean
What does each platform actually give you?
Fly.io
- Best for
- The cheapest way to keep a small async API online, and the best option if callers are spread across regions.
- Pricing
- Pay as you go. The smallest shared-cpu-1x machine with 256 MB RAM works out at roughly $2.02/month, billed per second.
- Cheapest entry point in this table, and an async API holds a lot of concurrency per megabyte.
- Multi-region deployment and Anycast routing are first-class, which matters when latency is the product.
- Takes your Dockerfile, so a slim multi-stage Python image ships exactly as you built it.
- Per-second billing, so stopped machines cost only storage.
- The headline ~$2 machine is 256 MB, which is tight once SQLAlchemy and Pydantic are loaded into more than one worker — the price applies to a single small process, not to a worker set.
- Postgres is a Fly app you operate and back up yourself.
- No free tier for new organisations since October 2024.
Railway
- Best for
- Getting FastAPI, Postgres and Redis running together the same afternoon.
- Pricing
- Billing is per second of actual usage against a monthly minimum: $5 on Hobby and $20 on Pro, each including that much usage credit. The free plan is a 30-day trial with $5 of credits and $1 a month afterwards, capped at 1 vCPU and 0.5 GB per service. Pro includes unlimited workspace seats.
- Detects a Python project and runs your start command without configuration.
- Postgres and Redis sit in the same project, which is what an ARQ or Celery worker needs.
- A free plan and a 30-day trial, so you can evaluate without a card.
- Usage-based billing on top of the base fee makes the monthly cost hard to forecast.
- Hobby allows a single developer per workspace; a shared project needs Pro and its $20 monthly minimum.
Render
- Best for
- A free URL for an API other people need to call, and a simple paid tier once it is real.
- Pricing
- Free web services are available but spin down after 15 minutes without traffic. The cheapest paid instance, Starter, is $7/month for 0.5 vCPU and 512 MB RAM.
- A genuine free tier for web services, which is rare and ideal for an API a front end is being built against.
- Managed Postgres, Redis, background workers and cron jobs in one account.
- Websockets are supported on ordinary web services rather than being a separate product.
- Free services spin down after 15 minutes idle, and every open websocket dies with them.
- The $7 Starter tier is 512 MB, comfortable for two uvicorn workers and tight beyond that.
Granite
- Best for
- An API that is one part of a system — with the Postgres, the Valkey and the worker it depends on in the same project.
- Pricing
- Hobby is $9/month and includes $15 of monthly usage credits. Advanced is $39/month with $50 of credits, Professional $149/month with $200. Every plan has unlimited workspace seats.
- Managed Postgres, MySQL and Valkey run beside the app over internal DNS, so the async driver talks to the database over a private network rather than the public internet.
- Databases have no public endpoint at all — they stay inside the cluster.
- The API, an ARQ or Celery worker and a cron job are separate resources built from the same image, so the worker can never run older code than the API.
- S3-compatible storage with a CDN is in the same project, which is where uploaded files belong.
- Flat plan pricing with usage credits, so a traffic spike does not change the invoice.
- No free tier — the cheapest way in is $9/month, which is the wrong shape for an API you are still prototyping.
- Persistent volumes start on the Advanced plan.
- Fewer regions than the hyperscalers, and no multi-region routing yet.
Koyeb
- Best for
- Edge presence with scale-to-zero for an API that is idle most of the day.
- Pricing
- Pro is $29/month plus compute and includes $10 of it; Scale is $299/month including $100. Serverless Postgres has a free tier of 5 hours a month at 0.25 vCPU, 1 GB RAM and 1 GB of storage, after which the smallest always-on instance is $29.76/month plus $0.50 per GB stored.
- Edge locations included rather than sold separately.
- Managed Postgres available without leaving the platform.
- A Python cold start is seconds rather than tens of seconds, so scale-to-zero is at least defensible here.
- The highest entry price of any managed option in this table.
- Scale-to-zero and websockets do not mix: an instance that sleeps takes every open connection with it.
Google Cloud Run
- Best for
- A request-driven JSON API with bursty traffic, for teams already inside GCP.
- Pricing
- No monthly fee. You pay per request and per resource-second, with a monthly free allowance. Cloud SQL and networking are billed separately.
- Scales to zero, so an idle API is genuinely free.
- Takes any container image, so a slim multi-stage build deploys unchanged.
- Effectively unlimited scale ceiling if something takes off.
- Instances are request-scoped, so websockets and server-sent events are bounded by the request timeout rather than by your application.
- No persistent disk, so uploads must go to Cloud Storage before the first deploy.
- Every instance opens its own connection pool, and autoscaling multiplies that by the instance count — the fastest way to exhaust a Postgres without noticing.
- Database, secrets and networking are separate GCP products you assemble and bill separately.
What does a FastAPI app need from a host?
- ASGI, not WSGI
- FastAPI cannot be served by gunicorn's default sync worker — that worker speaks WSGI and your application does not. You need uvicorn, either directly with its own worker management or as a gunicorn worker class. Any platform whose Python support means "we run gunicorn for you" with no way to override the command is the wrong platform.
- Workers, not magic
- One uvicorn worker uses one CPU core, however async your code is. Concurrency inside a worker is free; parallelism across cores is not. Memory scales with the worker count — each is a full interpreter with your application loaded — so size the plan by processes, and prefer more replicas of a small container over one large one where the platform lets you.
- Connections multiply
- Your Postgres connection count is pool size × workers × replicas, and it is almost always larger than people expect. A managed database with a hundred-connection ceiling disappears quickly under autoscaling. Either cap the pool deliberately or put PgBouncer in front — and if you use asyncpg through a pooler in transaction mode, disable the prepared-statement cache or you will get errors that only appear under load.
- Idle timeouts on long-lived connections
- Websockets and server-sent events are the reason many teams choose FastAPI, and every platform puts a proxy in front of your container that closes idle connections after some interval it rarely documents. Send an application-level ping on a timer, and confirm the platform's timeout before you promise anyone a live feed.
- Never block the event loop
- One synchronous call inside an async def — a requests call, a blocking driver, a CPU-bound loop — stalls every other request that worker is handling. A plain def endpoint is safe because FastAPI runs it in a threadpool; an async def one is not. This shows up as latency that gets worse with traffic and looks exactly like an undersized instance.
- BackgroundTasks is not a queue
- Tasks scheduled after a response run inside the same process, with no retries and no persistence. A deploy, a crash or a scale-down loses them silently. Anything that must actually happen belongs in a real worker — ARQ, Celery or Dramatiq — which means the platform needs somewhere to run a long-lived process that is not a web service.
- Readiness after lifespan
- The lifespan startup is where the connection pool is opened and caches are warmed. If the platform routes traffic as soon as the port is listening, the first requests after every deploy hit an application that is not ready. Point the health check at an endpoint that reports on the pool, not at the root path.
- The docs are public by default
- /docs, /redoc and /openapi.json are served without authentication unless you disable or protect them. For an internal API that is a complete map of your surface area published on the internet. Decide deliberately per environment rather than discovering it in a pentest report.
Where do background jobs and queue workers run?
BackgroundTasks runs inside the same uvicorn process that served the request, which makes it right for sending a confirmation email and wrong for anything you would miss: a rolling deploy or an OOM kill takes the task with the container, and nothing anywhere knows it did not finish. Durable work needs a broker and a consumer — arq and Dramatiq both sit naturally beside an async codebase, Celery if the rest of the team already knows it. The consumer is a separate long-lived process, arq app.worker.WorkerSettings, from the same image as the API. On Granite that is a worker resource with a managed Valkey beside it, both inside one application and reachable over internal DNS. The worker deploys in the same step as the API, so a task signature and the handler that enqueues it never ship apart.
How do scheduled tasks and cron work?
arq has its own cron definitions, evaluated by the worker rather than by the web process, which is already the right shape: the schedule lives where exactly one consumer claims each occurrence. An asyncio task started in the lifespan handler is the version that goes wrong, because it starts again in every uvicorn worker in every replica. When the job is a command rather than a queue entry, a platform cron is simpler still — on Granite a cron-job resource runs python -m app.tasks.reconcile as a single container on a cron expression, with Forbid or Allow deciding what an overrun does.
Is Postgres managed, and what about backups?
Managed on Render, Railway, Koyeb and Granite; on Fly you run it; on Cloud Run it is Cloud SQL beside the service. Granite's backups run on a schedule into external storage, with point-in-time recovery for Postgres available from support on request and no published interval — confirm it before you rely on one. The database has no public address, so the app uses internal DNS and you use novps port-forward database <id> -l 5432. Async connection pools are the sharp edge here: asyncpg holds its pool per event loop, so four uvicorn workers with a max size of ten is forty connections per replica, and a small managed instance runs out long before your traffic does.
How do deploys and migrations work?
From a Git push that builds the image, or from a Docker tag the platform watches for a new digest. alembic upgrade head has to run once per deploy — Render and Railway have a release command, and Granite has no such hook, so the migration goes through the resource's Console tab or a forwarded database port before the new image rolls. Running it from the start command means every uvicorn container attempts the same revision at once. Since a rollback returns the image and not the schema, expand-then-contract migrations are worth the extra deploy: add the column, ship the code, drop the old one later.
What does it actually cost per month?
An API, an arq worker, a Postgres and a broker, as of 1 September 2026. Fly.io is $3.32 per 512 MB machine and a database you operate. Render is $7 plus $7 plus $6 for a 256 MB Postgres plus $10 for a 256 MB Key Value instance — $30. Cloud Run charges $0.000018 per vCPU-second with 180,000 free monthly, which flatters an idle API and does nothing for a worker that must stay awake to poll. Granite is $9 with $15 of shared credits, $8 of which the Extra Small Valkey node takes, inside a per-service ceiling of 1 vCPU and 1 GiB on Hobby.
So which should you pick?
An API a front end is being built against. Render's free tier. A real URL, no card, and the spin-down after idle costs a few seconds that nobody on your own team will mind.
The cheapest way to keep it online. Fly.io, at roughly $2/month — as long as you stay honest about the worker count that fits in 256 MB.
A JSON API that is idle most of the day. Cloud Run. Scaling to zero makes an idle service genuinely free; cap the connection pool per instance before you turn on autoscaling, and do not plan on websockets.
An API with a database, a cache and a worker behind it. This is where we would argue for Granite. Postgres and Valkey sit in the same project with no public endpoint, the async driver reaches them over internal DNS instead of the open internet, and the API, the worker and the cron job are three resources built from one image — so the worker cannot drift onto older code than the endpoint that enqueued the job. From $9/month with $15 of usage credits.
Comparing frameworks rather than platforms? The Django, Flask and Go comparisons cover the same platforms with different conclusions, and the app platform page covers workers and cron jobs in detail.
Hosting for other stacks
Six ways to run a Go binary, from a $2 machine to scale-to-zero — and why Go stays cheap longer.
Seven options weighed on the things Django actually needs: media storage, a real Postgres, Celery workers and enough memory for gunicorn.
Vercel and six alternatives, weighed on the things that actually break when you self-host: ISR across replicas, image optimization and build-time env vars.
Six ways to run an Express, NestJS or Fastify service — weighed on the event loop, the connection pool, and what a long-lived process costs while it waits.
Six platforms plus Kamal, weighed on what Rails really needs: a release phase for migrations, a job runner, Active Storage and enough memory for Puma.
Laravel Cloud and six alternatives, weighed on queue workers, the scheduler, writable storage and the caches you must rebuild on every deploy.
Seven platforms for Django, Flask, FastAPI or a script with no HTTP port at all — and how to tell which of those you are actually deploying.
Seven options for the framework that ships no opinions — weighed on the WSGI server you have to bring, the session key you must keep stable, and the extensions that decide the rest.
Six platforms weighed on the things Symfony assumes: a warmed cache built at build time, Messenger workers that restart on deploy, and Doctrine migrations that run exactly once.
Seven platforms for a framework that renders on every request — weighed on streaming, adapters, and how far the loaders sit from the database.
Six platforms weighed on what the JVM actually asks for: memory it is allowed to use, a container that knows its own limits, and a start-up you can afford to repeat.
Six places to run a container image, compared on what actually bites: architecture mismatches, registry access, signal handling and the volume you assumed would still be there.
Five ways to serve HTML that is already written — and an honest note about which of them we are not the right answer for.