From 74c116de749934b825a8d6e0be54942508d0cd90 Mon Sep 17 00:00:00 2001
From: Nik Richers
Date: Mon, 14 Sep 2026 16:48:39 -0700
Subject: [PATCH] =?UTF-8?q?docs:=20add=20Multigres=20Public=20Alpha=20docu?=
=?UTF-8?q?mentation=20=E2=80=94=C2=A0MERGE=20ON=20SEP=2014,=202026=20(#49?=
=?UTF-8?q?020)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## I have read the CONTRIBUTING.md file.
YES
## What kind of change does this PR introduce?
This PR adds Public Alpha documentation for Multigres, Supabase's
multi-node Postgres high-availability integration. It introduces an
overview guide, a compatibility stub, Database sidebar navigation, a
Features table row, and a "What you get" card grid. ContentListings
items can now omit `href` so those cards are not forced to be links.
Linear: MUL-452.
~~๐จ **DO NOT MERGE UNTIL THE PUBLIC ALPHA GOES LIVE** ๐จ~~ [@jhydra12
OK'ed merging, FYI]
## What is the current behavior?
- Linear item: Documentation for Multigres
- Production has no Multigres guides.
`https://supabase.com/docs/guides/database/multigres` and
`https://supabase.com/docs/guides/database/multigres/compatibility`
return 404
- The Database sidebar has no Multigres section
- The Features status table does not list Multigres
- ContentListings items required a link (`href` was mandatory)
## What is the new behavior?
- Overview guide at `/docs/guides/database/multigres` covering alpha
status, eligibility, enablement, and what is not included
- Compatibility stub at `/docs/guides/database/multigres/compatibility`
- Database sidebar: Multigres โ Overview, Compatibility (after OrioleDB)
- Features table: Database / Multigres / `public alpha`
- "What you get" renders as three non-link ContentListings cards
- `href` is optional on ContentListings items; markdown export renders
unlinked entries when it is omitted
## Additional context
- Worktree:
~/GitHub/supabase/supabase-worktrees/nikrichers/mul-452-documentation-for-multigres-ready
- Branch commits: Initial Multigres docs draft; Edits (cards, copy, MDX
comments); merge master; spelling allow-list for Multigres, Vitess, and
sharding
- Verification:
| Check | Result |
| --------------------------------------- | --------------- |
| Preview overview | 200 |
| Preview compatibility | 200 |
| Production overview | 404 (expected) |
| Production compatibility | 404 (expected) |
| `supa-mdx-lint` on changed MDX | pass |
| `vitest` `lib/content-listings.test.ts` | pass (21 tests) |
### Proof: Multigres docs pages render, including non-link What you get
cards
**Verified:** production 404 ยท Vercel docs preview 200
#### Overview [(PR
preview)](https://docs-git-nikrichers-mul-452-documentation-for-m-6f8a59-supabase.vercel.app/docs/guides/database/multigres)
#### Compatibility [(PR
preview)](https://docs-git-nikrichers-mul-452-documentation-for-m-6f8a59-supabase.vercel.app/docs/guides/database/multigres/compatibility)
### Test plan
- [ ] [Production
overview](https://supabase.com/docs/guides/database/multigres) (404) vs
[preview
overview](https://docs-git-nikrichers-mul-452-documentation-for-m-6f8a59-supabase.vercel.app/docs/guides/database/multigres)
- [ ] [Production
compatibility](https://supabase.com/docs/guides/database/multigres/compatibility)
(404) vs [preview
compatibility](https://docs-git-nikrichers-mul-452-documentation-for-m-6f8a59-supabase.vercel.app/docs/guides/database/multigres/compatibility)
- [ ] Database sidebar shows Multigres โ Overview and Compatibility
after OrioleDB
- [ ] Overview shows Public Alpha caution, three What you get cards (not
links), eligibility, and one-way-migration caution
- [ ] Compatibility page is a placeholder that links back to the
overview
- [ ] Features table lists Database / Multigres / `public alpha`
- [ ] `supa-mdx-lint` on
`apps/docs/content/guides/database/multigres.mdx`,
`apps/docs/content/guides/database/multigres/compatibility.mdx`, and
`apps/docs/content/guides/getting-started/features.mdx`
## Summary by CodeRabbit
* **New Features**
* Added Multigres documentation covering availability, setup,
compatibility, limitations, migration behavior, and external resources.
* Added Multigres to database navigation and feature-status listings.
* Added an overview of Multigres benefits, including automatic failover,
unchanged connection strings, and consensus-backed write durability.
* **Improvements**
* Content listings now support informational items without links across
layouts.
* Improved listing rendering and click tracking for linked and
non-linked items.
* **Documentation**
* Added spelling support for Multigres, Vitess, and sharding
terminology.
---------
Co-authored-by: Nik Richers
Co-authored-by: Cursor Agent
---
apps/docs/WORD_LIST.md | 13 ++++
.../ContentListings.client.tsx | 64 ++++++++++++-------
.../NavigationMenu.constants.ts | 14 ++++
.../content/guides/database/multigres.mdx | 60 +++++++++++++++++
.../database/multigres/compatibility.mdx | 6 ++
.../guides/getting-started/features.mdx | 3 +-
.../data/content-listings/database.data.ts | 24 +++++++
apps/docs/data/content-listings/index.ts | 3 +-
.../markdown-schema/ContentListings.ts | 5 ++
apps/docs/lib/content-listings.test.ts | 39 ++++++++++-
apps/docs/lib/content-listings.zod.mjs | 2 +-
.../ProjectHome/HighAvailabilityBadge.tsx | 2 +-
supa-mdx-lint/Rule001HeadingCase.toml | 1 +
supa-mdx-lint/Rule003Spelling.toml | 3 +
14 files changed, 210 insertions(+), 29 deletions(-)
create mode 100644 apps/docs/content/guides/database/multigres.mdx
create mode 100644 apps/docs/content/guides/database/multigres/compatibility.mdx
diff --git a/apps/docs/WORD_LIST.md b/apps/docs/WORD_LIST.md
index e3ee4af18cc..45666d8c76b 100644
--- a/apps/docs/WORD_LIST.md
+++ b/apps/docs/WORD_LIST.md
@@ -517,6 +517,10 @@ Use _might_ for possibility or an uncertain outcome.
Use _must_ or _need to_ for a requirement. Don't use _must_ for a recommendation.
+### Multigres
+
+Use _Multigres_ for the product name. Don't write _multi-gres_ or _MultiGres_.
+
## N
### native
@@ -652,6 +656,11 @@ Use _setup_ as a noun or adjective and _set up_ as a verb.
- Recommended: Complete the setup to set up authentication.
- Not recommended: Setup authentication.
+### shard
+
+Use _shard_ as a noun and _sharding_ for the practice of splitting data across
+nodes.
+
### sign in and sign-in
Use _sign in_, _sign out_, and _sign up_ as verbs. Use the hyphenated forms
@@ -788,6 +797,10 @@ actual operation.
Write _versus_ in prose, not _vs._ Use `vs` only when it is part of a literal name
or when space is constrained.
+### Vitess
+
+Use _Vitess_ for the product name.
+
## W
### web
diff --git a/apps/docs/components/ContentListings/ContentListings.client.tsx b/apps/docs/components/ContentListings/ContentListings.client.tsx
index 93086bd588a..b28e1b18841 100644
--- a/apps/docs/components/ContentListings/ContentListings.client.tsx
+++ b/apps/docs/components/ContentListings/ContentListings.client.tsx
@@ -29,6 +29,8 @@ function useContentListingClickHandler(group: ContentListingGroup) {
const trackClick = useCallback(
(item: ContentListingItem) => {
+ if (!item.href) return
+
sendTelemetryEvent({
action: 'docs_content_listing_clicked',
properties: {
@@ -73,8 +75,45 @@ function ContentListingsGroup({ group }: { group: ContentListingGroup }) {
)}
+ )
+ }
+
const external = isExternalContentListingHref(item.href)
- const key = `${group.id}-${item.href}`
if (isGrid) {
return (
@@ -87,26 +126,7 @@ function ContentListingsGroup({ group }: { group: ContentListingGroup }) {
target={external ? '_blank' : undefined}
rel={external ? 'noopener noreferrer' : undefined}
>
- {item.badge}
- ) : undefined
- }
- >
- {item.badge && item.badgePosition === 'below' && (
-
- {item.badge}
-
- )}
- {item.subtitle && (
- {item.subtitle}
- )}
- {item.description}
-
+ {panel}
)
@@ -120,7 +140,7 @@ function ContentListingsGroup({ group }: { group: ContentListingGroup }) {
target={external ? '_blank' : undefined}
rel={external ? 'noopener noreferrer' : undefined}
>
- {item.title}: {item.description}
+ {listContent}
)
diff --git a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts
index 0909dba5851..d1617528709 100644
--- a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts
+++ b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts
@@ -1139,6 +1139,20 @@ export const database: NavMenuConstant = {
},
],
},
+ {
+ name: 'Multigres',
+ url: undefined,
+ items: [
+ {
+ name: 'Overview',
+ url: '/guides/database/multigres' as `/${string}`,
+ },
+ {
+ name: 'Compatibility',
+ url: '/guides/database/multigres/compatibility' as `/${string}`,
+ },
+ ],
+ },
{
name: 'Access and security',
url: undefined,
diff --git a/apps/docs/content/guides/database/multigres.mdx b/apps/docs/content/guides/database/multigres.mdx
new file mode 100644
index 00000000000..3f0e15ce5c2
--- /dev/null
+++ b/apps/docs/content/guides/database/multigres.mdx
@@ -0,0 +1,60 @@
+---
+id: 'multigres'
+title: 'Multigres'
+subtitle: 'Horizontally scalable Postgres for high availability'
+description: 'Run high availability Postgres across multiple nodes with automatic failover, using Multigres.'
+---
+
+
+
+Multigres is in [Public Alpha](/docs/guides/getting-started/features#feature-status). It's free during the Alpha for organizations on a paid plan, for up to two projects, but pricing may change once it leaves Alpha. It isn't covered by the [uptime SLA](/sla), and Supabase isn't targeting production or mission-critical workloads with it during this stage.
+
+
+
+Multigres gives your project high availability by running Postgres across multiple nodes instead of one, so reads and writes continue if a node fails. It is Supabase's integration of [Multigres](https://multigres.com), an open-source project that brings the same distributed-systems approach Vitess brought to MySQL to Postgres.
+
+
+
+## Eligibility
+
+During the Public Alpha:
+
+- Multigres is available to organizations on a paid plan. It isn't available on the Free plan.
+- Availability is being rolled out gradually, so the option to enable it may not yet appear for every eligible organization.
+- Up to two projects per eligible organization can use Multigres for free during the Alpha.
+
+## Enabling Multigres
+
+In the Dashboard, Multigres appears as **High availability** during project creation:
+
+1. Open [Create a new project](/dashboard/new/_) in the Dashboard.
+2. Under **High availability**, turn on **Enable high availability**.
+3. Finish the remaining fields such as database password, region, and compute size, if shown.
+4. Click **Create new project**.
+
+If your organization isn't eligible or hasn't been rolled out yet, **High availability** won't appear.
+
+## What's not included in the alpha
+
+Some Supabase features and project operations aren't yet available on Multigres-backed projects:
+
+- **Realtime.** Multigres doesn't yet support the logical replication that Realtime depends on, so Realtime is unavailable.
+- **Point-in-Time Recovery.** Only the standard daily backups are available.
+- **Cross-region read replicas.** Multigres projects run in a single region during the Alpha.
+- **OrioleDB.** A project can use Multigres or [OrioleDB](/docs/guides/database/orioledb), not both.
+- **Resizing after creation.** Compute size, disk, and the number of replicas can't be changed after a Multigres project is created.
+- **Sharding and custom durability policies.** These are on the longer-term roadmap but aren't part of the Alpha.
+
+
+
+Enabling Multigres migrates your project's database to run on Multigres. There's currently no managed path to move it back to a standard Postgres project.
+
+
+
+## Compatibility
+
+Multigres aims for full compatibility with standard Postgres, but there are some differences to be aware of. See [Multigres compatibility](/docs/guides/database/multigres/compatibility) for details.
+
+## Resources
+
+[Multigres documentation](https://multigres.com/docs) โ architecture, self-hosted deployment, and other technical depth that goes beyond the hosted Supabase integration covered on this page.
diff --git a/apps/docs/content/guides/database/multigres/compatibility.mdx b/apps/docs/content/guides/database/multigres/compatibility.mdx
new file mode 100644
index 00000000000..02a7072e2a4
--- /dev/null
+++ b/apps/docs/content/guides/database/multigres/compatibility.mdx
@@ -0,0 +1,6 @@
+---
+title: 'Multigres compatibility'
+description: 'Where Multigres-backed Postgres projects differ from standard Postgres.'
+---
+
+Multigres targets full compatibility with standard Postgres, verified against the [`pg_regress`](https://www.postgresql.org/docs/current/regress.html) test suite. See the [Multigres documentation](https://multigres.com/docs) for lower-level architecture and compatibility details, and the [Multigres overview](/docs/guides/database/multigres#whats-not-included-in-the-alpha) for what's not yet supported during the Public Alpha.
diff --git a/apps/docs/content/guides/getting-started/features.mdx b/apps/docs/content/guides/getting-started/features.mdx
index 98240af9be9..6c4dbc57908 100644
--- a/apps/docs/content/guides/getting-started/features.mdx
+++ b/apps/docs/content/guides/getting-started/features.mdx
@@ -176,7 +176,7 @@ Manage your projects programmatically. [Docs](/docs/reference/api).
## Client libraries
-Official client libraries for [JavaScript](/docs/reference/javascript/start), [Flutter](/docs/reference/dart/initializing) and [Swift](/docs/reference/swift/introduction).
+Official client libraries for [JavaScript](/docs/reference/javascript/introduction), [Flutter](/docs/reference/dart/initializing) and [Swift](/docs/reference/swift/introduction).
Unofficial libraries are supported by the community.
## Feature status
@@ -208,6 +208,7 @@ In addition to the Beta requirements, features in GA are covered by the [uptime
| Database | Webhooks | `beta` | โ |
| Database | Vault | `public alpha` | โ |
| Database | Supabase Pipelines | `public alpha` | N/A |
+| Database | Multigres | `public alpha` | N/A |
| Platform | | `GA` | โ |
| Platform | Point-in-Time Recovery | `GA` | ๐งย [wal-g](https://github.com/wal-g/wal-g) |
| Platform | Custom Domains | `GA` | N/A |
diff --git a/apps/docs/data/content-listings/database.data.ts b/apps/docs/data/content-listings/database.data.ts
index 60c9b4c038e..65cd98428f1 100644
--- a/apps/docs/data/content-listings/database.data.ts
+++ b/apps/docs/data/content-listings/database.data.ts
@@ -94,3 +94,27 @@ export const databaseNextSteps: ContentListingGroup = {
},
],
}
+
+export const databaseMultigresWhatYouGet: ContentListingGroup = {
+ id: 'database-multigres-what-you-get',
+ heading: 'What you get',
+ description:
+ 'When you enable Multigres on a project, your database runs as a small cluster instead of a single instance:',
+ type: 'grid',
+ items: [
+ {
+ title: 'Automatic failover',
+ description:
+ 'If a node fails, another in the cluster is promoted within seconds, without you having to intervene.',
+ },
+ {
+ title: 'No connection changes',
+ description:
+ 'Use the same connection string. Coordination is transparent to your application.',
+ },
+ {
+ title: 'Consensus-backed durability',
+ description: 'Writes are acknowledged only after the cluster agrees they are durable.',
+ },
+ ],
+}
diff --git a/apps/docs/data/content-listings/index.ts b/apps/docs/data/content-listings/index.ts
index aca30691be8..60e42a382d4 100644
--- a/apps/docs/data/content-listings/index.ts
+++ b/apps/docs/data/content-listings/index.ts
@@ -2,7 +2,7 @@ import type { ContentListingGroup } from '~/lib/content-listings.schema'
import { aiToolsBuildingIntoApp, aiToolsSupportedAgents } from './ai-tools.data'
import { authGetStarted, authNextSteps, authPricing } from './auth.data'
-import { databaseGetStarted, databaseNextSteps } from './database.data'
+import { databaseGetStarted, databaseMultigresWhatYouGet, databaseNextSteps } from './database.data'
import {
functionsExamplesAiMedia,
functionsExamplesMessaging,
@@ -42,6 +42,7 @@ const ALL_GROUPS: readonly ContentListingGroup[] = [
authPricing,
authNextSteps,
databaseGetStarted,
+ databaseMultigresWhatYouGet,
databaseNextSteps,
functionsGetStarted,
functionsExamplesSupabase,
diff --git a/apps/docs/internals/markdown-schema/ContentListings.ts b/apps/docs/internals/markdown-schema/ContentListings.ts
index 6817ce1f919..56b1c7ba404 100644
--- a/apps/docs/internals/markdown-schema/ContentListings.ts
+++ b/apps/docs/internals/markdown-schema/ContentListings.ts
@@ -34,6 +34,11 @@ export function serializeContentListingGroupToMarkdown(
}
for (const item of items) {
+ if (!item.href) {
+ lines.push(`- **${item.title}:** ${item.description}`)
+ continue
+ }
+
const href = isExternalContentListingHref(item.href)
? item.href
: `${linkBaseUrl}${withDocsBasePath(item.href)}`
diff --git a/apps/docs/lib/content-listings.test.ts b/apps/docs/lib/content-listings.test.ts
index 71f0de5c6f6..7d017438edf 100644
--- a/apps/docs/lib/content-listings.test.ts
+++ b/apps/docs/lib/content-listings.test.ts
@@ -147,6 +147,27 @@ describe('serializeContentListingGroupToMarkdown', () => {
)
})
+ it('renders items without href as unlinked list entries', () => {
+ const markdown = serializeContentListingGroupToMarkdown(
+ {
+ id: 'what-you-get',
+ heading: 'What you get',
+ items: [
+ {
+ title: 'Automatic failover',
+ description: 'Another node is promoted if a node goes down.',
+ },
+ ],
+ },
+ 'https://supabase.com'
+ )
+
+ expect(markdown).toContain(
+ '- **Automatic failover:** Another node is promoted if a node goes down.'
+ )
+ expect(markdown).not.toContain('](')
+ })
+
it('omits heading line when heading is not set', () => {
const markdown = serializeContentListingGroupToMarkdown(
{
@@ -260,9 +281,11 @@ describe('dashboard content listing hrefs', () => {
// Root-relative /dashboard hrefs get the docs basePath and 404; use absolute URLs.
it('uses absolute https://supabase.com dashboard URLs', () => {
const dashboardLinks = Object.values(CONTENT_LISTINGS).flatMap((group) =>
- group.items
- .filter((item) => isDashboardHref(item.href))
- .map((item) => ({ listingId: group.id, title: item.title, href: item.href }))
+ group.items.flatMap((item) =>
+ item.href && isDashboardHref(item.href)
+ ? [{ listingId: group.id, title: item.title, href: item.href }]
+ : []
+ )
)
expect(dashboardLinks.length).toBeGreaterThan(0)
@@ -275,6 +298,16 @@ describe('dashboard content listing hrefs', () => {
})
})
+describe('contentListingItemSchema href', () => {
+ it('accepts an item without href', () => {
+ const result = contentListingItemSchema.safeParse({
+ title: 'Automatic failover',
+ description: 'Another node is promoted if a node goes down.',
+ })
+ expect(result.success).toBe(true)
+ })
+})
+
describe('contentListingItemSchema icon', () => {
const baseItem = {
title: 'Datadog',
diff --git a/apps/docs/lib/content-listings.zod.mjs b/apps/docs/lib/content-listings.zod.mjs
index decf8220a03..bc9b6de5e2d 100644
--- a/apps/docs/lib/content-listings.zod.mjs
+++ b/apps/docs/lib/content-listings.zod.mjs
@@ -22,7 +22,7 @@ export const contentListingIconSchema = z.union([z.string().min(1), contentListi
export const contentListingItemSchema = z.object({
title: z.string().min(1),
- href: z.string().min(1),
+ href: z.string().min(1).optional(),
description: z.string().min(1),
/** Shown under the title on grid cards, before the description. */
subtitle: z.string().min(1).optional(),
diff --git a/apps/studio/components/interfaces/ProjectHome/HighAvailabilityBadge.tsx b/apps/studio/components/interfaces/ProjectHome/HighAvailabilityBadge.tsx
index 15041a5c3c5..b1b45f29756 100644
--- a/apps/studio/components/interfaces/ProjectHome/HighAvailabilityBadge.tsx
+++ b/apps/studio/components/interfaces/ProjectHome/HighAvailabilityBadge.tsx
@@ -37,7 +37,7 @@ export function HighAvailabilityBadge({ size = 'default' }: HighAvailabilityBadg
globally distributed deployments.