Supabase preview-branch compute sizing & a CI parity model
The problem
Section titled “The problem”With the Supabase GitHub App’s Automatic branching enabled, every pull request spins up its own preview branch (a full, isolated Supabase project). That branch always provisions on the Micro compute tier (1 GB RAM), and there is no setting anywhere to change that default.
Micro is fine for steady-state use, but resetting a branch tears down all
tables/buckets and replays every migration + reseed - effectively a
supabase db reset. On a non-trivial schema, that replay can exhaust Micro’s
1 GB and fail with an out-of-memory error. The manual fix is to open the branch’s
infrastructure menu, bump Micro -> Small, then reset again - per branch, by hand.
This guide shows what’s actually configurable, the cost delta, and three approaches to get branches off Micro: keep auto-branching and resize after creation via the compute add-on, take over the lifecycle and create at the size you want, or bump it by hand. It also covers the feature-parity gaps and an IPv6 gotcha you inherit when you own the lifecycle.
Prerequisites: a SUPABASE_ACCESS_TOKEN in repo secrets, the parent project
ref as SUPABASE_PROJECT_ID, and the Supabase CLI in CI
(supabase/setup-cli@v2) - full list in the Secrets & setup tab below. The
restart numbers quoted for resizes were measured separately in
what a platform operation costs,
which this guide relies on rather than re-measures.
Where compute size can be set
Section titled “Where compute size can be set”Size is settable two ways: at branch creation (CLI or Management API), or after creation by applying a compute add-on to the branch (a branch is a project, so the project billing API applies to it). The one place it is not settable is the auto-branching flow itself - there is no default-size knob.
| Surface | Size knob? | Notes |
|---|---|---|
supabase branches create --size <tier> | ✅ | A branch created with --size small provisions ci_small (2 GB). |
POST /v1/projects/{ref}/branches (desired_instance_size) | ✅ | Enum pico|nano|micro|small|medium - API caps branches at medium at creation. |
PATCH /v1/projects/{branch_ref}/billing/addons (resize existing) | ✅ | {addon_type:"compute_instance", addon_variant:"ci_small"} scales an existing branch up/down - to ci_xlarge. Restarts Postgres. The cost was measured on project resizes, not on a branch: Micro -> Small cost 131 s of Auth downtime up and 99 s down, with the pooler out for 207 s / 196 s, while REST and Realtime never dropped a sample (platform-downtime D03/D04, 2026-08-04); a Small -> Large step on another rig produced 17.0 s of contiguous REST failure (compute-disk D09, 2026-08-19) - see what a platform operation costs. |
DELETE /v1/projects/{branch_ref}/billing/addons/{variant} | ✅ | Reverts the compute add-on to the previous size. |
PATCH /v1/branches/{ref} (branch metadata) | ❌ | Body has branch_name / git_branch / reset_on_push / persistent / status / notify_url only - no size field. |
supabase branches update | ❌ | No --size flag. |
config.toml | ❌ | Syncs DB/API/Auth/seed/function settings to branches, but carries no compute-size key. |
| GitHub integration UI (auto-branching) | ❌ | Exposes only Automatic branching, Branch limit, Supabase changes only - no default-size setting. |
The takeaway: auto-created PR branches always come up Micro, but you have two programmatic levers to get a larger tier - create the branch yourself at the size you want, or let auto-branching create it Micro and then resize it via the compute add-on.
Cost delta
Section titled “Cost delta”From GET /v1/projects/{ref}/billing/addons:
| Tier | RAM | Direct conns | Pooler conns | Price |
|---|---|---|---|---|
Micro (ci_micro) | 1 GB | 60 | 200 | $0.01344/hr (~$10/mo) |
Small (ci_small) | 2 GB | 90 | 400 | $0.0206/hr (~$15/mo) |
Branch compute bills only while the branch is awake (usage details), is shown as “Branching Compute Hours” on the invoice, and is not covered by the Spend Cap and not eligible for Compute Credits. Preview branches auto-pause on inactivity and auto-delete when the PR merges/closes, so the delta is small in practice.
The three approaches
Section titled “The three approaches”Pick by constraint:
- Keep the GitHub integration, and the OOM only bites on reset -> B (resize after). The branch boots Micro, then a one-time add-on call bumps it to Small; later resets re-migrate on Small. One API call, every integration feature intact.
- Want Small from the first byte, no restart, OOM structurally impossible -> C (create at size). You give up the integration’s turnkey check/comment/configure/seed/deploy and own the lifecycle.
- A is the status quo that OOMs - listed only for contrast.
Approach B: keep auto-branching, resize after creation
Section titled “Approach B: keep auto-branching, resize after creation”If you want to keep the GitHub integration’s turnkey pipeline (its checks, PR
comment, configure/migrate/seed/deploy, and auto-delete) and only need branches
off Micro, leave Automatic branching on and add a small workflow that resizes
the branch the App created. Because a branch is a project, you apply a
compute_instance add-on to its project_ref.
name: supabase-preview-resizeon: pull_request: types: [opened, reopened]
permissions: contents: readconcurrency: group: sb-resize-${{ github.event.pull_request.number }}
jobs: resize: # same-repo only (forks carry no secrets) if: github.event.pull_request.head.repo.full_name == github.repository runs-on: ubuntu-latest env: SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }} PARENT_REF: ${{ secrets.SUPABASE_PROJECT_ID }} # parent project ref PR_NUMBER: ${{ github.event.pull_request.number }} TARGET: ci_small # ci_micro|ci_small|ci_medium|ci_large|ci_xlarge steps: - name: Wait for the auto-branch, then resize it run: | set -euo pipefail api="https://api.supabase.com/v1" auth=(-H "Authorization: Bearer $SUPABASE_ACCESS_TOKEN") # 1. Wait until the App has FINISHED its pipeline on this PR's branch. # Resizing restarts Postgres, so we must not resize mid-migration - # gate on MIGRATIONS_PASSED / FUNCTIONS_DEPLOYED, not mere existence. branch_ref="" for i in $(seq 1 60); do # ~15 min @ 15s branch_ref=$(curl -fsS "${auth[@]}" "$api/projects/$PARENT_REF/branches" \ | jq -r --argjson pr "$PR_NUMBER" \ '.[]|select(.pr_number==$pr and (.status=="MIGRATIONS_PASSED" or .status=="FUNCTIONS_DEPLOYED"))|.project_ref' | head -n1) [ -n "$branch_ref" ] && [ "$branch_ref" != "null" ] && break echo "branch not ready ($i)..."; sleep 15 done [ -n "$branch_ref" ] || { echo "::error::branch not ready in time"; exit 1; } # 2. Skip if already at target. Micro is the ABSENCE of a compute # addon (the GET reports no compute_instance row), so an empty # readback means ci_micro. cur=$(curl -fsS "${auth[@]}" "$api/projects/$branch_ref/billing/addons" \ | jq -r '.selected_addons[]?|select(.type=="compute_instance")|.variant.id') cur=${cur:-ci_micro} [ "$cur" = "$TARGET" ] && { echo "already $TARGET"; exit 0; } # 3. Apply the compute add-on to the BRANCH project (this restarts it). curl -fsS -X PATCH "${auth[@]}" -H "Content-Type: application/json" \ "$api/projects/$branch_ref/billing/addons" \ -d "$(jq -n --arg v "$TARGET" \ '{addon_type:"compute_instance",addon_variant:$v}')" # 4. Confirm the addon, then wait for the project to be healthy again. # The variant readback is a config value, not a health signal; # settle to ACTIVE_HEALTHY measured 61-105 s on project resizes # (compute-disk D09). for i in $(seq 1 20); do now=$(curl -fsS "${auth[@]}" "$api/projects/$branch_ref/billing/addons" \ | jq -r '.selected_addons[]?|select(.type=="compute_instance")|.variant.id') now=${now:-ci_micro} [ "$now" = "$TARGET" ] && break sleep 15 done [ "$now" = "$TARGET" ] || { echo "::warning::resize not confirmed yet"; exit 0; } for i in $(seq 1 20); do st=$(curl -fsS "${auth[@]}" "$api/projects/$branch_ref" | jq -r .status) [ "$st" = "ACTIVE_HEALTHY" ] && { echo "resized to $now, healthy"; exit 0; } sleep 10 done echo "::warning::resized to $now but not ACTIVE_HEALTHY yet"Net: you keep every integration feature (checks, PR comment, configure / seed /
deploy, auto-delete) and add one API call, at the cost of a Postgres restart and
the Micro boot/first-migration window. It can also scale beyond the create-time
medium cap (up to ci_xlarge).
Approach C: own the lifecycle in CI (create at small)
Section titled “Approach C: own the lifecycle in CI (create at small)”To control size you turn Automatic branching off (otherwise you get a duplicate Micro branch and/or hit the branch limit) and let a workflow own create -> migrate -> delete.
name: supabase-previewon: pull_request: types: [opened, reopened, synchronize, closed] branches: [main] # gate on Supabase files if you like; remove to run on every PR paths: ['supabase/**']
permissions: contents: readconcurrency: group: sb-preview-${{ github.event.pull_request.number }}
env: SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }} PROJECT_ID: ${{ secrets.SUPABASE_PROJECT_ID }} # parent project ref BRANCH_NAME: ci-preview-${{ github.event.pull_request.number }}
jobs: upsert: # same-repo only (forks carry no secrets); skip on close if: github.event.pull_request.head.repo.full_name == github.repository && github.event.action != 'closed' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: supabase/setup-cli@v2 with: version: latest github-token: ${{ github.token }}
- name: Create branch at Small (idempotent) run: | set -euo pipefail if ! supabase branches get "$BRANCH_NAME" --project-ref "$PROJECT_ID" >/dev/null 2>&1; then supabase branches create "$BRANCH_NAME" \ --project-ref "$PROJECT_ID" --git-branch "${{ github.head_ref }}" \ --size small --yes fi
- name: Resolve IPv4 session-pooler URL # GH runners have no IPv6 run: | set -euo pipefail supabase branches get "$BRANCH_NAME" --project-ref "$PROJECT_ID" -o env > creds.env POOLER=$(grep '^POSTGRES_URL=' creds.env | cut -d= -f2- | tr -d '"') SESSION="${POOLER/:6543/:5432}" # transaction pooler -> session mode echo "::add-mask::$SESSION" echo "PGURL=$SESSION" >> "$GITHUB_ENV"
- name: Apply migrations run: supabase db push --db-url "$PGURL" --include-all --yes
# Optional parity steps the auto-branching pipeline would do for you: # - name: Seed # run: psql "$PGURL" -f supabase/seed.sql # - name: Deploy edge functions # run: supabase functions deploy --project-ref "$(echo "$PGURL" | grep -oP 'postgres\.\K[a-z0-9]+')"
cleanup: if: github.event.action == 'closed' runs-on: ubuntu-latest env: SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }} steps: - uses: supabase/setup-cli@v2 with: version: latest github-token: ${{ github.token }} - run: supabase branches delete "ci-preview-${{ github.event.pull_request.number }}" --project-ref "${{ secrets.SUPABASE_PROJECT_ID }}" --yes || trueSUPABASE_ACCESS_TOKEN- an account access token (supabase logintoken, or dashboard -> Account -> Access Tokens). Set as a repo secret:gh secret set SUPABASE_ACCESS_TOKEN --repo <owner>/<repo> < tokenfile.SUPABASE_PROJECT_ID- the parent project ref (not a branch ref).- In the dashboard: Integrations -> GitHub -> turn Automatic branching off so Supabase doesn’t also create a Micro branch.
supabase/setup-cli@v2is the official CLI installer action.
Feature-parity matrix
Section titled “Feature-parity matrix”Auto-branching runs a fixed pipeline (clone -> pull -> health -> configure -> migrate -> seed -> deploy) and wires in GitHub checks. Owning the lifecycle means
replicating the parts you need:
| Auto-branching does | DIY equivalent | Notes |
|---|---|---|
| Create branch on PR | branches create --size | You also get size control |
configure (apply config.toml) | Not done by db push - apply via Management API / CLI yourself | Gap to replicate |
| migrate | supabase db push --db-url <session-pooler> | Applies pending migrations |
seed (seed.sql) | psql "$PGURL" -f supabase/seed.sql | Not run by db push; add explicitly |
| deploy (edge functions) | supabase functions deploy | Only if you have functions |
Supabase Preview status check | Make the workflow itself a required check | Rebuild |
| PR comment with branch status | Add a comment step if wanted | Rebuild |
| Auto-delete on PR close | cleanup job on closed event | - |
Net: you gain size control and lose the integration’s turnkey check/comment/configure/seed/deploy ergonomics, which you rebuild in YAML.
Gotcha: the configure step needs your config.toml secrets (or it lies with MIGRATIONS_FAILED)
Section titled “Gotcha: the configure step needs your config.toml secrets (or it lies with MIGRATIONS_FAILED)”This one only bites the full-deploy path - native auto-branching, or a
branch created with a git association so Supabase runs the whole
configure -> migrate -> deploy -> seed pipeline from your repo. Approach C
above sidesteps it precisely because bare-branch + db push skips configure
(the “Gap to replicate” row in the matrix). If you do want configure parity,
read this first.
The branch status reflects the whole deploy, and a failure in the
configure step is still reported as MIGRATIONS_FAILED - so you go
debugging SQL that was never wrong. The usual trigger: config.toml sets custom
Auth via env() secrets, e.g.
[auth.rate_limit]email_sent = 30 # a custom rate limit ...
[auth.email.smtp]sender_name = "Pasteriser" # ... and a custom SMTP sender ...pass = "env(RESEND_API_KEY)" # ... whose password is an env() secret
[auth.external.github]enabled = trueclient_id = "env(GH_OAUTH_CLIENT_ID)"secret = "env(GH_OAUTH_CLIENT_SECRET)"A preview branch does not inherit the parent project’s secrets. So
env(RESEND_API_KEY) resolves to empty, and because you asked for a custom
sender name / email rate limit without a valid SMTP password, Supabase rejects
the configure step with a 401:
unexpected status 401: {"message":"Custom SMTP required to configureSMTP_SENDER_NAME or RATE_LIMIT_EMAIL_SENT. Missing SMTP_PASS fields."}The deploy aborts and the branch lands MIGRATIONS_FAILED. Same project, same
schema; the only variable is whether the branch got the secrets:
| Branch | secrets supplied at create | result |
|---|---|---|
| default compute, no secrets | no | MIGRATIONS_FAILED (configure step) |
| nano compute, no secrets | no | MIGRATIONS_FAILED (configure step) |
default compute, secrets in create body | yes | FUNCTIONS_DEPLOYED - all migrations applied, tables present |
Every migration replays clean via psql in all three cases - the SQL is never
the problem.
Fix: give the branch its secrets
Section titled “Fix: give the branch its secrets”-
Native integration: commit a dotenvx-encrypted
supabase/.env.previewand upload the decrypt key once withsupabase secrets set --env-file supabase/.env.keys. The branching executor decrypts it for every branch it creates. Only designated secret fields accept theencrypted:syntax - relevantlyauth.email.smtp.passandauth.external.*.secret. -
Self-driven (Management API): pass a
secretsobject in the create body - no committed ciphertext, the values come from GitHub Actions secrets:Terminal window curl -fsSL -X POST -H "Authorization: Bearer $SUPABASE_ACCESS_TOKEN" \-H 'Content-Type: application/json' \-d "$(jq -n --arg gb "$GIT_BRANCH" --arg r "$RESEND_API_KEY" \--arg ci "$GH_OAUTH_CLIENT_ID" --arg cs "$GH_OAUTH_CLIENT_SECRET" \'{branch_name:$gb, git_branch:$gb, secrets:{RESEND_API_KEY:$r, GH_OAUTH_CLIENT_ID:$ci, GH_OAUTH_CLIENT_SECRET:$cs}}')" \"https://api.supabase.com/v1/projects/$PROJECT_ID/branches" -
Or dodge it: disable custom SMTP / external OAuth for ephemeral branches (a throwaway preview should not send real email or do real OAuth anyway), or take the bare-branch +
db pushroute which never runs configure.
Gotcha: GitHub runners have no IPv6
Section titled “Gotcha: GitHub runners have no IPv6”A branch’s direct connection string points at an IPv6-only host:
PGURL = postgresql://postgres@db.<ref>.supabase.co:5432/postgrespsql: error: connection to server at "db.<ref>.supabase.co" (2a05:d014:...), port 5432 failed: Network is unreachablesupabase db push against it fails and the CLI tells you why:
Your network does not support IPv6, which is required for direct connections.Retry with your project's IPv4 transaction pooler connection string via --db-url.Why auto-branching doesn’t hit this: Supabase runs its migrate step on its own (IPv6-capable) infrastructure. The moment you run migrations from a GitHub-hosted runner, you’re on an IPv4-only network.
Fix: use the IPv4 pooler. The branch’s POSTGRES_URL is the
transaction pooler (...pooler.supabase.com:6543). For migrations, derive
the session pooler by swapping the port to 5432 (session mode supports the
advisory locks / session state that db push needs):
POOLER=$(grep '^POSTGRES_URL=' creds.env | cut -d= -f2- | tr -d '"')SESSION="${POOLER/:6543/:5432}" # session pooler, IPv4-reachablesupabase db push --db-url "$SESSION" --include-all --yesAlternative: Cloudflare WARP for IPv6 egress
Section titled “Alternative: Cloudflare WARP for IPv6 egress”If you want the direct connection from a GitHub-hosted runner (e.g. to avoid
the pooler entirely), Cloudflare WARP can hand the IPv4-only runner working
public IPv6 egress. WARP routes through Cloudflare’s network, so it reaches
arbitrary IPv6 destinations - including the db.<ref>.supabase.co host - even
though the runner has no native IPv6.
- name: Cloudflare WARP (IPv6 egress, IPv4 stays direct) run: | set -euo pipefail curl -fsSL https://pkg.cloudflareclient.com/pubkey.gpg \ | sudo gpg --yes --dearmor -o /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg echo "deb [signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://pkg.cloudflareclient.com/ $(lsb_release -cs) main" \ | sudo tee /etc/apt/sources.list.d/cloudflare-client.list sudo apt-get update -qq && sudo apt-get install -y -qq cloudflare-warp sudo warp-cli --accept-tos registration new sudo warp-cli --accept-tos mode warp # keep IPv4 OUT of the tunnel so the runner's link to GitHub is untouched sudo warp-cli --accept-tos tunnel ip add-range 0.0.0.0/0 sudo warp-cli --accept-tos connect # connect is async - gate on the daemon actually reporting Connected for i in $(seq 1 30); do sudo warp-cli --accept-tos status 2>/dev/null | grep -qi Connected && break sleep 2 done curl -s6 --max-time 10 https://api6.ipify.org # confirm public IPv6 egress
- name: db push over the DIRECT connection run: | supabase branches get "$BRANCH_NAME" --project-ref "$PROJECT_ID" -o env > creds.env DIRECT=$(grep '^POSTGRES_URL_NON_POOLING=' creds.env | cut -d= -f2- | tr -d '"') echo "::add-mask::$DIRECT" supabase db push --db-url "$DIRECT" --include-all --yesTwo footguns that make this fail silently if you skip them:
- Split-tunnel in default Exclude mode -
tunnel ip add-range 0.0.0.0/0excludes all IPv4 from the tunnel, so only IPv6 routes through WARP and the runner’s IPv4 connection to the GitHub Actions service is left alone. Without this, full-tunnel mode pushes everything through Cloudflare. warp-cli connectis asynchronous - it returnsSuccessimmediately, well before the tunnel is up. Pollingcurlalone races; gate onwarp-cli statusreportingConnectedfirst, otherwise the IPv6 probe runs against a tunnel that hasn’t finished establishing and you get a false negative.
On a clean runner this brings up a CloudflareWARP interface with a global
2606:4700:... address and a default IPv6 route; db push then applies every
migration over the direct host.
What a run looks like
Section titled “What a run looks like”The DIY lifecycle, end to end:
- Auto-created PR branches report
ci_micro(1 GB) from the billing API. branches create ... --size smallreportsci_small(2 GB).- A branch created via the CLI/API starts empty -
db pushthen applies every migration:
pastes table present before db push: f # branch starts emptyApplying migration 20260407101812_remote_schema.sql...... (all migrations) ...Finished supabase db push.table public.pastes present: ttable public.slugs present: tThe branch is a genuinely isolated instance with no production data copied. Counting rows over REST against each project confirms it - the branch has its own ref and keys and starts empty, while the parent still has its data:
# branch (<branch-ref>) -> content-range: */0 (0 rows, RLS-visible)# parent (<parent-ref>) -> content-range: 0-0/1 (its own data)- On the
closedevent, only thecleanupjob runs and the branch is deleted, stopping the compute billing.
Recommendation
Section titled “Recommendation”- Keep auto-branching, OOM bites on reset -> Approach B: add the resize workflow. One API call per PR, every integration feature intact (restart + Micro boot window are the cost).
- Want Small from boot / OOM bites on the initial migrate / don’t need the integration’s turnkey pipeline -> Approach C: own the lifecycle and create at Small. No restart, OOM impossible, but you rebuild checks/comments/seed.
- One-off -> bump Micro->Small by hand in the dashboard.
Neither auto-branching nor config.toml exposes a default compute size, so a
larger tier always costs you either a resize step (B) or ownership of branch
creation (C).
What to do about it
Section titled “What to do about it”What the measured project-lifecycle numbers add to the two workflows above. Every timing here comes from PROJECT resizes and fresh PROJECT provisioning; no branch was resized or provisioned under sampling, so treat the seconds as the shape to expect, not a branch figure. Module ids resolve in the platform-downtime RUNLOG, the compute-disk RUNLOG and the instance-sizing RUNLOG.
| Practice | Evidence | Module |
|---|---|---|
Treat an absent compute addon as ci_micro when comparing against TARGET. | Returning to Micro removes the addon and the GET reports no compute_instance row, so a ci_micro target never matches .variant.id. The Approach B workflow defaults the empty readback to ci_micro for this reason. | platform-downtime D04 |
After the addon readback confirms, poll GET /v1/projects/{branch_ref} for ACTIVE_HEALTHY before a reset or your own steps. | The variant is a config readback, and settle to healthy measured 61-105 s across four resizes and 107 s on another. | compute-disk D09, D01 |
Handle the addon-change 429 on the PATCH: sleep and retry once. | The PATCH answers 429 We are still processing addon changes, please try again in 1-2 minutes. A reopened event or a re-run inside about 2 minutes of the first PATCH fails a bare curl -fsS. | compute-disk D09 |
| Expect REST to drop during an upgrade. | 1.0 s of contiguous failure on Micro -> Small, 17.0 s on Small -> Large; both measured downgrades were 0 s. The default supabase-js client took 4 attempts and ~7.0s to ride out three 503s (W02); whether it survives a 17.0 s gap was not measured. | compute-disk D09; edge-resilience W02 |
| Budget about 200 s of pooler unavailability into any CI step that runs over the pooler during the resize, such as a seed or a smoke test. | The lab sampled port 6543: the pooler was out 207 s resizing up and 196 s down while REST and Realtime kept serving. | platform-downtime D03, D04 |
In Approach C, wait for ACTIVE_HEALTHY and retry the first db push or first write. | After branches create: 5 of 5 fresh projects refused the first POST /auth/v1/admin/users with 500 one poll tick after healthy and accepted the retry. | placement reference, Verified row ‘Create -> healthy, and healthy is not writable’ (2026-08-04, n=5, bash run not in the lab repo); supabase-lab AGENTS.md provisioning note (2026-08-03, 2 of 2, 500 "Database error checking email") |
| Treat Micro as the floor on a paid org. | Project creation with desired_instance_size: "nano" answered 400 Minimum instance size on paid plans is Micro, the addon PATCH 400 addon_variant: Invalid input, and ci_nano is absent from available_addons. Whether a BRANCH accepts nano on a paid org was not measured (the gotcha table’s nano branch does not record its plan). | instance-sizing I01, 2026-08-17 |
Not measured: branch resize timings (all figures are project resizes); the
OOM threshold itself at any schema size; auto-pause timing for idle
branches; whether the check_run trigger fires before the App’s pipeline
completes; WARP tunnel establishment time on a runner; the IPv4 add-on
price is quoted undated.
Verification
Section titled “Verification”After the first PR with a workflow in place:
- The workflow run shows the branch reporting the target compute variant
(
ci_small) after the PATCH/creation path completes - pollGET /v1/projects/{branch_ref}/billing/addonsuntil it does. - A branch reset triggered on Small completes without the OOM that Micro hit.
- Close the PR: only the
cleanupjob runs, and the branch is deleted (Approach C; on the App-managed path the branch auto-deletes when the PR merges/closes).
Modules
Section titled “Modules”| Module | Experiment | Test | Artifact |
|---|---|---|---|
| D01 | compute-disk | d01-compute-pg-limits.ts | none published |
| D03 | platform-downtime | d03-resize-up.ts | none published |
| D04 | platform-downtime | d04-resize-down.ts | none published |
| D09 | compute-disk | d09-compute-resize-timing.ts | none published |
| I01 | instance-sizing | i01-nano-availability.ts | none published |
| W02 | edge-resilience | w02-retry-probe.ts | out/2026-08-16, out/2026-08-17 |
See also
Section titled “See also”- Supabase docs: Working with branches
References
Section titled “References”-
Supabase, “Management API OpenAPI document,” api.supabase.com. https://api.supabase.com/api/v1-json ↩