# Instances, projects and the stack

> How a SupaHost instance is built: one VM per customer, one Postgres database per project, which services are shared, how requests are routed and how settings changes reach the server.

Source: https://supahost.app/docs/getting-started/architecture · Updated 2026-11-11

This page explains what runs where on SupaHost. You don't need it to build an app, but it helps when you are planning capacity, reading an error, or deciding how many projects to put on one instance.

## Instances and projects

An **instance** is a cloud VM that runs only your workloads. It isn't shared with other customers. Its size depends on the plan: Builder is a small VM with 2 shared vCPU and 4 GB RAM, Pro a dedicated 2 vCPU and 8 GB, Business a dedicated 4 vCPU and 16 GB. The VM runs Ubuntu 24.04 LTS as a Shielded VM with a static external IP. You choose its region when it's created, and the region can't be changed later.

A **project** is one Supabase project living on that instance. Each project has its own database, users, files, keys and URL. Projects on the same instance can't see each other's data, but they do share the VM's CPU, memory and disk.

Instance and project names become part of every URL:

| What | Address |
|---|---|
| Instance | `https://acme.supahost.space` |
| Project API | `https://app-one.acme.supahost.space` |
| Project Studio | `https://app-one.studio.acme.supahost.space` (opened from the dashboard) |

Project names are 2 to 30 characters: lowercase letters, digits and hyphens, starting and ending with a letter or digit.

## What is shared and what is per project

Some services run once per instance and serve every project. Others run once per project.

| Runs once per instance | Runs once per project |
|---|---|
| Postgres server | Auth (GoTrue) |
| Realtime (multi-tenant, one tenant per project) | Data API (PostgREST) |
| postgres-meta | Storage API |
| Caddy, the HTTPS gateway and router | Edge Functions runtime (only when the project has functions) |
| Studio login gate | Studio (started on demand) |

Studio starts the first time you open it, which takes about 20 seconds, and stops after 30 minutes without use. The Edge Functions container only exists for projects that have deployed at least one function.

## One Postgres server, one database per project

All projects on an instance share one Postgres 17 server. Each project gets its own database inside it, named `p_` plus the project name with hyphens turned into underscores. Project `app-one` uses the database `p_app_one`.

Things that follow from this:

- **Connections are shared.** The server allows 400 connections in total across every project. Each project's Auth and Data API keep small pools of their own (5 connections each), so most of that budget is free for your own work.
- **Size is pooled.** Your plan's database allowance covers the sum of every project's database.
- **One busy project affects the others.** A slow query or a large import in one project uses CPU and memory the rest also need.
- **Postgres isn't on the internet.** Port 5432 listens only on the VM itself. On Business and Enterprise you reach it through a restricted [SSH tunnel](/docs/platform/ssh). On other plans you work through the Data API, Studio, the [MCP server](/docs/ai-tools/mcp) or [exports](/docs/platform/exports).

## How requests reach your project

Caddy terminates HTTPS and routes each request by host name and path:

| Path | Service |
|---|---|
| `/auth/v1/*` | Auth |
| `/rest/v1/*` | Data API |
| `/storage/v1/*` | Storage |
| `/realtime/v1/*` | Realtime |
| `/functions/v1/*` | Edge Functions |

Any other path returns a 404 with the message `no Route matched with those values`. There's no `/graphql/v1` route, so pg_graphql isn't available over HTTP.

Requests need your `apikey` header (or an `?apikey=` query parameter); without it they get a 401 `No API key found in request`. A few paths are exempt, such as email verification links, OAuth callbacks, public Storage objects and Edge Functions, which check their own JWT. If you send `apikey` without an `Authorization` header, the gateway copies the key into `Authorization: Bearer` for you, so a curl call needs only one header:

```bash
curl "https://app-one.acme.supahost.space/rest/v1/recipes?select=id,title" \
  -H "apikey: $SUPABASE_ANON_KEY"
```

## How changes are applied

The SupaHost dashboard doesn't edit your server directly. A control plane runs a reconcile pass about once a minute and writes the desired state for each instance. An agent on the VM applies any change it sees and checks in at least every 2 minutes. In practice this means settings you save, such as Auth providers, redirect URLs or function secrets, take effect within about a minute.

## Versions

The current release (`2026.11.02`) runs these components:

| Component | Version |
|---|---|
| Postgres | `supabase/postgres` 17.6.1.136 |
| Auth | GoTrue v2.197.0 |
| Data API | PostgREST v14.18 |
| Realtime | v2.148.3 |
| Storage | storage-api v1.89.12 |
| Edge Functions | edge-runtime v1.78.1 |
| Studio | 2026.11.02 |

The instance page in the dashboard shows the versions your instance runs, under **Software updates**. Upgrades can run automatically in a maintenance window (03:00-05:00 UTC on the days you choose) or when you click **Upgrade now**, which takes a disk snapshot first.

## Backups and disks

Backups cover the whole Postgres server: a base backup every 24 hours plus a continuous stream of write-ahead log, stored in a private bucket in your instance's region. Restores still work one project at a time; the others aren't touched. Storage files live on the instance disk and aren't in these backups. See [Backups](/docs/platform/backups).

The disk grows by itself once it is 60% full, online and without a restart.

## Related

- [Projects](/docs/platform/projects) and [Instances](/docs/platform/instances)
- [Plans and limits](/docs/platform/plans)
- [Connections and timeouts](/docs/database/connections-and-timeouts)
