Why Starlette fits Phemeral
No adapters, no wrappers, no config.
One line of config, and only once
Phemeral figures out what dependencies you're using and what version of Python you're using. Set a start command once and never think about it again.
Runs serverlessly without compromises
Websockets and SSE are supported. And even though your app is running on serverless infra, it runs with uvicorn just like normal. So, no more adapters to get your app running for serverless (Mangum).
Free concurrency even if you didn't write async
Since each request is handled in an ephemeral serverless environment, concurrent requests won't block each other. Even if your app isn't using asyncio.
Lightning fast cold starts.
When scaling up, your app goes from dead to alive in less than 50 ms. Pretty darn fast.
Deployment model
Github integration gives you CI/CD. New deployments are triggered on pushes to your repo.
- 01
Push
A push triggers a deployment.
- 02
Detect
Python version, framework, package manager, project root and entry point are detected from source.
- 03
Build
Dependencies are installed, the project is built.
- 04
Live
The deployment is assigned a URL and any custom domains you've set up will route to the latest deployment.
Platform features you need for a Starlette app
Environments
Production, Staging, and Development are created with every project. Make as many other environments as you need too.
Environment variables
Manage your environment variables for your app. Set env vars for each of your environments.
Custom domains
Use your custom domains for your hosted apps.
Build and runtime logs
Observability you need. Monitor build logs as your deployment is built, and runtime logs as it runs. Catch bugs before they're bugs.
Custom start command
Set a custom start command if you're doing something fancy.
CRON jobs
Set up CRON jobs to make requests to your deployment on whatever schedule you want.
Everything around the app
Databases, static files, background work and scaling.
- Databases
Provision managed serverless Postgres clusters inside the project.
Our managed serverless Postgres scales up and down to match your traffic
- Static files
Mount StaticFiles as a route to serve assets from the app.
Mount("/static", StaticFiles(directory="static"))
- Background work
Scheduled webhooks cover recurring jobs: cache warming, maintenance endpoints, and application-level tasks triggered on a schedule.
0 0 3 * * * → every day at 03:00 UTC
- Scaling and connections
Deployments scale to zero when idle and up on demand.
A minimal Starlette project
That's all you need. No config files to be found.
Repository
my-project/
├── .python-version
├── pyproject.toml
├── uv.lock
└── app/
└── main.pyapp/main.py
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route
async def read_root(request):
return JSONResponse({"message": "Hello, World!"})
app = Starlette(routes=[Route("/", read_root)])Set uvicorn app.main:app --host 0.0.0.0 --port 8000 as the start command.
Read the full tutorial
All docs- Deploy Your First ProjectProject, repository, branch mapping, first push.
- Project Structure RequirementsProject root, dependency priority, entry point.
- Supported FrameworksServers, protocols and package managers.
- WebSockets & SSEReal-time connections, keepalives, billing.
- Managed PostgresCreate a cluster and connect your app.
- Set a Custom Start CommandOverride the autodetected command.