docs: re-publish Multigres Private Alpha docs — merge on October 2, 2026 (#50664)

## I have read the CONTRIBUTING.md file.

YES

## What kind of change does this PR introduce?

Re-add. Reapplies the Multigres Private Alpha docs section removed in
#50662, ready to merge once Sugu gives the go-ahead. Do not merge until
then.

Linear: MUL-1621 (follow-up to MUL-452).

## What is the current behavior?

Multigres docs section is down (per #50662): no overview/compatibility
pages, no sidebar entry, no features-table row, no "What you get" cards.

## What is the new behavior?

Exact reapply of #49020 (with Multigres marked Private Alpha): overview
guide at `/docs/guides/database/multigres`, compatibility stub, Database
sidebar entry, features-table row, "What you get" cards, and the
`ContentListings` optional-`href` support they rely on.

Base branch is the revert PR (#50662) so the diff here is legible now;
retarget to `master` once #50662 merges.

## Additional context

- `pnpm --filter docs exec vitest run lib/content-listings.test.ts` — 22
passed
- Blocked on Sugu's go-ahead — `do-not-merge` label applied

---------

Co-authored-by: Nik Richers <nik@validmind.ai>
This commit is contained in:
Nik RichersandNik Richers authored and GitHub committed 2026-10-02 09:18:25 -07:00
1 parent 43ffe6b067
commit 0405b31b26
12 files changed
+251 -83

No files matched your search

@@ -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 }) {
)}
<ul className={listClassName}>
{items.map((item) => {
const key = `${group.id}-${item.href ?? item.title}`
const panel = (
<GlassPanel
title={item.title}
icon={resolveContentListingIcon(item.icon)}
hasLightIcon={item.hasLightIcon ?? typeof item.icon === 'string'}
className={item.href ? undefined : 'cursor-default'}
badge={
item.badge && item.badgePosition !== 'below' ? (
<Badge variant="success">{item.badge}</Badge>
) : undefined
}
>
{item.badge && item.badgePosition === 'below' && (
<Badge variant="success" className="mb-3 block w-fit">
{item.badge}
</Badge>
)}
{item.subtitle && (
<span className="mb-2 block text-tertiary-foreground">{item.subtitle}</span>
)}
{item.description}
</GlassPanel>
)
const listContent = (
<>
<strong>{item.title}</strong>: {item.description}
</>
)
if (!item.href) {
return (
<li key={key} className={gridItemClassName}>
{isGrid ? panel : listContent}
</li>
)
}
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}
>
<GlassPanel
title={item.title}
icon={resolveContentListingIcon(item.icon)}
hasLightIcon={item.hasLightIcon ?? typeof item.icon === 'string'}
badge={
item.badge && item.badgePosition !== 'below' ? (
<Badge variant="success">{item.badge}</Badge>
) : undefined
}
>
{item.badge && item.badgePosition === 'below' && (
<Badge variant="success" className="mb-3 block w-fit">
{item.badge}
</Badge>
)}
{item.subtitle && (
<span className="mb-2 block text-tertiary-foreground">{item.subtitle}</span>
)}
{item.description}
</GlassPanel>
{panel}
</Link>
</li>
)
@@ -120,7 +140,7 @@ function ContentListingsGroup({ group }: { group: ContentListingGroup }) {
target={external ? '_blank' : undefined}
rel={external ? 'noopener noreferrer' : undefined}
>
<strong>{item.title}</strong>: {item.description}
{listContent}
</Link>
</li>
)
@@ -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,
@@ -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.'
---
<Admonition type="caution">
Multigres is in [Private 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.
</Admonition>
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.
<ContentListings id="database-multigres-what-you-get" />
## Eligibility
During the Private 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.
<Admonition type="caution">
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.
</Admonition>
## 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.
@@ -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 Private Alpha.
@@ -199,61 +199,62 @@ Features in Beta are tested by an external penetration tester for security issue
In addition to the Beta requirements, features in GA are covered by the [uptime SLA](/sla).
| Product | Feature | Stage | Available on self-hosted |
| -------------- | -------------------------- | -------------- | ------------------------------------------- |
| Database | Postgres | `GA` | ✅ |
| Database | Vector Database | `GA` | ✅ |
| Database | Auto-generated Rest API | `GA` | ✅ |
| Database | Auto-generated GraphQL API | `GA` | ✅ |
| Database | Webhooks | `beta` | ✅ |
| Database | Vault | `public alpha` | ✅ |
| Database | Supabase Pipelines | `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 |
| Platform | Network Restrictions | `GA` | N/A |
| Platform | SSL enforcement | `GA` | N/A |
| Platform | Branching | `beta` | N/A |
| Platform | Terraform Provider | `public alpha` | N/A |
| Platform | Read Replicas | `GA` | N/A |
| Platform | Log Drains | `public alpha` | ✅ |
| Platform | MCP | `public alpha` | ✅ |
| Platform | PrivateLink | `beta` | N/A |
| Studio | | `GA` | ✅ |
| Studio | SSO | `GA` | ✅ |
| Studio | Column Privileges | `public alpha` | ✅ |
| Realtime | Postgres Changes | `GA` | ✅ |
| Realtime | Broadcast | `GA` | ✅ |
| Realtime | Presence | `GA` | ✅ |
| Realtime | Broadcast Authorization | `public beta` | ✅ |
| Realtime | Presence Authorization | `public beta` | ✅ |
| Realtime | Broadcast from Database | `public beta` | ✅ |
| Storage | | `GA` | ✅ |
| Storage | CDN | `GA` | 🚧 [Cloudflare](https://www.cloudflare.com) |
| Storage | Smart CDN | `GA` | 🚧 [Cloudflare](https://www.cloudflare.com) |
| Storage | Image Transformations | `GA` | ✅ |
| Storage | Resumable Uploads | `GA` | ✅ |
| Storage | S3 compatibility | `GA` | ✅ |
| Edge Functions | | `GA` | ✅ |
| Edge Functions | Regional Invocations | `GA` | ✅ |
| Edge Functions | NPM compatibility | `GA` | ✅ |
| Auth | | `GA` | ✅ |
| Auth | Email sign-in | `GA` | ✅ |
| Auth | Social login | `GA` | ✅ |
| Auth | Phone sign-in | `GA` | ✅ |
| Auth | Passwordless sign-in | `GA` | ✅ |
| Auth | SSO with SAML | `GA` | ✅ |
| Auth | Authorization via RLS | `GA` | ✅ |
| Auth | CAPTCHA protection | `GA` | ✅ |
| Auth | Server-side Auth | `beta` | ✅ |
| Auth | Third-Party Auth | `GA` | ✅ |
| Auth | Hooks | `beta` | ✅ |
| CLI | | `GA` | ✅ Works with self-hosted |
| Management API | | `GA` | N/A |
| Client Library | JavaScript | `GA` | N/A |
| Client Library | Flutter | `GA` | N/A |
| Client Library | Swift | `GA` | N/A |
| Client Library | Python | `beta` | N/A |
| Product | Feature | Stage | Available on self-hosted |
| -------------- | -------------------------- | --------------- | ------------------------------------------- |
| Database | Postgres | `GA` | ✅ |
| Database | Vector Database | `GA` | ✅ |
| Database | Auto-generated Rest API | `GA` | ✅ |
| Database | Auto-generated GraphQL API | `GA` | ✅ |
| Database | Webhooks | `beta` | ✅ |
| Database | Vault | `public alpha` | ✅ |
| Database | Supabase Pipelines | `public alpha` | N/A |
| Database | Multigres | `private 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 |
| Platform | Network Restrictions | `GA` | N/A |
| Platform | SSL enforcement | `GA` | N/A |
| Platform | Branching | `beta` | N/A |
| Platform | Terraform Provider | `public alpha` | N/A |
| Platform | Read Replicas | `GA` | N/A |
| Platform | Log Drains | `public alpha` | ✅ |
| Platform | MCP | `public alpha` | ✅ |
| Platform | PrivateLink | `beta` | N/A |
| Studio | | `GA` | ✅ |
| Studio | SSO | `GA` | ✅ |
| Studio | Column Privileges | `public alpha` | ✅ |
| Realtime | Postgres Changes | `GA` | ✅ |
| Realtime | Broadcast | `GA` | ✅ |
| Realtime | Presence | `GA` | ✅ |
| Realtime | Broadcast Authorization | `public beta` | ✅ |
| Realtime | Presence Authorization | `public beta` | ✅ |
| Realtime | Broadcast from Database | `public beta` | ✅ |
| Storage | | `GA` | ✅ |
| Storage | CDN | `GA` | 🚧 [Cloudflare](https://www.cloudflare.com) |
| Storage | Smart CDN | `GA` | 🚧 [Cloudflare](https://www.cloudflare.com) |
| Storage | Image Transformations | `GA` | ✅ |
| Storage | Resumable Uploads | `GA` | ✅ |
| Storage | S3 compatibility | `GA` | ✅ |
| Edge Functions | | `GA` | ✅ |
| Edge Functions | Regional Invocations | `GA` | ✅ |
| Edge Functions | NPM compatibility | `GA` | ✅ |
| Auth | | `GA` | ✅ |
| Auth | Email sign-in | `GA` | ✅ |
| Auth | Social login | `GA` | ✅ |
| Auth | Phone sign-in | `GA` | ✅ |
| Auth | Passwordless sign-in | `GA` | ✅ |
| Auth | SSO with SAML | `GA` | ✅ |
| Auth | Authorization via RLS | `GA` | ✅ |
| Auth | CAPTCHA protection | `GA` | ✅ |
| Auth | Server-side Auth | `beta` | ✅ |
| Auth | Third-Party Auth | `GA` | ✅ |
| Auth | Hooks | `beta` | ✅ |
| CLI | | `GA` | ✅ Works with self-hosted |
| Management API | | `GA` | N/A |
| Client Library | JavaScript | `GA` | N/A |
| Client Library | Flutter | `GA` | N/A |
| Client Library | Swift | `GA` | N/A |
| Client Library | Python | `beta` | N/A |
- ✅ = Fully Available
- 🚧 = Available, but requires external tools or configuration
@@ -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.',
},
],
}
+2 -1
View File
@@ -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,
@@ -47,6 +47,7 @@ const ALL_GROUPS: readonly ContentListingGroup[] = [
authPricing,
authNextSteps,
databaseGetStarted,
databaseMultigresWhatYouGet,
databaseNextSteps,
functionsGetStarted,
functionsExamplesSupabase,
@@ -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)}`
+36 -3
View File
@@ -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',
+1 -1
View File
@@ -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(),
+4
View File
@@ -539,6 +539,10 @@ Write _microservices_, not _micro-services_.
Use _might_ for possibility or an uncertain outcome.
### Multigres
Use _Multigres_ for the product name. Don't write _multi-gres_ or _MultiGres_.
### must
Use _must_ or _need to_ for a requirement. Don't use _must_ for a recommendation.
@@ -37,7 +37,7 @@ export function HighAvailabilityBadge({ size = 'default' }: HighAvailabilityBadg
globally distributed deployments.
</p>
<Link
href={`${DOCS_URL}/guides/deployment/high-availability`}
href={`${DOCS_URL}/guides/database/multigres`}
target="_blank"
rel="noopener noreferrer"
className="mt-1 inline-flex items-center gap-1 text-xs text-foreground-lighter transition-colors hover:text-foreground"