# Supabase compute sizes: Micro, Small, Medium, when to upgrade

> Supabase compute sizes set each project's CPU, RAM and connection limits. Micro is $10 a month, Small $15, Medium $60; upgrade only when metrics show a limit.

Source: https://supahost.app/guides/supabase-compute-sizes · Updated 2026-11-11

Every Supabase project runs on its own Postgres instance, and the compute size decides how much memory, CPU and how many database connections it gets. Micro ($10 a month, covered by the Pro plan's credit) suits most new apps; Small ($15) and Medium ($60) add memory and connections; Large ($110) is the first size with dedicated CPU. Upgrade when your metrics show you're hitting a limit, and only after checking that indexes and queries aren't the real problem.

## Supabase compute sizes compared

Specs are from Supabase's [compute add-ons page](https://supabase.com/docs/guides/platform/compute-add-ons); prices are from [supabase.com/pricing](https://supabase.com/pricing), November 2026.

| Size | CPU | Memory | Max direct connections | Max pooler clients | Price per project |
|---|---|---|---|---|---|
| Micro | Shared | 1 GB | 60 | 200 | $10/mo |
| Small | Shared | 2 GB | 90 | 400 | $15/mo |
| Medium | Shared | 4 GB | 120 | 600 | $60/mo |
| Large | Dedicated, 2 vCPU | 8 GB | 160 | 800 | $110/mo |

Free plan projects run on Nano, which has up to 0.5 GB of memory. Above Large, sizes go from XL (4 vCPU, 16 GB) up to 16XL (64 vCPU, 256 GB); check the compute add-ons page for their current specs and prices.

How it's billed:

- Compute is charged per project, by the hour. A partial hour is billed as a full hour.
- The Pro plan ($25) includes a $10 monthly compute credit, which covers one Micro project. A second Micro project adds $10; moving your only project to Small adds $5.
- Changing size usually means under two minutes of downtime, according to Supabase, though it can take longer.

For how compute fits into the whole bill, see [Supabase pricing explained](/guides/supabase-pricing-explained).

## Micro vs Small vs Medium: what actually changes

The main differences up to Medium are **memory** and **connection limits**. All three share CPU with other workloads.

- **Memory** decides how much of your data and indexes Postgres can keep in cache. When your working set (the rows and indexes you read often) no longer fits, queries start reading from disk and get slower.
- **Connections** matter if you connect directly with many clients, such as serverless functions that each open a connection. Requests through the Data API and the pooler share a smaller number of database connections.
- **CPU** is shared up to Medium. If you need consistent CPU for heavy queries, Large is the first dedicated size.

Supabase also notes that the burst behaviour you may notice on smaller sizes relates to disk IO, not CPU. A workload that reads a lot from disk can be fast for a while and then slow down.

## Signs you need more compute

### CPU stays high

Short spikes are normal. CPU that sits near 100% during normal traffic, with request latency rising at the same time, means the instance is too small or something is doing too much work.

### Memory is tight

Check the cache hit rate. On a healthy app it's usually close to 99%; a steady drop means data no longer fits in memory.

```sql
select
  round(100.0 * sum(heap_blks_hit) / nullif(sum(heap_blks_hit) + sum(heap_blks_read), 0), 2)
    as table_cache_hit_pct
from pg_statio_user_tables;
```

### You run out of connections

Errors like "remaining connection slots are reserved" or "too many clients" mean you've hit the connection limit. See what's holding connections:

```sql
select usename, application_name, state, count(*)
from pg_stat_activity
group by 1, 2, 3
order by count(*) desc;
```

Many `idle` connections usually point to a client that opens connections and doesn't close them, which a pooler fixes better than a bigger instance.

### Queries are slow even with good plans

Use `pg_stat_statements` to find the queries that take the most total time. Enable it from the Extensions list or with `create extension pg_stat_statements with schema extensions;` if it isn't already on ([docs](https://supabase.com/docs/guides/database/extensions/pg_stat_statements)).

```sql
select calls, round(mean_exec_time::numeric, 1) as mean_ms,
       round(total_exec_time::numeric) as total_ms, query
from pg_stat_statements
order by total_exec_time desc
limit 10;
```

If the top queries already use indexes and are still slow because they process a lot of data, more memory or CPU will help.

## What to try before upgrading

A missing index often costs more than a size upgrade would fix. Work through these first.

### Add the right indexes

Run the slow query with `explain analyze` and look for sequential scans on large tables.

```sql
explain analyze
select id, title from posts where author_id = '…' order by created_at desc limit 20;

-- If it shows a Seq Scan on posts:
create index concurrently posts_author_created_idx
  on posts (author_id, created_at desc);
```

Supabase's [index_advisor](https://supabase.com/docs/guides/database/extensions/index_advisor) extension suggests indexes for a given query. Also index foreign key columns and the columns your RLS policies filter on.

### Make RLS policies cheap

Row Level Security runs on every row a query touches. Wrapping `auth.uid()` in a subquery lets Postgres evaluate it once per statement instead of once per row:

```sql
create policy "Users read own posts" on posts
for select using ((select auth.uid()) = author_id);
```

More in our [Supabase Row Level Security guide](/guides/supabase-row-level-security).

### Return less data

Select only the columns you need and paginate. Use keyset pagination (`where created_at < $last order by created_at desc limit 20`) instead of large offsets on big tables. This also cuts [egress](/guides/supabase-egress).

### Fix connection handling

Send serverless and edge traffic through the pooler instead of opening direct connections, and reuse one client per process in long-running servers.

### Move heavy work off the busy hours

Reports, cleanups and bulk updates can run at night with pg_cron. See [Supabase pg_cron](/guides/supabase-pg-cron).

## Which size to choose

| Situation | Reasonable size |
|---|---|
| New app, prototype, low traffic | Micro |
| Cache hit rate dropping, working set over 1 GB | Small |
| Several GB of hot data, or more direct connections | Medium |
| CPU-bound queries that need consistent performance | Large or above |

Upgrade one step, watch the metrics for a few days, and move again only if the same limit is still the bottleneck.

## How SupaHost sizes differ

[SupaHost](/pricing) runs the open-source Supabase stack on one VM dedicated to your account. Instead of sizing each project, you choose a plan, and every project on the instance shares that server's CPU, RAM and disk.

| Plan (November 2026) | Server | Projects included | Price |
|---|---|---|---|
| Builder | Small VM, 2 shared vCPU, 4 GB RAM | 5 | $25/mo |
| Pro | Dedicated VM, 2 vCPU, 8 GB RAM | 15 | $49/mo |
| Business | Dedicated VM, 4 vCPU, 16 GB RAM | 30 | $99/mo |

SupaHost's load tests (a typical app where 5% of monthly users are active in the busiest hour) give rough capacity guides:

| Plan | Monthly active users | Concurrent Realtime connections | API reads per second |
|---|---|---|---|
| Builder | ~25,000 | ~5,000 | ~300 |
| Pro | ~50,000 | ~15,000 | ~540 |
| Business | ~100,000 | ~30,000 | ~950 |

These numbers are for the whole instance, not per project. Changing plan resizes the VM, with about a minute or two of downtime.

The trade-offs: a busy project can slow the others on the same instance, and SupaHost has no connection pooler (Supavisor) and no read replicas. If you have one large project that needs big dedicated compute, read replicas or a pooler for thousands of serverless connections, Supabase Cloud's larger sizes are the better choice. The shared model works out cheaper when you run many small and medium projects that would each need their own compute on Supabase. Compare details on [SupaHost vs Supabase Cloud](/compare/supabase-cloud), or estimate your own case with the [pricing calculator](/supabase-pricing-calculator).

## FAQ

### What is the default Supabase compute size?
Free plan projects run on Nano. On paid plans the smallest size you're billed for is Micro (Supabase bills Nano at the Micro price on paid organizations), and the Pro plan's $10 compute credit covers one project at that size.

### What is the difference between Supabase Micro and Small?
Small doubles memory from 1 GB to 2 GB and raises the limit from 60 to 90 direct connections and from 200 to 400 pooler clients. Both use shared CPU. Small costs $15 a month against Micro's $10 (November 2026).

### Does upgrading Supabase compute cause downtime?
Yes, briefly. Supabase says compute changes usually apply with under two minutes of downtime, though it can take longer depending on the cloud provider. Plan the change for a quiet period.

### How do I know if I need more Supabase compute?
Look for CPU near 100% during normal traffic, a falling cache hit rate, connection limit errors, or slow queries that already use indexes. If a missing index or an inefficient RLS policy explains the slowness, fix that first.

### Is Supabase compute billed per project?
Yes. Each project is billed for its own compute by the hour, so ten Micro projects cost $100 a month in compute, minus the $10 credit, on top of the $25 Pro plan.

### Can several Supabase projects share one compute instance?
Not on Supabase Cloud, where each project has its own. On SupaHost, all projects on an instance share one VM, which is why the price is per plan rather than per project. Self-hosting Supabase works the same way; see [how to self-host Supabase](/guides/self-host-supabase).
