App hosting ยท FastAPI and a database

FastAPI with a managed database, both on your private network

An API without a database is a demo. Deploy the FastAPI app from GitHub, create a managed PostgreSQL or MySQL beside it, and give the app the connection URL as an environment variable. The database answers on your private network and nowhere else.

Databases
MySQL 8, PostgreSQL 17, MongoDB 8, Redis 7
First one
Free on every verified account
Reachable from
Your apps and servers, not the internet
App
First app free; paid from $2/mo

Creating the database and wiring it in

  1. Create the database in the panel and pick the engine. The Connect dialog gives you a private hostname, the port, the user, the password and the database name.
  2. Put the URL in the app's environment, for example DATABASE_URL=postgresql+asyncpg://user:password@db-abc123:5432/app.
  3. Read it in code with os.environ["DATABASE_URL"] and hand it to SQLAlchemy, SQLModel, asyncpg or whatever you use.

The first database on a verified account is free; more are $2, $4 or $8 a month by size. Every paid app also includes a one-click MySQL of its own.

Migrations, and where to run them

Alembic in the start command keeps the schema and the code in step on every deploy: alembic upgrade head && uvicorn main:app --host 0.0.0.0 --port $PORT. The migration runs, then the API starts, and a failed migration shows up in the live console instead of as a 500 on the first request.

One thing to know before you scale out: two app instances starting at the same moment both try to migrate. With one app, which is how these plans start, that does not come up. With more, run the migration once from the console and leave it out of the start command.

Connections are the thing people get wrong

A pool of 20 connections per worker, times two workers, is 40 connections from an API that serves a handful of requests a second. Keep the pool small: pool_size=5 with a short pool_recycle is plenty for one uvicorn worker on 1 GB, and it leaves the database room for your other apps and game servers. An async driver with create_async_engine holds fewer connections for the same throughput than a thread per request.

Private by default

Databases answer on your private network, reachable from your apps, bots, game servers and VPS on the same account, and not from the open internet. There is nothing to firewall and no public port to forget about. Connecting from your own machine means joining that private network, or turning on public access for that database when you really need it.

Frequently asked questions

Which hostname and port does the app use?

The private hostname the Connect dialog shows, for example db-abc123, on the engine's usual port. Apps and servers on the account join your private network and resolve it from inside; if the app was already running when you created your first database, restart it once.

Is the database free?

The first database on a verified account is free. More are $2, $4 or $8 a month by size, and every paid app includes a one-click MySQL as well.

Which drivers work?

Anything on PyPI: asyncpg or psycopg for PostgreSQL, aiomysql or PyMySQL for MySQL, with SQLAlchemy or SQLModel on top. The free plan's outbound list already covers the database ports.

Does the data survive a redeploy?

Yes. A redeploy replaces the app's code; the database is a separate service and files under /data are untouched.

Which port does the app listen on?

The PORT environment variable, 8080 by default, on 0.0.0.0. A server bound to 127.0.0.1 answers only itself and the web address gets nothing.

How does the public address work?

Give the app a web address in the panel and it is served at https://name.fadehost.app behind the Cloudflare proxy with a certificate. It comes with the plan on every tier. On the free tier the address sleeps when nobody has used it for a while and wakes on the next request; on a paid tier it stays awake. Your own domain can point at it.

Related

FastAPI with a managed database, both on your private network

Deploy an API and a database