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) image #### Compatibility [(PR preview)](https://docs-git-nikrichers-mul-452-documentation-for-m-6f8a59-supabase.vercel.app/docs/guides/database/multigres/compatibility) image ### 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 }) { )}
    {items.map((item) => { + const key = `${group.id}-${item.href ?? item.title}` + const panel = ( + {item.badge} + ) : undefined + } + > + {item.badge && item.badgePosition === 'below' && ( + + {item.badge} + + )} + {item.subtitle && ( + {item.subtitle} + )} + {item.description} + + ) + const listContent = ( + <> + {item.title}: {item.description} + + ) + + if (!item.href) { + return ( +
  • + {isGrid ? panel : listContent} +
  • + ) + } + 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.