Supabase Documentation Audit
Supabase ships an enormous, generally high-quality documentation set with llms-full.txt, llms.txt, and product-level coverage that most competitors lack. But the audit surfaces a cluster of dead canonical URLs, several silent breaking changes shipping faster than the docs can absorb them, contradictory key/limit guidance, and reference pages so heavy they exceed normal fetch budgets — issues that affect both human developers and AI agents trying to parse the docs programmatically.
1. Canonical GraphQL guide returns 404 despite being a top-level product (critical)
Location: https://supabase.com/docs/guides/graphql
Problem: /llms-full.txt and the docs top-nav both list "GraphQL API" as a core module ("GraphQL via pg_graphql"), but the canonical-looking landing page /docs/guides/graphql returns HTTP 404. Compounding this, the January 2026 changelog item "pg_graphql — extension disabled by default on new projects (breaking change)" means new projects don't even ship GraphQL on by default — yet the entry-point guide is missing.
Consequence: A developer arriving from the navigation or llms-full.txt index has no place to learn (a) that pg_graphql is now opt-in on new projects, (b) how to enable it, or (c) what the GraphQL surface even looks like. AI agents indexing the site via the advertised llms files will encounter a dead canonical for a product the index promises exists.
The fix: Restore /docs/guides/graphql (or redirect) and prominently surface the "disabled by default on new projects" change with enablement instructions. Audit all routes referenced by llms-full.txt against the live site and add a CI check.
2. Multiple dead canonical pages linked from indexes and adjacent guides (critical)
Location: Various — confirmed 404s:
/docs/guides/troubleshooting/docs/guides/auth/auth-deep-linking/docs/guides/database/postgres/setup-readonly/docs/guides/functions/deno-runtime/docs/guides/database/replication/setting-up-replication/docs/guides/api/rest/api-keys
Problem: Six canonical-looking URLs that look like first-class topics (deep linking is referenced from mobile quickstarts; the Edge Functions overview repeatedly calls itself a "Deno compatible runtime" yet /guides/functions/deno-runtime is missing; /guides/api/rest/api-keys is the path a developer would intuit from the URL hierarchy when the working page is actually /guides/api/api-keys).
Consequence: Inbound links from search engines, blog posts, and AI agents constructing URLs from the docs' own naming patterns all hit dead ends. The /api/rest/api-keys 404 is especially damaging because API keys are the very thing that's mid-deprecation — see Issue #4.
The fix: Either restore each page or add explicit redirects from the conventional path to the actual one. Add a docs link-checker to CI that crawls every URL in llms-full.txt and every internal anchor.
3. Management API reference pages exceed 10 MB single-page weight (significant)
Location: /docs/reference/api/start and /docs/reference/api/introduction
Problem: Both pages exceeded a 10 MB content-length limit on fetch. That strongly implies the Management API reference is being rendered as one monolithic document rather than split per-endpoint.
Consequence: Browsers chew CPU and memory loading the page; mobile reads are painful; and — most importantly for the agent-parsing focus — LLM-driven tools cannot fit the page into a single context window or fetch budget. The advertised llms-full.txt becomes useless for the Management API specifically, because the underlying reference is too large to chunk reliably. Search inside the page also degrades.
The fix: Split the Management API reference into per-resource or per-endpoint pages (the JavaScript reference is already structured this way). Publish a machine-readable OpenAPI spec at a stable URL and link it prominently from the reference index so agents can consume the spec instead of scraping HTML.
4. API key migration is half-explained and the conventional URL 404s (significant)
Location: /docs/guides/api/api-keys, /docs/guides/api/rest/api-keys (404), /docs/guides/getting-started/quickstarts/nextjs, /docs/guides/functions/secrets
Problem: Supabase is mid-deprecation from JWT-based anon/service_role keys to sb_publishable_…/sb_secret_… keys. The story is inconsistent across the docs:
- The Next.js quickstart says "legacy keys remain functional through end of 2026" — but no other page surfaces that hard date.
/guides/functions/secretslists both new (SUPABASE_PUBLISHABLE_KEYS,SUPABASE_SECRET_KEYS) and legacy (SUPABASE_ANON_KEY,SUPABASE_SERVICE_ROLE_KEY) reserved env names side-by-side with no migration ordering.- The conventional URL
/guides/api/rest/api-keys404s, while/guides/api/api-keysworks. - No single page lays out: when legacy stops working, how the two key families coexist during transition, and whether SDK versions differ in support.
Consequence: A developer (or coding agent) reading the secrets page sees four key env vars and has no clear signal which to use. Snippets copy-pasted from older blog posts using anon/service_role will keep working through 2026 and then silently break.
The fix: Create a single canonical "Key migration guide" page with a dated deprecation timeline, link it from every page that mentions either key family, and add a clear "new projects use sb_publishable / sb_secret; legacy keys removed YYYY-MM-DD" callout on the secrets reference.
5. Realtime broadcast payload limit contradicts Edge Function ecosystem expectations and isn't cross-referenced (significant)
Location: /docs/guides/realtime/quotas, /docs/guides/functions/limits
Problem: Realtime broadcast payloads are capped at 256 KB (Free) / 3,000 KB (Pro/Team). Postgres Change payloads are capped at 1,024 KB. Edge Functions don't document request or response size limits at all (the limits page explicitly says it "does not specify limits for request size or response size"). There is no cross-reference between these surfaces.
Consequence: A developer wiring Edge Functions to Realtime broadcasts — a documented use case — has no way to know the end-to-end payload budget. Agents generating code that pipes Function output to a Realtime channel will silently fail at 256 KB on Free-plan projects.
The fix: Document Edge Function request and response size limits on /guides/functions/limits. Add a "payload size across products" matrix that lists the limit for Functions, Realtime broadcast, Postgres changes, Storage upload, and Data API in one place.
6. Recent breaking changes are buried in the changelog with no migration pages (significant)
Location: /changelog (May 2026 view)
Problem: The changelog lists five breaking or end-of-life changes inside a tight window:
- "OAuth Token Endpoint (May 1) — HTTP status code changing from 201 to 200"
- "Data API Exposure (April 28) — new tables in the public schema no longer auto-exposed"
- "pg_graphql (January 2026) — extension disabled by default on new projects"
- "Edge Functions Rate Limits (March 11) — new rate-limiting on recursive/nested function calls"
- "Postgres 14 Support Ending (May 12, 2026) — deprecated as of July 1, 2026"
None of these are surfaced as banners on the affected product pages. The Data API quickstart still shows the implicit-exposure model. The Edge Functions limits page mentions "~5000 requests per minute" for recursive calls but doesn't flag it as a March 2026 behavior change. The pg_graphql change has no GraphQL guide to surface it on (see Issue #1). The Postgres 14 EOL date appears nowhere on the database overview or migration guides.
Consequence: Developers (and agents) reading the canonical product page get the pre-breaking behavior with no warning. A status-code change from 201 → 200 is exactly the kind of thing that silently breaks integrations that assert on response codes. A Postgres EOL date that lives only in the changelog will be missed by teams on long release cycles.
The fix: Add a dated "Recent breaking changes" banner block on the top of each affected product page that links to the changelog entry, and write a brief migration page for each item rather than relying on the changelog entry alone.
7. JavaScript and Python reference landing pages have no install command or version (significant)
Location: /docs/reference/javascript/introduction, /docs/reference/python/introduction
Problem: Both reference "introduction" pages contain only a one-line description. The JS one doesn't show npm install @supabase/supabase-js, doesn't state that the current version is v2, and doesn't link prominently to /reference/javascript/installing. The Python landing page is worse: it doesn't even include the supabase-py install command — the user has to navigate to a separate "Installing" page or the GitHub repo.
Consequence: This is the canonical landing page an LLM or developer reaches when typing "supabase python sdk docs." For a coding agent doing zero-shot code generation, the lack of an install command at the entry point means the agent must perform a second lookup, or worse, fabricate one.
The fix: Put the canonical install command, current version, and a minimal createClient snippet at the top of every reference introduction page. This is one of the highest-value pages for AI-agent parsing in the entire site.
8. Password policy is undocumented (significant)
Location: /docs/guides/auth/passwords
Problem: The password authentication guide contains no statement of minimum length, maximum length, character class requirements, or breach-list checks. Compare with the depth of the JWT and session pages, which document timeouts to the second.
Consequence: A developer cannot answer "what password rules do my users have to obey?" from the docs. They must guess or test empirically. Compliance teams cannot reference an authoritative statement of password policy. Agents generating signup forms with client-side validation have to invent rules.
The fix: Add an explicit Password requirements section: min/max length, allowed characters, whether HaveIBeenPwned-style checks are applied, and how to configure stricter rules at the project level.
9. Social-login overview never enumerates first-class providers (significant)
Location: /docs/guides/auth/social-login
Problem: The overview says "Supabase supports a suite of social providers" and then doesn't list which ones. /llms-full.txt claims "20+ social providers" but the docs landing page that should canonically enumerate them only describes the "Custom OAuth/OIDC Providers" fallback.
Consequence: A developer evaluating Supabase cannot answer "does Supabase support [X] out of the box?" from the overview. AI agents asked "which auth providers does Supabase support natively" cannot extract a structured list. Sub-pages exist (e.g., /social-login/auth-google), but discoverability depends on guessing.
The fix: On the social-login overview, render a parseable list (table or bullet list) of every first-class provider with a link to its configuration guide. Mirror the same list in llms-full.txt.
10. Regions page never enumerates the available AWS regions (significant)
Location: /docs/guides/platform/regions
Problem: The Regions page distinguishes between "General Regions" (best-effort placement) and "Specific Regions" (pick an exact AWS region) and notes that General Regions "do not yet support read replicas or API management." But the page never lists which AWS regions are actually available — it just says "an available AWS region within that area."
Consequence: A developer choosing a region for compliance, latency, or read-replica reasons cannot answer "is Frankfurt available? São Paulo? Mumbai?" from the docs. This is the same structural defect as Issue #9 — an overview page that promises a set and then withholds the enumeration. Agents asked "where can I deploy Supabase" have no parseable answer.
The fix: Publish a table of AWS regions with columns for region code, friendly name, General vs Specific availability, and read-replica support. Mirror it in llms-full.txt.
11. statement_timeout defaults are documented but idle_in_transaction_session_timeout and lock_timeout are not (significant)
Location: /docs/guides/database/postgres/timeouts
Problem: The timeouts page enumerates default statement_timeout per role (anon: 3s, authenticated: 8s, service_role/postgres: capped at 2min) but does not document defaults for idle_in_transaction_session_timeout or lock_timeout — two of the three timeouts the page is named after.
Consequence: A developer debugging "why did my long-running transaction get killed" or "why is my migration blocked behind a lock" has no authoritative number to anchor on. Compliance reviews of timeout behavior can't be completed from the docs. Same defect as Issue #8 — a reference page that documents one parameter and silently omits the neighbors.
The fix: Add the default values for idle_in_transaction_session_timeout and lock_timeout per role, in the same table format used for statement_timeout.
12. /llms-full.txt doesn't reflect the breadth of platform limits the docs actually contain (significant)
Location: /llms-full.txt, /llms.txt
Problem: The headline llms-full.txt lists products and capabilities but does not include the concrete numbers an agent most often needs: Edge Function memory (256 MB), CPU time (2s), Realtime broadcast payload limits, Storage upload tiers (6 MB / 5 GB / TUS), connection limits per compute size, statement_timeout per role. These are scattered across at least eight different pages.
Consequence: The whole point of llms-full.txt is to give an agent a single high-quality digest. Today, agents indexing only the llms file will know Supabase has "Edge Functions" but not that an Edge Function dies at 2s of CPU on Free — exactly the constraint that determines whether to use Functions or background workers.
The fix: Expand llms-full.txt with a "Limits" section that aggregates the numbers from /guides/functions/limits, /guides/realtime/quotas, /guides/storage/uploads/standard-uploads, /guides/platform/compute-and-disk, and /guides/platform/billing-on-supabase into a single parseable block.
13. Anonymous sign-in abuse warning lives in one place with no cross-link from billing or quotas (significant)
Location: /docs/guides/auth/auth-anonymous
Problem: The anonymous-auth page contains a strong warning: "Bad actors can abuse the endpoint to increase your database size drastically. It is strongly recommended to enable invisible CAPTCHA or Cloudflare Turnstile to prevent abuse for anonymous sign-ins." This is a real footgun — anonymous sign-ins create real user rows. But the warning is not surfaced on the billing page's "Database Size" line, the auth rate-limits page (which lists anon sign-ins as having an uncustomizable IP-based rate limit), or the captcha guide.
Consequence: A developer following the "anonymous shopping cart" pattern from /guides/auth/users may never read the dedicated anonymous-auth page; an agent generating signInAnonymously() boilerplate has no signal that captcha is effectively mandatory. The first signal of abuse is the database size bill.
The fix: Add the captcha-recommendation callout to the auth rate-limits page, the billing page's database-size section, and any quickstart that uses anonymous auth.
14. cron.job_run_details growth can fail upgrades, but the cron guide never mentions it (significant)
Location: /docs/guides/cron, /docs/guides/platform/migrating-and-upgrading-projects
Problem: The upgrade guide states: extremely large cron.job_run_details tables "can cause at best unnecessary performance degradation, or at worst, upgrade process failures." But the cron guide — where this table is created and the page where developers schedule jobs — never mentions the table exists, never recommends pruning, and never links to the upgrade caveat.
Consequence: A developer who follows /guides/cron to schedule a job-every-minute pattern will accumulate an unbounded cron.job_run_details table for months, then discover at upgrade time that their pg_upgrade fails. Agents generating cron jobs have no signal that retention management is required.
The fix: On the cron guide, add a "Retention" section that explains cron.job_run_details, links to a pruning recipe, and cross-links the upgrade-failure caveat from the migration guide.
15. Quickstart cURL example has empty apikey header and project URL (minor)
Location: /docs/guides/api/quickstart
Problem: The cURL example is rendered as:
curl 'https://.supabase.co/rest/v1/leaderboard?select=*&order=score.desc' \
-H "apikey: "
Both the project subdomain and the apikey value are empty rather than marked with <your-project-ref> / <YOUR_PUBLISHABLE_KEY> style placeholders.
Consequence: A developer who copies the snippet gets a request that resolves to https://.supabase.co/... (nonsense) and an empty apikey: header. AI agents extracting the snippet have no signal that values are missing — there's no placeholder pattern to substitute against.
The fix: Use explicit, conventional placeholders such as https://<PROJECT_REF>.supabase.co/... and apikey: <SUPABASE_PUBLISHABLE_KEY>. Mark placeholder variables consistently across every code sample on the site.
16. @supabase/ssr is described as the recommended path while still labelled beta (minor)
Location: /docs/guides/auth/server-side, /docs/guides/auth/auth-helpers
Problem: The auth-helpers page directs users to "uninstall framework-specific Auth Helpers packages…and install the unified @supabase/ssr package instead." The server-side guide then states that @supabase/ssr "is currently in beta" with "the API is still unstable and may have breaking changes in the future."
Consequence: Developers are simultaneously told to migrate off the older helpers and warned that the migration target is unstable. There is no statement of when @supabase/ssr will be GA, what the supported migration window is, or whether the previous helpers will be removed.
The fix: Either remove the beta label (if the API is actually stable enough to recommend as the default migration target) or add a dated GA roadmap and explicit support policy for the framework-specific helpers being deprecated.
17. Connection-management guidance lives on a different page than the numbers it references (minor)
Location: /docs/guides/database/connection-management vs /docs/guides/platform/compute-and-disk
Problem: The connection-management page tells users to keep pool size below "40% of the Database Max Connections" if they use PostgREST heavily — but doesn't include the table of Max Connections by compute size. That table lives on /guides/platform/compute-and-disk (Nano/Micro: 60, Small: 90, Medium: 120, Large: 160, up to 500).
Consequence: Sizing a connection pool requires reading two pages and doing arithmetic. Agents reading only the connection-management page produce confidently wrong pool sizes.
The fix: Inline the Max Connections table (or a compact summary) on the connection-management page, with a worked example for each compute tier.
18. Default Site URL is http://localhost:3000 with no production warning (minor)
Location: /docs/guides/auth/redirect-urls
Problem: The redirect-URLs page states: "The Site URL in URL Configuration defines the default redirect URL when no redirectTo is specified in the code. Default: http://localhost:3000." There is no callout that this default is unsafe to leave in place once the project is in production — emails sent from a production project with the default Site URL will redirect users to a local-only address.
Consequence: Magic links and password-reset emails for production users can route to http://localhost:3000, an address that resolves only on the user's own machine if anything. The failure is silent in development (where it works) and only manifests in production.
The fix: Add a "Production checklist" callout on the redirect-URLs page warning that the default Site URL must be changed before going live, and surface the same warning on the Auth getting-started page.
19. Phone OTP 60-second verification window isn't surfaced as a constraint (minor)
Location: /docs/guides/auth/phone-login
Problem: The phone-login page mentions that users "must verify [the 6-digit code] within 60 seconds." A 60-second window is unusually tight compared to email OTPs (which can be valid up to 86,400 seconds per /auth/auth-magic-link) and against general industry norms for SMS OTP (typically 5–10 minutes). The constraint is mentioned once in prose with no callout, no configurability section, and no UX guidance.
Consequence: Developers shipping phone-login UIs without an obvious resend timer will get user complaints from anyone who didn't read the SMS within 60 seconds (a common scenario on slow carriers or with notifications disabled). Agents generating phone-login forms have no signal that a resend affordance is effectively mandatory.
The fix: Surface the 60-second window as a labeled constraint (callout or table row), explain whether it is configurable, and recommend a resend-timer pattern in the example UI.
What they do well
- The platform publishes both
llms.txtandllms-full.txtat the root — more than most peers, and a real asset for AI tooling once the gaps above are fixed. - Auth and RLS pages are unusually careful about security nuance — the
user_metadatavsapp_metadatadistinction, theauth.uid() IS NOT NULLrecommendation, and the(select auth.uid())performance trick are all called out with concrete benchmark numbers. - The Realtime quotas page is exemplary: every limit is tabulated by plan in a single, parseable place rather than scattered through prose.
Top 3 recommendations
- Fix the dead canonical URLs and add a link-checker to CI — the GraphQL, troubleshooting, deep-linking, deno-runtime, and
/api/rest/api-keys404s are the single highest-impact issue, both for humans and for agents traversingllms-full.txt. - Surface breaking changes on the affected product pages — five breaking or EOL changes in a month deserve banners on the canonical guides, not just changelog entries.
- Split the Management API reference and publish a stable OpenAPI spec URL — a 10 MB single-page reference is the opposite of agent-friendly; a machine-readable spec replaces dozens of prose lookups.