Your AI assistant just helped you build a FastAPI application. It works perfectly on localhost. Now you type "how do I deploy this?" and get a confident recommendation for a platform. But AI picks platforms the way it picks variable names, based on what it has seen most often, not based on your specific constraints. This lesson gives you the framework to evaluate that recommendation.
The deployment landscape for Python
Python APIs cannot run on purely static hosting platforms like GitHub Pages or Netlify (those serve HTML/JS only). You need a platform that runs a Python process, specifically, a WSGI or ASGI server like uvicorn or gunicorn.
The good news: in 2026, several platforms make this nearly painless. The bad news: "nearly painless" still requires understanding what is happening under the hood, because when something breaks at 2 AM, the AI is not the one getting paged.
Railway
Railway is the platform AI recommends most often, and for good reason, it has the shortest path from code to deployed URL.
# The entire Railway deployment flow
railway login
railway init
railway up
# That's it. You get a URL.Railway detects your Python project, installs dependencies from requirements.txt, and runs your start command. You can also deploy from a GitHub repo with automatic deploys on push.
| Strength | Limitation |
|---|---|
| Zero-config deployment | Limited free tier (500 hours/month, then $5/month) |
| Built-in PostgreSQL, Redis | No multi-region by default |
| Environment variables UI | Cold starts on free tier |
| GitHub integration | Less control over infrastructure |
Procfile or start command. If your project does not have a Procfile with web: uvicorn main:app --host 0.0.0.0 --port $PORT, Railway may not know how to start your app. Always verify the start command.Fly.io
Fly.io deploys DockerWhat is docker?A tool that packages your application and all its dependencies into a portable container that runs identically on any machine. containers to edge locations worldwide. It gives you more control than Railway but requires more configuration.
fly launch # generates fly.toml and Dockerfile
fly deploy # builds and deploys
fly secrets set DATABASE_URL=postgresql://...Fly.io generates a fly.toml configuration file and expects a Dockerfile. If you followed the Docker moduleWhat is module?A self-contained file of code with its own scope that explicitly exports values for other files to import, preventing name collisions., you already have one.
| Strength | Limitation |
|---|---|
| Global edge deployment (30+ regions) | Requires Docker knowledge |
| Persistent volumes for SQLite | More complex setup than Railway |
| Built-in metrics and logs | Free tier limited to 3 shared VMs |
| Fly Postgres (managed) | Pricing can surprise you (egress costs) |
Render
Render positions itself as the simple PaaSWhat is paas?Platform as a Service - a managed hosting service where you push your code and the platform handles deployment, SSL, restarts, and scaling., somewhere between Railway's zero-config approach and Fly.io's DockerWhat is docker?A tool that packages your application and all its dependencies into a portable container that runs identically on any machine.-based control.
# render.yaml - Infrastructure as Code
services:
- type: web
name: my-api
runtime: python
buildCommand: pip install -r requirements.txt
startCommand: uvicorn main:app --host 0.0.0.0 --port $PORT
envVars:
- key: DATABASE_URL
fromDatabase:
name: my-db
property: connectionString
databases:
- name: my-db
plan: free| Strength | Limitation |
|---|---|
| Infrastructure as code (render.yaml) | Free tier spins down after 15 min inactivity |
| Auto-scaling on paid plans | Cold starts on free tier (30-60 seconds) |
| Managed PostgreSQL and Redis | Slower builds than Railway |
| Preview environments per PR | Limited regions (US/EU only) |
Cloudflare Python Workers
Since 2025, Cloudflare supports Python Workers via Pyodide (a WebAssembly Python runtimeWhat is runtime?The environment that runs your code after it's written. Some languages need a runtime installed on the machine; others (like Go) bake it into the binary.). You can even run FastAPI on it. But it comes with significant constraints.
# worker.py - FastAPI on Cloudflare Workers
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Running on the edge"}
# Deployed via wrangler, runs in V8 isolates| Strength | Limitation |
|---|---|
| Global edge (300+ locations) | Not all Python packages work (no C extensions) |
| Generous free tier | Cold starts for Python Workers |
| D1 database integration | Pyodide runtime has memory limits |
| No Docker needed | Ecosystem is young, fewer examples |
Decision framework
| Scenario | Best fit | Why |
|---|---|---|
| Hobby project, learning | Railway (free tier) | Fastest to deploy, good for experimentation |
| Startup MVP, < 1000 users | Railway or Render | Low ops burden, reasonable pricing |
| Need global low latency | Fly.io | Multi-region edge deployment |
| Enterprise with compliance | AWS ECS / GCP Cloud Run | Full control, audit logs, VPC |
| Simple API, no C deps | Cloudflare Workers | Edge performance, generous free tier |
| ML model serving | Railway or Fly.io | GPU support, larger instance sizes |
Quick reference
| Platform | Deploy method | Database | Free tier | Best for |
|---|---|---|---|---|
| Railway | Git push / CLI | Built-in Postgres | 500 hrs/month | Quick deploys |
| Fly.io | Docker / CLI | Fly Postgres | 3 shared VMs | Global edge |
| Render | Git / render.yaml | Managed Postgres | Spins down | PaaS simplicity |
| Cloudflare | Wrangler CLI | D1 (SQLite) | 100K req/day | Edge APIs |
| AWS ECS | Docker / Terraform | RDS | 12-month trial | Enterprise |