# Table of Contents - [Glossary | Supabase Docs](#glossary-supabase-docs) - [Cron | Supabase Docs](#cron-supabase-docs) - [Install | Supabase Docs](#install-supabase-docs) - [Integrations | Supabase Docs](#integrations-supabase-docs) - [Expose Queues for local and self-hosted Supabase | Supabase Docs](#expose-queues-for-local-and-self-hosted-supabase-supabase-docs) - [API | Supabase Docs](#api-supabase-docs) - [Supabase Marketplace | Supabase Docs](#supabase-marketplace-supabase-docs) - [Supabase Security | Supabase Docs](#supabase-security-supabase-docs) - [Vercel Marketplace | Supabase Docs](#vercel-marketplace-supabase-docs) - [Security testing of your Supabase projects | Supabase Docs](#security-testing-of-your-supabase-projects-supabase-docs) - [Supabase Queues | Supabase Docs](#supabase-queues-supabase-docs) - [SOC 2 Compliance and Supabase | Supabase Docs](#soc-2-compliance-and-supabase-supabase-docs) - [Platform Audit Logs | Supabase Docs](#platform-audit-logs-supabase-docs) - [HIPAA Compliance and Supabase | Supabase Docs](#hipaa-compliance-and-supabase-supabase-docs) - [Restoring a downloaded backup locally | Supabase Docs](#restoring-a-downloaded-backup-locally-supabase-docs) - [Reports | Supabase Docs](#reports-supabase-docs) - [Managing config and secrets | Supabase Docs](#managing-config-and-secrets-supabase-docs) - [Metrics API | Supabase Docs](#metrics-api-supabase-docs) - [Local Development & CLI | Supabase Docs](#local-development-cli-supabase-docs) - [Telemetry | Supabase Docs](#telemetry-supabase-docs) - [Advanced Log Filtering | Supabase Docs](#advanced-log-filtering-supabase-docs) - [Settings | Supabase Docs](#settings-supabase-docs) - [Log Drains | Supabase Docs](#log-drains-supabase-docs) - [Realtime Pricing | Supabase Docs](#realtime-pricing-supabase-docs) - [Branching | Supabase Docs](#branching-supabase-docs) - [Listening to Postgres Changes with Flutter | Supabase Docs](#listening-to-postgres-changes-with-flutter-supabase-docs) - [Using Realtime Presence with Flutter | Supabase Docs](#using-realtime-presence-with-flutter-supabase-docs) - [Customizing email templates | Supabase Docs](#customizing-email-templates-supabase-docs) - [SQL to REST API Translator | Supabase Docs](#sql-to-rest-api-translator-supabase-docs) - [Realtime Concepts | Supabase Docs](#realtime-concepts-supabase-docs) - [Quickstart | Supabase Docs](#quickstart-supabase-docs) - [Deployment & Branching | Supabase Docs](#deployment-branching-supabase-docs) - [Data REST API | Supabase Docs](#data-rest-api-supabase-docs) - [Build an API route in less than 2 minutes. | Supabase Docs](#build-an-api-route-in-less-than-2-minutes-supabase-docs) - [Benchmarks | Supabase Docs](#benchmarks-supabase-docs) - [Realtime Limits | Supabase Docs](#realtime-limits-supabase-docs) - [Consuming Supabase Queue Messages with Edge Functions | Supabase Docs](#consuming-supabase-queue-messages-with-edge-functions-supabase-docs) - [Using Realtime with Next.js | Supabase Docs](#using-realtime-with-next-js-supabase-docs) - [Secure configuration of Supabase products | Supabase Docs](#secure-configuration-of-supabase-products-supabase-docs) - [Permissions | Supabase Docs](#permissions-supabase-docs) - [Your monthly invoice | Supabase Docs](#your-monthly-invoice-supabase-docs) - [Secure configuration of Supabase platform | Supabase Docs](#secure-configuration-of-supabase-platform-supabase-docs) - [Realtime | Supabase Docs](#realtime-supabase-docs) - [Using Custom Schemas | Supabase Docs](#using-custom-schemas-supabase-docs) - [Realtime Architecture | Supabase Docs](#realtime-architecture-supabase-docs) - [Quickstart | Supabase Docs](#quickstart-supabase-docs) - [Credits | Supabase Docs](#credits-supabase-docs) - [Manage your subscription | Supabase Docs](#manage-your-subscription-supabase-docs) - [Restore to a new project | Supabase Docs](#restore-to-a-new-project-supabase-docs) - [Hardening the Data API | Supabase Docs](#hardening-the-data-api-supabase-docs) - [HIPAA Projects | Supabase Docs](#hipaa-projects-supabase-docs) - [Understanding API keys | Supabase Docs](#understanding-api-keys-supabase-docs) - [Multi-factor Authentication | Supabase Docs](#multi-factor-authentication-supabase-docs) - [Get set up for billing | Supabase Docs](#get-set-up-for-billing-supabase-docs) - [Self-Hosting | Supabase Docs](#self-hosting-supabase-docs) - [Sentry integration | Supabase Docs](#sentry-integration-supabase-docs) - [Maturity Model | Supabase Docs](#maturity-model-supabase-docs) - [Project Transfers | Supabase Docs](#project-transfers-supabase-docs) - [Converting SQL to JavaScript API | Supabase Docs](#converting-sql-to-javascript-api-supabase-docs) - [PrivateLink | Supabase Docs](#privatelink-supabase-docs) - [Resources | Supabase Docs](#resources-supabase-docs) - [Migrating within Supabase | Supabase Docs](#migrating-within-supabase-supabase-docs) - [Enabling MCP Server Access | Supabase Docs](#enabling-mcp-server-access-supabase-docs) - [Supabase Platform | Supabase Docs](#supabase-platform-supabase-docs) - [Available regions | Supabase Docs](#available-regions-supabase-docs) - [AWS Marketplace | Supabase Docs](#aws-marketplace-supabase-docs) - [Performance Tuning | Supabase Docs](#performance-tuning-supabase-docs) - [Understanding Database and Disk Size | Supabase Docs](#understanding-database-and-disk-size-supabase-docs) - [Upgrading | Supabase Docs](#upgrading-supabase-docs) - [Dedicated IPv4 Address for Ingress | Supabase Docs](#dedicated-ipv4-address-for-ingress-supabase-docs) - [Pricing | Supabase Docs](#pricing-supabase-docs) - [Storage | Supabase Docs](#storage-supabase-docs) - [Copy Storage Objects from Platform | Supabase Docs](#copy-storage-objects-from-platform-supabase-docs) - [Configure Reverse Proxy and HTTPS | Supabase Docs](#configure-reverse-proxy-and-https-supabase-docs) - [Restore a Platform Project to Self-Hosted | Supabase Docs](#restore-a-platform-project-to-self-hosted-supabase-docs) - [About billing on Supabase | Supabase Docs](#about-billing-on-supabase-supabase-docs) - [Enable SSO for Your Organization | Supabase Docs](#enable-sso-for-your-organization-supabase-docs) - [Declarative database schemas | Supabase Docs](#declarative-database-schemas-supabase-docs) - [Read Replicas | Supabase Docs](#read-replicas-supabase-docs) - [Local development with schema migrations | Supabase Docs](#local-development-with-schema-migrations-supabase-docs) - [Operational Error Codes | Supabase Docs](#operational-error-codes-supabase-docs) - [Database Backups | Supabase Docs](#database-backups-supabase-docs) - [Configure S3 Storage | Supabase Docs](#configure-s3-storage-supabase-docs) - [Choosing a Client | Supabase Docs](#choosing-a-client-supabase-docs) - [Postgres SSL Enforcement | Supabase Docs](#postgres-ssl-enforcement-supabase-docs) - [Build a Supabase Integration | Supabase Docs](#build-a-supabase-integration-supabase-docs) - [Database Migrations | Supabase Docs](#database-migrations-supabase-docs) - [Google Colab | Supabase Docs](#google-colab-supabase-docs) - [Subscribing to Database Changes | Supabase Docs](#subscribing-to-database-changes-supabase-docs) - [Network Restrictions | Supabase Docs](#network-restrictions-supabase-docs) - [Configure Phone Login & MFA | Supabase Docs](#configure-phone-login-mfa-supabase-docs) - [Python client | Supabase Docs](#python-client-supabase-docs) - [General configuration | Supabase Docs](#general-configuration-supabase-docs) - [Logging | Supabase Docs](#logging-supabase-docs) - [Seeding your database | Supabase Docs](#seeding-your-database-supabase-docs) - [Storage Quickstart | Supabase Docs](#storage-quickstart-supabase-docs) - [How to do automatic retries with `supabase-js` | Supabase Docs](#how-to-do-automatic-retries-with-supabase-js-supabase-docs) - [Billing FAQ | Supabase Docs](#billing-faq-supabase-docs) - [Going to Production | Supabase Docs](#going-to-production-supabase-docs) - [Structured and Unstructured | Supabase Docs](#structured-and-unstructured-supabase-docs) - [Compute and Disk | Supabase Docs](#compute-and-disk-supabase-docs) - [Identities | Supabase Docs](#identities-supabase-docs) - [OAuth 2.1 Server | Supabase Docs](#oauth-2-1-server-supabase-docs) - [Building ChatGPT plugins | Supabase Docs](#building-chatgpt-plugins-supabase-docs) - [Adding generative Q&A for your documentation | Supabase Docs](#adding-generative-q-a-for-your-documentation-supabase-docs) - [New API Keys and Asymmetric Authentication | Supabase Docs](#new-api-keys-and-asymmetric-authentication-supabase-docs) - [Custom Domains | Supabase Docs](#custom-domains-supabase-docs) - [Creating API Routes | Supabase Docs](#creating-api-routes-supabase-docs) - [Upgrade to Postgres 17 | Supabase Docs](#upgrade-to-postgres-17-supabase-docs) - [Self-Hosted Functions | Supabase Docs](#self-hosted-functions-supabase-docs) - [Hugging Face Inference API | Supabase Docs](#hugging-face-inference-api-supabase-docs) - [Concepts | Supabase Docs](#concepts-supabase-docs) - [Enterprise Single Sign-On | Supabase Docs](#enterprise-single-sign-on-supabase-docs) - [Users | Supabase Docs](#users-supabase-docs) - [Control your costs | Supabase Docs](#control-your-costs-supabase-docs) - [Manage your usage | Supabase Docs](#manage-your-usage-supabase-docs) - [Password security | Supabase Docs](#password-security-supabase-docs) - [Shared Responsibility Model | Supabase Docs](#shared-responsibility-model-supabase-docs) - [AI & Vectors | Supabase Docs](#ai-vectors-supabase-docs) - [Production Checklist | Supabase Docs](#production-checklist-supabase-docs) - [Custom Claims & Role-based Access Control (RBAC) | Supabase Docs](#custom-claims-role-based-access-control-rbac-supabase-docs) - [Custom Email Templates | Supabase Docs](#custom-email-templates-supabase-docs) - [Rate limits | Supabase Docs](#rate-limits-supabase-docs) - [Migrating to Supabase | Supabase Docs](#migrating-to-supabase-supabase-docs) - [Choosing your Compute Add-on | Supabase Docs](#choosing-your-compute-add-on-supabase-docs) - [Send emails with custom SMTP | Supabase Docs](#send-emails-with-custom-smtp-supabase-docs) - [Signing out | Supabase Docs](#signing-out-supabase-docs) - [Vector indexes | Supabase Docs](#vector-indexes-supabase-docs) - [Vector columns | Supabase Docs](#vector-columns-supabase-docs) - [Auth Audit Logs | Supabase Docs](#auth-audit-logs-supabase-docs) - [Enable CAPTCHA Protection | Supabase Docs](#enable-captcha-protection-supabase-docs) - [PGMQ Extension | Supabase Docs](#pgmq-extension-supabase-docs) - [Agent Skills | Supabase Docs](#agent-skills-supabase-docs) - [Semantic search | Supabase Docs](#semantic-search-supabase-docs) - [Server-Side Rendering | Supabase Docs](#server-side-rendering-supabase-docs) - [Supabase for Platforms | Supabase Docs](#supabase-for-platforms-supabase-docs) - [Realtime Reports | Supabase Docs](#realtime-reports-supabase-docs) - [Dart Edge | Supabase Docs](#dart-edge-supabase-docs) - [Engineering for Scale | Supabase Docs](#engineering-for-scale-supabase-docs) - [User sessions | Supabase Docs](#user-sessions-supabase-docs) - [Limits | Supabase Docs](#limits-supabase-docs) - [Pricing | Supabase Docs](#pricing-supabase-docs) - [Edge Functions Architecture | Supabase Docs](#edge-functions-architecture-supabase-docs) - [Local Debugging | Supabase Docs](#local-debugging-supabase-docs) - [Self-Hosting with Docker | Supabase Docs](#self-hosting-with-docker-supabase-docs) - [Securing your API | Supabase Docs](#securing-your-api-supabase-docs) - [Managing Environments | Supabase Docs](#managing-environments-supabase-docs) - [Realtime Authorization | Supabase Docs](#realtime-authorization-supabase-docs) - [Status codes | Supabase Docs](#status-codes-supabase-docs) - [Background Tasks | Supabase Docs](#background-tasks-supabase-docs) - [Environment Variables | Supabase Docs](#environment-variables-supabase-docs) - [Regional Invocations | Supabase Docs](#regional-invocations-supabase-docs) - [Architecture | Supabase Docs](#architecture-supabase-docs) - [Function Configuration | Supabase Docs](#function-configuration-supabase-docs) - [Using Wasm modules | Supabase Docs](#using-wasm-modules-supabase-docs) - [Handling Compressed Requests | Supabase Docs](#handling-compressed-requests-supabase-docs) - [User Management | Supabase Docs](#user-management-supabase-docs) - [Scheduling Edge Functions | Supabase Docs](#scheduling-edge-functions-supabase-docs) - [Edge Functions | Supabase Docs](#edge-functions-supabase-docs) - [Development Environment | Supabase Docs](#development-environment-supabase-docs) - [Error Handling | Supabase Docs](#error-handling-supabase-docs) - [CORS (Cross-Origin Resource Sharing) support for Invoking from the browser | Supabase Docs](#cors-cross-origin-resource-sharing-support-for-invoking-from-the-browser-supabase-docs) - [Getting Started | Supabase Docs](#getting-started-supabase-docs) - [Model context protocol (MCP) | Supabase Docs](#model-context-protocol-mcp-supabase-docs) - [Identity Linking | Supabase Docs](#identity-linking-supabase-docs) - [Keyword search | Supabase Docs](#keyword-search-supabase-docs) - [Email Templates | Supabase Docs](#email-templates-supabase-docs) - [Presence | Supabase Docs](#presence-supabase-docs) - [Custom OAuth/OIDC Providers | Supabase Docs](#custom-oauth-oidc-providers-supabase-docs) - [Sign in with Web3 | Supabase Docs](#sign-in-with-web3-supabase-docs) - [Deploy MCP servers | Supabase Docs](#deploy-mcp-servers-supabase-docs) - [Logging | Supabase Docs](#logging-supabase-docs) - [Managing dependencies | Supabase Docs](#managing-dependencies-supabase-docs) - [JWT Signing Keys | Supabase Docs](#jwt-signing-keys-supabase-docs) - [AI Prompts | Supabase Docs](#ai-prompts-supabase-docs) - [RAG with Permissions | Supabase Docs](#rag-with-permissions-supabase-docs) - [Getting Started with Edge Functions (Dashboard) | Supabase Docs](#getting-started-with-edge-functions-dashboard-supabase-docs) - [Auth architecture | Supabase Docs](#auth-architecture-supabase-docs) - [Hybrid search | Supabase Docs](#hybrid-search-supabase-docs) - [Phone Login | Supabase Docs](#phone-login-supabase-docs) - [Development tips | Supabase Docs](#development-tips-supabase-docs) - [Configure SAML SSO | Supabase Docs](#configure-saml-sso-supabase-docs) - [JSON Web Token (JWT) | Supabase Docs](#json-web-token-jwt-supabase-docs) - [Redirect URLs | Supabase Docs](#redirect-urls-supabase-docs) - [Integrating with Supabase Storage | Supabase Docs](#integrating-with-supabase-storage-supabase-docs) - [Passwordless email logins | Supabase Docs](#passwordless-email-logins-supabase-docs) - [LangChain | Supabase Docs](#langchain-supabase-docs) - [Testing your Edge Functions | Supabase Docs](#testing-your-edge-functions-supabase-docs) - [Configure Social Login (OAuth) Providers | Supabase Docs](#configure-social-login-oauth-providers-supabase-docs) - [Auth Hooks | Supabase Docs](#auth-hooks-supabase-docs) - [Integrating with Supabase Database (Postgres) | Supabase Docs](#integrating-with-supabase-database-postgres-supabase-docs) - [JWT Claims Reference | Supabase Docs](#jwt-claims-reference-supabase-docs) - [File Storage | Supabase Docs](#file-storage-supabase-docs) --- # Glossary | Supabase Docs Resources Glossary ============ * * * Definitions for terminology and acronyms used in the Supabase documentation. Access token[#](https://supabase.com/docs/guides/resources/glossary#access-token) ---------------------------------------------------------------------------------- An access token is a short-lived (usually no more than 1 hour) token that authorizes a client to access resources on a server. It comes in the form of a [JSON Web Token (JWT)](https://supabase.com/docs/guides/resources/glossary#json-web-token-jwt) . Authentication[#](https://supabase.com/docs/guides/resources/glossary#authentication) -------------------------------------------------------------------------------------- Authentication (often abbreviated `authn.`) is the process of verifying the identity of a user. Verification of the identity of a user can happen in multiple ways: 1. Asking users for something they know. For example: password, passphrase. 2. Checking that users have access to something they own. For example: an email address, a phone number, a hardware key, recovery codes. 3. Confirming that users have some biological features. For example: a fingerprint, a certain facial structure, an iris print. Authenticator app[#](https://supabase.com/docs/guides/resources/glossary#authenticator-app) -------------------------------------------------------------------------------------------- An authenticator app generates time-based one-time passwords (TOTPs). These passwords are generated based off a long and difficult to guess secret string. The secret is initially passed to the application by scanning a QR code. Authorization[#](https://supabase.com/docs/guides/resources/glossary#authorization) ------------------------------------------------------------------------------------ Authorization (often abbreviated `authz.`) is the process of verifying if a certain identity is allowed to access resources. Authorization often occurs by verifying an access token. Identity provider[#](https://supabase.com/docs/guides/resources/glossary#identity-provider) -------------------------------------------------------------------------------------------- An identity provider is software or service that allows third-party applications to identify users without the exchange of passwords. Social login and enterprise single-sign on won't be possible without identity providers. Social login platforms typically use the OAuth protocol, while enterprise single-sign on is based on the OIDC or SAML protocols. JSON Web Token (JWT)[#](https://supabase.com/docs/guides/resources/glossary#json-web-token-jwt) ------------------------------------------------------------------------------------------------ A [JSON Web Token](https://jwt.io/introduction) is a type of data structure, represented as a string, that usually contains identity and authorization information about a user. It encodes information about its lifetime and is signed with cryptographic key making it tamper resistant. Access tokens are JWTs and by inspecting the information they contain you can allow or deny access to resources. Row level security policies are based on the information present in JWTs. JWT signing secret[#](https://supabase.com/docs/guides/resources/glossary#jwt-signing-secret) ---------------------------------------------------------------------------------------------- JWTs issued by Supabase are signed using the HMAC-SHA256 algorithm. The secret key used in the signing is called the JWT signing secret. You should not share this secret with someone or some thing you don't trust, nor should you post it publicly. Anyone with access to the secret can create arbitrary JWTs. Multi-factor authentication (MFA or 2FA)[#](https://supabase.com/docs/guides/resources/glossary#multi-factor-authentication-mfa-or-2fa) ---------------------------------------------------------------------------------------------------------------------------------------- Multi-factor authentication is the process of authenticating a user's identity by using a combination of factors: something users know, something users have or something they are. Nonce[#](https://supabase.com/docs/guides/resources/glossary#nonce) -------------------------------------------------------------------- Nonce means number used once. In reality though, it is a unique and difficult to guess string used to either initialize a protocol or algorithm securely, or detect abuse in various forms of replay attacks. OAuth[#](https://supabase.com/docs/guides/resources/glossary#oauth) -------------------------------------------------------------------- OAuth is a protocol allowing third-party applications to request and receive authorization from their users. It is typically used to implement social login, and serves as a base for enterprise single-sign on in the OIDC protocol. Applications can request different levels of access, including basic user identification information such as name, email address, and user ID. OIDC[#](https://supabase.com/docs/guides/resources/glossary#oidc) ------------------------------------------------------------------ OIDC stands for OpenID Connect and is a protocol that enables single-sign on for enterprises. OIDC is based on modern web technologies such as OAuth and JSON Web Tokens. It is commonly used instead of the older SAML protocol. One-time password (OTP)[#](https://supabase.com/docs/guides/resources/glossary#one-time-password-otp) ------------------------------------------------------------------------------------------------------ A one-time password is a short, randomly generated and difficult to guess password or code that is sent to a device (like a phone number) or generated by a device or application. Password hashing function[#](https://supabase.com/docs/guides/resources/glossary#password-hashing-function) ------------------------------------------------------------------------------------------------------------ Password hashing functions are specially-designed algorithms that allow web servers to verify a password without storing it as-is. Unlike other difficult to guess strings generated from secure random number generators, passwords are picked by users and often are easy to guess by attackers. These algorithms slow down and make it very costly for attackers to guess passwords. There are three generally accepted password hashing functions: Argon2, bcrypt and scrypt. Password strength[#](https://supabase.com/docs/guides/resources/glossary#password-strength) -------------------------------------------------------------------------------------------- Password strength is a measurement of how difficult a password is to guess. Simple measurement includes calculating the number of possibilities given the types of characters used in the password. For example a password of only letters has fewer variations than ones with letters and digits. Better measurements include strategies such as looking for similarity to words, phrases or already known passwords. PKCE[#](https://supabase.com/docs/guides/resources/glossary#pkce) ------------------------------------------------------------------ Proof Key for Code Exchange is an extension to the OAuth protocol that enables secure exchange of refresh and access tokens between an application (web app, single-page app or mobile app) and the authorization server. It is used in places where the exchange of the refresh and access token may be intercepted by third parties such as other applications running in the operating system. This is a common problem on mobile devices where the operating system may hand out URLs to other applications. This can sometimes be also exploited in single-page apps too. Provider refresh token[#](https://supabase.com/docs/guides/resources/glossary#provider-refresh-token) ------------------------------------------------------------------------------------------------------ A provider refresh token is a refresh token issued by a third-party identity provider which can be used to refresh the provider token returned. Provider tokens[#](https://supabase.com/docs/guides/resources/glossary#provider-tokens) ---------------------------------------------------------------------------------------- A provider token is a long-lived token issued by a third-party identity provider. These are issued by social login services (e.g., Google, Twitter, Apple, Microsoft) and uniquely identify a user on those platforms. Refresh token[#](https://supabase.com/docs/guides/resources/glossary#refresh-token) ------------------------------------------------------------------------------------ A refresh token is a long-lived (in most cases with an indefinite lifetime) token that is meant to be stored and exchanged for a new refresh and access tokens only once. Once a refresh token is exchanged it becomes invalid, and can't be exchanged again. In practice, though, a refresh token can be exchanged multiple times but in a short time window. Refresh token flow[#](https://supabase.com/docs/guides/resources/glossary#refresh-token-flow) ---------------------------------------------------------------------------------------------- The refresh token flow is a mechanism that issues a new refresh and access token on the basis of a valid refresh token. It is used to extend authorization access for an application. An application that is being constantly used will invoke the refresh token flow just before the access token expires. Replay attack[#](https://supabase.com/docs/guides/resources/glossary#replay-attack) ------------------------------------------------------------------------------------ A replay attack is when sensitive information is stolen or intercepted by attackers who then attempt to use it again (thus replay) in an effort to compromise a system. Commonly replay attacks can be mitigated with the proper use of nonces. Row level security policies (RLS)[#](https://supabase.com/docs/guides/resources/glossary#row-level-security-policies-rls) -------------------------------------------------------------------------------------------------------------------------- Row level security policies are special objects within the Postgres database that limit the available operations or data returned to clients. RLS policies use information contained in a JWT to identify users and the actions and data they are allowed to perform or view. SAML[#](https://supabase.com/docs/guides/resources/glossary#saml) ------------------------------------------------------------------ SAML stands for Security Assertion Markup Language and is a protocol that enables single-sign on for enterprises. SAML was invented in the early 2000s and is based on XML technology. It is the de facto standard for enabling single-sign on for enterprises, although the more recent OIDC (OpenID Connect) protocol is gaining popularity. Session[#](https://supabase.com/docs/guides/resources/glossary#session) ------------------------------------------------------------------------ A session or authentication session is the concept that binds a verified user identity to a web browser. A session usually is long-lived, and can be terminated by the user logging out. An access and refresh token pair represent a session in the browser, and they are stored in local storage or as cookies. Single-sign on (SSO)[#](https://supabase.com/docs/guides/resources/glossary#single-sign-on-sso) ------------------------------------------------------------------------------------------------ Single-sign on allows enterprises to centrally manage accounts and access to applications. They use identity provider software or services to organize employee information in directories and connect those accounts with applications via OIDC or SAML protocols. Time-based one-time password (TOTP)[#](https://supabase.com/docs/guides/resources/glossary#time-based-one-time-password-totp) ------------------------------------------------------------------------------------------------------------------------------ A time-based one-time password is a one-time password generated at regular time intervals from a secret, usually from an application in a mobile device (e.g., Google Authenticator, 1Password). ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/resources/glossary%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/resources/glossary%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Cron | Supabase Docs Cron Cron ======== Schedule Recurring Jobs with Cron Syntax in Postgres -------------------------------------------------------- * * * Supabase Cron is a Postgres Module that simplifies scheduling recurring Jobs with cron syntax and monitoring Job runs inside Postgres. Cron Jobs can be created via SQL or the [Integrations -> Cron](https://supabase.com/dashboard/project/_/integrations) interface inside the Dashboard, and can run anywhere from every second to once a year depending on your use case. ![Manage cron jobs via the Dashboard](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fguides%2Fcron%2Fcron--light.jpg&w=3840&q=75) Every Job can run SQL snippets or database functions with zero network latency or make an HTTP request, such as invoking a Supabase Edge Function, with ease. For best performance, we recommend no more than 8 Jobs run concurrently. Each Job should run no more than 10 minutes. How does Cron work?[#](https://supabase.com/docs/guides/cron#how-does-cron-work) --------------------------------------------------------------------------------- Under the hood, Supabase Cron uses the [`pg_cron`](https://github.com/citusdata/pg_cron) Postgres database extension which is the scheduling and execution engine for your Jobs. The extension creates a `cron` schema in your database and all Jobs are stored on the `cron.job` table. Every Job's run and its status is recorded on the `cron.job_run_details` table. The Supabase Dashboard provides an interface for you to schedule Jobs and monitor Job runs. You can also do the same with SQL. Resources[#](https://supabase.com/docs/guides/cron#resources) -------------------------------------------------------------- * [`pg_cron` GitHub Repository](https://github.com/citusdata/pg_cron) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/cron%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/cron%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Install | Supabase Docs Cron Install =========== * * * Install the Supabase Cron Postgres Module to begin scheduling recurring Jobs. DashboardSQL 1. Go to the [Cron Postgres Module](https://supabase.com/dashboard/project/_/integrations/cron/overview) under Integrations in the Dashboard. 2. Enable the `pg_cron` extension. Uninstall[#](https://supabase.com/docs/guides/cron/install#uninstall) ---------------------------------------------------------------------- Uninstall Supabase Cron by disabling the `pg_cron` extension: 1drop extension if exists pg_cron; Disabling the `pg_cron` extension will permanently delete all Jobs. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/cron/install%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/cron/install%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Integrations | Supabase Docs Integrations Integrations ================ * * * Supabase integrates with many of your favorite third-party services. Vercel Marketplace[#](https://supabase.com/docs/guides/integrations#vercel-marketplace) ---------------------------------------------------------------------------------------- Create and manage your Supabase projects directly through Vercel. [Get started with Vercel](https://supabase.com/docs/guides/integrations/vercel-marketplace) . Supabase Marketplace[#](https://supabase.com/docs/guides/integrations#supabase-marketplace) -------------------------------------------------------------------------------------------- Browse tools for extending your Supabase project. [Browse the Supabase Marketplace](https://supabase.com/partners/integrations) . ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/integrations%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/integrations%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Expose Queues for local and self-hosted Supabase | Supabase Docs Queues Expose Queues for local and self-hosted Supabase ==================================================== Learn how to expose Queues when running Supabase with Supabase CLI or Docker Compose ---------------------------------------------------------------------------------------- * * * By default, local and self-hosted Supabase instances expose only core schemas like public and graphql\_public. To allow client-side consumers to use your queues, you have to add `pgmq_public` schema to the list of exposed schemas. Before continuing, complete the step [Expose queues to client-side consumers](https://supabase.com/docs/guides/queues/quickstart#expose-queues-to-client-side-consumers) from the Queues Quickstart guide. This creates the `pgmq_public` schema, which must exist before it can be exposed through the API. You only need to expose the `pgmq_public` schema manually when running Supabase locally with the Supabase CLI or self-hosting using Docker Compose. Expose Queues with Supabase CLI[#](https://supabase.com/docs/guides/queues/expose-self-hosted-queues#expose-queues-with-supabase-cli) -------------------------------------------------------------------------------------------------------------------------------------- When running Supabase locally with Supabase CLI, update your project's `config.toml` file. Locate the `[api]` section and add `pgmq_public` to the list of schemas. 1[api]2enabled = true3port = 543214schemas = ["public", "graphql_public", "pgmq_public"] Then restart your local Supabase stack. 1supabase stop && supabase start Expose queues with Docker compose[#](https://supabase.com/docs/guides/queues/expose-self-hosted-queues#expose-queues-with-docker-compose) ------------------------------------------------------------------------------------------------------------------------------------------ When running Supabase with Docker Compose, locate the `PGRST_DB_SCHEMAS` variable inside your `.env` file and add `pgmq_public` to it. This environment variable is passed to the `rest` service inside `docker-compose.yml`. 1PGRST_DB_SCHEMAS=public,graphql_public,pgmq_public Restart your containers for the changes to take effect. 1docker compose down2docker compose up -d Stop exposing queues[#](https://supabase.com/docs/guides/queues/expose-self-hosted-queues#stop-exposing-queues) ---------------------------------------------------------------------------------------------------------------- If you no longer want to expose the `pgmq_public` schema, you can remove it from your configuration. * For Supabase CLI, remove `pgmq_public` from the `[api]` schemas list in your `config.toml` file. * For Docker Compose, remove `pgmq_public` from the `PGRST_DB_SCHEMAS` variable in your `.env` file. After updating your configuration, restart your containers for the changes to take effect. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/queues/expose-self-hosted-queues%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/queues/expose-self-hosted-queues%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # API | Supabase Docs Queues API ======= * * * When you create a Queue in Supabase, you can choose to create helper database functions in the `pgmq_public` schema. This schema exposes operations to manage Queue Messages to consumers client-side, but does not expose functions for creating or dropping Queues. Database functions in `pgmq_public` can be exposed via Supabase Data API so consumers client-side can call them. Visit the [Quickstart](https://supabase.com/docs/guides/queues/quickstart) for an example. ### `pgmq_public.pop(queue_name)`[#](https://supabase.com/docs/guides/queues/api#pgmqpublicpopqueuename) Retrieves the next available message and deletes it from the specified Queue. * `queue_name` (`text`): Queue name * * * ### `pgmq_public.send(queue_name, message, sleep_seconds)`[#](https://supabase.com/docs/guides/queues/api#pgmqpublicsendqueuename-message-sleepseconds) Adds a Message to the specified Queue, optionally delaying its visibility to all consumers by a number of seconds. * `queue_name` (`text`): Queue name * `message` (`jsonb`): Message payload to send * `sleep_seconds` (`integer`, optional): Delay message visibility by specified seconds. Defaults to 0 * * * ### `pgmq_public.send_batch(queue_name, messages, sleep_seconds)`[#](https://supabase.com/docs/guides/queues/api#pgmqpublicsendbatchqueuename-messages-sleepseconds) Adds a batch of Messages to the specified Queue, optionally delaying their availability to all consumers by a number of seconds. * `queue_name` (`text`): Queue name * `messages` (`jsonb[]`): Array of message payloads to send * `sleep_seconds` (`integer`, optional): Delay messages visibility by specified seconds. Defaults to 0 * * * ### `pgmq_public.archive(queue_name, message_id)`[#](https://supabase.com/docs/guides/queues/api#pgmqpublicarchivequeuename-messageid) Archives a Message by moving it from the Queue table to the Queue's archive table. * `queue_name` (`text`): Queue name * `message_id` (`bigint`): ID of the Message to archive * * * ### `pgmq_public.delete(queue_name, message_id)`[#](https://supabase.com/docs/guides/queues/api#pgmqpublicdeletequeuename-messageid) Permanently deletes a Message from the specified Queue. * `queue_name` (`text`): Queue name * `message_id` (`bigint`): ID of the Message to delete * * * ### `pgmq_public.read(queue_name, sleep_seconds, n)`[#](https://supabase.com/docs/guides/queues/api#pgmqpublicreadqueuename-sleepseconds-n) Reads up to "n" Messages from the specified Queue with an optional "sleep\_seconds" (visibility timeout). * `queue_name` (`text`): Queue name * `sleep_seconds` (`integer`): Visibility timeout in seconds * `n` (`integer`): Maximum number of Messages to read ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/queues/api%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/queues/api%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Supabase Marketplace | Supabase Docs Integrations Supabase Marketplace ======================== * * * The Supabase Marketplace brings together all the tools you need to extend your Supabase project. This includes: * [Experts](https://supabase.com/partners/experts) - partners to help you build and support your Supabase project. * [Integrations](https://supabase.com/partners/integrations) - extend your projects with external Auth, Caching, Hosting, and Low-code tools. Build an integration[#](https://supabase.com/docs/guides/integrations/supabase-marketplace#build-an-integration) ----------------------------------------------------------------------------------------------------------------- Supabase provides several integration points: * The [Postgres connection](https://supabase.com/docs/guides/database/connecting-to-postgres) . Anything that works with Postgres also works with Supabase projects. * The [Project REST API](https://supabase.com/docs/guides/api#rest-api-overview) & client libraries. * The [Project GraphQL API](https://supabase.com/docs/guides/api#graphql-api-overview) . * The [Platform API](https://supabase.com/docs/reference/api) . List your integration[#](https://supabase.com/docs/guides/integrations/supabase-marketplace#list-your-integration) ------------------------------------------------------------------------------------------------------------------- [Apply to the Partners program](https://supabase.com/partners/integrations#become-a-partner) to list your integration in the Partners marketplace and in the Supabase docs. Integrations are assessed on the following criteria: * **Business viability** While we welcome everyone to built an integration, we only list companies that are deemed to be long-term viable. This includes an official business registration and bank account, meaningful revenue, or Venture Capital backing. We require this criteria to ensure the health of the marketplace. * **Compliance** Integrations should not infringe on the Supabase brand/trademark. In short, you cannot use "Supabase" in the name. As the listing appears on the Supabase domain, we don't want to mislead developers into thinking that an integration is an official product. * **Service Level Agreements** All listings are required to have their own Terms and Conditions, Privacy Policy, and Acceptable Use Policy, and the company must have resources to meet their SLAs. * **Maintainability** All integrations are required to be maintained and functional with Supabase, and the company may be assessed on your ability to remain functional over a long time horizon. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/integrations/supabase-marketplace%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/integrations/supabase-marketplace%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Supabase Security | Supabase Docs Security Supabase Security ===================== * * * Supabase is a hosted platform which makes it very simple to get started without needing to manage any infrastructure. The hosted platform comes with many security and compliance controls managed by Supabase. Compliance ========== Supabase is SOC 2 Type 2 compliant and regularly audited. All projects at Supabase are governed by the same set of compliance controls. The [SOC 2 Compliance Guide](https://supabase.com/docs/guides/security/soc-2-compliance) explains Supabase's SOC 2 responsibilities and controls in more detail. The [HIPAA Compliance Guide](https://supabase.com/docs/guides/security/hipaa-compliance) explains Supabase's HIPAA responsibilities. Additional [security and compliance controls](https://supabase.com/docs/guides/deployment/shared-responsibility-model#managing-healthcare-data) for projects that deal with electronic Protected Health Information (ePHI) and require HIPAA compliance are available through the HIPAA add-on. Platform configuration ====================== As a hosted platform, Supabase provides additional security controls to further enhance the security posture depending on organizations' own requirements or obligations. These can be found under the [dedicated security page](https://supabase.com/dashboard/org/_/security) under organization settings. And are described in greater detail [here](https://supabase.com/docs/guides/security/platform-security) . Product configuration ===================== Each product offered by Supabase comes with customizable security controls and these security controls help ensure that applications built on Supabase are secure, compliant, and resilient against various threats. The [security configuration guides](https://supabase.com/docs/guides/security/product-security) provide detailed information for configuring individual products. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/security%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/security%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Vercel Marketplace | Supabase Docs Integrations Vercel Marketplace ====================== * * * Overview[#](https://supabase.com/docs/guides/integrations/vercel-marketplace#overview) --------------------------------------------------------------------------------------- The Vercel Marketplace is a feature that allows you to manage third-party resources, such as Supabase, directly from the Vercel platform. This integration offers a seamless experience with unified billing, streamlined authentication, and easy access management for your team. When you create an organization and projects through Vercel Marketplace, they function just like those created directly within Supabase. However, the billing is handled through your Vercel account, and you can manage your resources directly from the Vercel dashboard or CLI. Additionally, environment variables are automatically synchronized, making them immediately available for your connected projects. For more information, see [Introducing the Vercel Marketplace](https://vercel.com/blog/introducing-the-vercel-marketplace) blog post. Vercel Marketplace is currently in Public Alpha. If you encounter any issues or have feature requests, [contact support](https://supabase.com/dashboard/support/new) . Quickstart[#](https://supabase.com/docs/guides/integrations/vercel-marketplace#quickstart) ------------------------------------------------------------------------------------------- ### Via template[#](https://supabase.com/docs/guides/integrations/vercel-marketplace#via-template) ##### Deploy a Next.js app with Supabase Vercel Storage now Uses the Next.js Supabase Starter Template [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fnext.js%2Ftree%2Fcanary%2Fexamples%2Fhello-world) ### Via Vercel Marketplace[#](https://supabase.com/docs/guides/integrations/vercel-marketplace#via-vercel-marketplace) Details coming soon.. ### Connecting to Supabase project[#](https://supabase.com/docs/guides/integrations/vercel-marketplace#connecting-to-supabase-project) Supabase Projects created via Vercel Marketplace are automatically synchronized with connected Vercel projects. This synchronization includes setting essential environment variables, such as: 1POSTGRES_URL2POSTGRES_PRISMA_URL3POSTGRES_URL_NON_POOLING4POSTGRES_USER5POSTGRES_HOST6POSTGRES_PASSWORD7POSTGRES_DATABASE8SUPABASE_SERVICE_ROLE_KEY9SUPABASE_PUBLISHABLE_KEY10SUPABASE_URL11SUPABASE_JWT_SECRET12NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY13NEXT_PUBLIC_SUPABASE_URL These variables ensure your applications can connect securely to the database and interact with Supabase APIs. Studio support[#](https://supabase.com/docs/guides/integrations/vercel-marketplace#studio-support) --------------------------------------------------------------------------------------------------- Accessing Supabase Studio is simple through the Vercel dashboard. You can open Supabase Studio from either the Integration installation page or the Vercel Storage page. Depending on your entry point, you'll either land on the Supabase dashboard homepage or be redirected to the corresponding Supabase Project. Supabase Studio provides tools such as: * **SQL Editor:** Run SQL queries against your database. * **Table Editor:** Create, edit, and delete tables and columns. * **Log Explorer:** Inspect real-time logs for your database. * **Postgres Upgrades:** Upgrade your Postgres instance to the latest version. * **Compute Upgrades:** Scale the compute resources allocated to your database. Permissions[#](https://supabase.com/docs/guides/integrations/vercel-marketplace#permissions) --------------------------------------------------------------------------------------------- There is a direct one-to-one relationship between a Supabase Organization and a Vercel team. Installing the integration or launching your first Supabase Project through Vercel triggers the creation of a corresponding Supabase Organization if one doesn’t already exist. When Vercel users interact with Supabase, they are automatically assigned Supabase accounts. New users get a Supabase account linked to their primary email, while existing users have their Vercel and Supabase accounts linked. * The user who initiates the creation of a Vercel Storage database is assigned the `owner` role in the new Supabase organization. * Subsequent users are assigned roles based on their Vercel role, such as `developer` for `member` and `owner` for `owner`. Role management is handled directly in the Vercel dashboard, and changes are synchronized with Supabase. Note: you can invite non-Vercel users to your Supabase Organization, but their permissions won't be synchronized with Vercel. Pricing[#](https://supabase.com/docs/guides/integrations/vercel-marketplace#pricing) ------------------------------------------------------------------------------------- Pricing for databases created through Vercel Marketplace is identical to those created directly within Supabase. Detailed pricing information is available on the [Supabase pricing page](https://supabase.com/pricing) . The [usage page](https://supabase.com/dashboard/org/_/usage) tracks the usage of your Vercel databases, with this information sent to Vercel for billing, which appears on your Vercel invoice. Note: Supabase Organization billing cycle is separate from Vercel's. Plan changes will reset the billing cycle to the day of the change, with the initial billing cycle starting the day you install the integration. Limitations[#](https://supabase.com/docs/guides/integrations/vercel-marketplace#limitations) --------------------------------------------------------------------------------------------- When using Vercel Marketplace, the following limitations apply: * Projects can only be created via the Vercel dashboard. * Organizations cannot be removed manually; they are removed only if you uninstall the Vercel Marketplace Integration. * Owners cannot be added manually within the Supabase dashboard. * Invoices and payments must be managed through the Vercel dashboard, not the Supabase dashboard. * [Custom Domains](https://supabase.com/docs/guides/platform/custom-domains) are not supported, and we always use the base `SUPABASE_URL` for the Vercel environment variables. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/integrations/vercel-marketplace%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/integrations/vercel-marketplace%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Security testing of your Supabase projects | Supabase Docs Security Security testing of your Supabase projects ============================================== * * * Supabase customer support policy for penetration testing Customers of Supabase are permitted to carry out security assessments or penetration tests of their hosted Supabase project components. This testing may be carried out without prior approval for the customer services listed under [permitted services](https://supabase.com/docs/guides/security/security-testing#permitted-services) . Supabase does not permit hosting security tooling that may be perceived as malicious or part of a campaign against Supabase customers or external services. This section is covered by the [Supabase Acceptable Use Policy](https://supabase.com/aup) (AUP). It is the customer’s responsibility to ensure that testing activities are aligned with this policy. Any testing performed outside of the policy will be seen as testing directly against Supabase and may be flagged as abuse behaviour. If Supabase receives an abuse report for activities related to your security testing, we will forward these to you. If you discover a security issue within any of the Supabase products, contact [Supabase Security](mailto:security@supabase.io) immediately. Furthermore, Supabase runs a [Vulnerability Disclosure Program](https://hackerone.com/ca63b563-9661-4ac3-8d23-7581582ef451/embedded_submissions/new) (VDP) with HackerOne, and external security researchers may report any bugs found within the scope of the aforementioned program. Customer penetration testing does not form part of this VDP. ### Permitted services[#](https://supabase.com/docs/guides/security/security-testing#permitted-services) * Authentication * Database * Edge Functions * Storage * Realtime * `https://.supabase.co/*` * `https://db..supabase.co/*` ### Prohibited testing and activities[#](https://supabase.com/docs/guides/security/security-testing#prohibited-testing-and-activities) * Any activity contrary to what is listed in the AUP. * Denial of Service (DoS) and Distributed Denial of Service (DDoS) testing. * Cross-tenant attacks, testing that directly targets other Supabase customers' accounts, organizations, and projects not under the customer’s control. * Request flooding. Terms and conditions[#](https://supabase.com/docs/guides/security/security-testing#terms-and-conditions) --------------------------------------------------------------------------------------------------------- The customer agrees to the following, Security testing: * Will be limited to the services within the customer’s project. * Is subject to the general [Terms of Service](https://supabase.com/terms) . * Is within the [Acceptable Usage Policy](https://supabase.com/aup) . * Will be stopped if contacted by Supabase due to a breach of the above or a negative impact on Supabase and Supabase customers. * Any vulnerabilities discovered directly in a Supabase product will be reported to Supabase Security within 24 hours of completion of testing. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/security/security-testing%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/security/security-testing%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Supabase Queues | Supabase Docs Queues Supabase Queues =================== Durable Message Queues with Guaranteed Delivery in Postgres --------------------------------------------------------------- * * * Supabase Queues is a Postgres-native durable Message Queue system with guaranteed delivery built on the [pgmq database extension](https://github.com/tembo-io/pgmq) . It offers developers a seamless way to persist and process Messages in the background while improving the resiliency and scalability of their applications and services. Queues couples the reliability of Postgres with the simplicity Supabase's platform and developer experience, enabling developers to manage Background Tasks with zero configuration. Features[#](https://supabase.com/docs/guides/queues#features) -------------------------------------------------------------- * **Postgres Native** Built on top of the `pgmq` database extension, create and manage Queues with any Postgres tooling. * **Guaranteed Message Delivery** Messages added to Queues are guaranteed to be delivered to your consumers. * **Exactly Once Message Delivery** A Message is delivered exactly once to a consumer within a customizable visibility window. * **Message Durability and Archival** Messages are stored in Postgres and you can choose to archive them for analytical or auditing purposes. * **Granular Authorization** Control client-side consumer access to Queues with API permissions and Row Level Security (RLS) policies. * **Queue Management and Monitoring** Create, manage, and monitor Queues and Messages in the Supabase Dashboard. Resources[#](https://supabase.com/docs/guides/queues#resources) ---------------------------------------------------------------- * [Quickstart](https://supabase.com/docs/guides/queues/quickstart) * [API Reference](https://supabase.com/docs/guides/queues/api) * [`pgmq` GitHub Repository](https://github.com/tembo-io/pgmq) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/queues%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/queues%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # SOC 2 Compliance and Supabase | Supabase Docs Security SOC 2 Compliance and Supabase ================================= * * * Supabase is Systems and Organization Controls 2 (SOC 2) Type 2 compliant and is assessed annually to ensure continued adherence to the SOC 2 security framework. SOC 2 assesses Supabase’s adherence to, and implementation of, controls governing the security, availability, processing integrity, confidentiality, and privacy on the Supabase platform. These controls define requirements for the management and storage of customer data on the platform. These controls applied to Supabase, as a service provider, serve two customer data environments. The first environment is the customer relationship with Supabase, this refers to the data Supabase has on a customer of the platform. All billing, contact, usage and contract information is managed and stored according to SOC 2 requirements. The second environment is the backend as a service (the product) that Supabase provides to customers. Supabase implements the controls from the SOC 2 framework to ensure the security of the platform, which hosts the backend as a service (the product), including the Postgres Database, Storage, Authentication, Realtime, Edge Functions and Data API features. Supabase can assert that the environment hosting customer data, stored within the product, adheres to SOC 2 requirements. And the management and storage of data within this environment (the product) is strictly controlled and kept secure. Supabase’s SOC 2 compliance does not transfer to environments outside of the Supabase product or Supabase’s control. This is known as the security or compliance boundary and forms part of the Shared Responsibility Model that Supabase and their customers enter into. SOC 2 does not cover, nor is it a substitute for, compliance with the Health Insurance Portability and Accountability Act (HIPAA). Organizations must have a signed Business Associate Agreement (BAA) with Supabase and have the HIPAA add-on enabled when dealing with Protected Health Information (PHI). Our [HIPAA documentation](https://supabase.com/docs/guides/security/hipaa-compliance) provides more information about the responsibilities and requirements for HIPAA on Supabase. Meeting compliance requirements =============================== SOC 2 compliance is a critical aspect of data security for Supabase and our customers. Being fully SOC 2 compliant is a shared responsibility and here’s a breakdown of the responsibilities for both parties: ### Supabase responsibilities[#](https://supabase.com/docs/guides/security/soc-2-compliance#supabase-responsibilities) 1. **Security Measures**: Supabase implements robust security controls to protect customer data. These includes measures to prevent data breaches and ensure the confidentiality and integrity of the information managed and stored by the platform. Supabase is obliged to be vigilant about security risks and must demonstrate that our security measures meet industry standards through regular audits. 2. **Compliance Audits**: Supabase undergoes SOC 2 audits yearly to verify that our data management practices comply with the Trust Services Criteria (TSC), which include security, availability, processing integrity, confidentiality, and privacy. These audits are conducted by an independent third party. 3. **Incident Response**: Supabase has an incident response plan in place to handle data breaches efficiently. This plan outlines how the organization detects issues, responds to incidents, and manages system vulnerabilities. 4. **Reporting**: Upon a successful audit, Supabase receive a SOC 2 report that details our compliance status. This report is available to customers as a SOC 2 Type 2 report, and allows customers and stakeholders to assure that Supabase has implemented adequate and the requisite safeguards to protect sensitive information. ### Customer responsibilities[#](https://supabase.com/docs/guides/security/soc-2-compliance#customer-responsibilities) 1. **Compliance Requirements**: Understand your own compliance requirements. While SOC 2 compliance is not a legal requirement, many enterprise customers require their providers to have a SOC 2 report. This is because it provides assurance that the provider has implemented robust controls to protect customer data. 2. **Due Diligence**: Customers must perform due diligence when selecting Supabase as a provider. This includes reviewing the SOC 2 Type 2 report to ensure that Supabase meets the expected security standards. Customers should also understand the division of responsibilities between themselves and Supabase to avoid duplication of effort. 3. **Monitoring and Review**: Customers should regularly monitor and review Supabase’s compliance status. 4. **Control Compliance**: If a customer needs to be SOC 2 compliant, they should themselves implement the requisite controls and undergo a SOC 2 audit. ### Shared responsibilities[#](https://supabase.com/docs/guides/security/soc-2-compliance#shared-responsibilities) 1. **Data Security**: Both customers and Supabase share the responsibility of ensuring data security. While the Supabase, as the provider, implements the security controls, the customer must ensure that their use of the Supabase platform does not compromise these controls. 2. **Control Compliance**: Supabase asserts through our SOC 2 that all requisite security controls are met. Customers wishing to also be SOC 2 compliant need to go through their own SOC 2 audit, verifying that security controls are met on the customer's side. In summary, SOC 2 compliance involves a shared responsibility between Supabase and our customers to ensure the security and integrity of data. Supabase, as a provider, must implement and maintain robust security measures, customers must perform due diligence and monitor Supabase's compliance status, while also implement their own compliance controls to protect their sensitive information. Frequently asked questions[#](https://supabase.com/docs/guides/security/soc-2-compliance#frequently-asked-questions) --------------------------------------------------------------------------------------------------------------------- **How often is Supabase SOC 2 audited?** Supabase has obtained SOC 2 Type 2 certification, which means Supabase's controls are fully audited annually. The auditor's reports on these examinations are issued as soon as they are ready after the audit. Supabase makes the SOC 2 Type 2 report available to [Enterprise and Team Plan](https://supabase.com/pricing) customers. The audit report covers a rolling 12-month window, known as the audit period, and runs from 1 March to 28 February of the next calendar year. **How to obtain Supabase's SOC 2 Type 2 report?** To access the SOC 2 Type 2 report, you must be a Enterprise or Team Plan Supabase customer. The report is downloadable from the [Legal Documents](https://supabase.com/dashboard/org/_/documents) section in the organization dashboard. **Why does it matter that Supabase is SOC 2 Compliant?** SOC 2 is used to assert that controls are in place to ensure the proper management and storage of data. SOC 2 provides a framework for measuring how secure a service provider is and re-evaluates the provider on an annual basis. This provides the confidence and assurance that data stored within the Supabase platform is correctly secured and managed. **If Supabase’s SOC 2 does not transfer to the customer, why does it matter that Supabase has SOC 2?** Even though Supabase’s SOC 2 compliance does not transfer outside of the product, it does provide the assurance that all data within the product is correctly managed and stored. Supabase can assert that only authorized persons have access to the data, and security controls are in place to prevent, detect and respond to data intrusions. This forms part of a customer’s own adherence to the SOC 2 framework and relieves part of the burden of data management and storage on the customer. In many organizations' security and risk departments require all vendors or sub-processors to be SOC 2 compliant. **What is the security or compliance boundary?** This defines the boundary or border between Supabase and customer responsibility for data security within the Shared Responsibility Model. Customer data stored within the Supabase product, on the Supabase side of the security boundary, is managed and secured by Supabase. Supabase ensures the safe handling and storage of data within this environment. This includes controls for preventing unauthorized access, monitoring data access, alerting, data backups and redundancy. Data on the customer side of the boundary, the data that enters and leaves the Supabase product, is the responsibility of the customer. Management and possible storage of such data outside of Supabase should be performed by the customer, and any security and compliance controls are the responsibility of the customer. **We have strong data residency requirements. Does Supabase SOC 2 cover data residency?** While SOC 2 itself does not mandate specific data residency requirements, organizations may still need to comply with other regulatory frameworks, such as GDPR, that do have such requirements. Ensuring projects are deployed in the correct region is a customer responsibility as each Supabase project is deployed into the region the customer specifies at creation time. All data will remain within the chosen region. [Read replicas](https://supabase.com/docs/guides/platform/read-replicas) can be created for multi-region availability, it remains the customer's responsibility to ensure regions chosen for read replicas are within the geographic area required by any additional regulatory frameworks. **Does SOC 2 cover health related data (HIPAA)?** SOC 2 is non-industry specific and provides a framework for the security and privacy of data. This is however not sufficient in most cases when dealing with Protected Healthcare Information (PHI), which requires additional privacy and legal controls. When dealing with PHI in the United States or for United States customers, HIPAA is mandatory. Resources[#](https://supabase.com/docs/guides/security/soc-2-compliance#resources) ----------------------------------------------------------------------------------- 1. [System and Organization Controls: SOC Suite of Services](https://www.aicpa-cima.com/resources/landing/system-and-organization-controls-soc-suite-of-services) 2. [Shared Responsibility Model](https://supabase.com/docs/guides/deployment/shared-responsibility-model) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/security/soc-2-compliance%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/security/soc-2-compliance%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Platform Audit Logs | Supabase Docs Security Platform Audit Logs ======================= * * * Any [Platform API](https://supabase.com/docs/reference/api/introduction) or [dashboard](https://supabase.com/dashboard) actions performed by organization members are logged automatically for auditing and security purposes. This includes actions such as creating a new project, inviting members, modifying an edge function or changing project settings. Besides Platform Audit Logs, Supabase Auth also provides [Auth Audit Logs](https://supabase.com/docs/guides/auth/audit-logs) to monitor authentication-related activities within your projects. Platform Audit Logs are only available on the [Team and Enterprise plans](https://supabase.com/pricing) . Accessing audit logs[#](https://supabase.com/docs/guides/security/platform-audit-logs#accessing-audit-logs) ------------------------------------------------------------------------------------------------------------ Platform Audit Logs can be found under your [organization's audit logs](https://supabase.com/dashboard/org/_/audit) . ![Platform audit logs](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fguides%2Fsecurity%2Fplatform-audit-logs--light.png&w=3840&q=75) For each audit log, you can see additional details by clicking on the log entry: * Timestamp of action * Actor who performed the action * IP address * Email * Token Type * Action performed * Name * Metadata such as route and response status * Action Target (Project, organization, Edge Function, ...) Limitations[#](https://supabase.com/docs/guides/security/platform-audit-logs#limitations) ------------------------------------------------------------------------------------------ * There is currently no way to export the logs via dashboard * There is currently no way to set up a log drain of platform audit logs * Retention periods depend on your plan ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/security/platform-audit-logs%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/security/platform-audit-logs%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # HIPAA Compliance and Supabase | Supabase Docs Security HIPAA Compliance and Supabase ================================= * * * The [Health Insurance Portability and Accountability Act (HIPAA)](https://www.hhs.gov/hipaa/for-professionals/privacy/laws-regulations/index.html) is a comprehensive law that protects individuals' health information while ensuring the continuity of health insurance coverage. It sets standards for privacy and security that must be followed by all entities that handle Protected Health Information (PHI), also known as electronic PHI (ePHI). HIPAA is specific to the United States, however many countries have similar or laws already in place or under legislation. Under HIPAA, both covered entities and business associates have distinct responsibilities to ensure the protection of PHI. Supabase acts as a business associate for customers (the covered entity) who wish to provide healthcare related services. As a business associate, Supabase has a number of obligations and has undergone auditing of the security and privacy controls that are in place to meet these. Supabase has signed a Business Associate Agreement (BAA) with all of our vendors who would have access to ePHI, such as AWS, and ensure that we follow their terms listed in the agreements. Similarly when a customer signs a BAA with us, they have some responsibilities they agree to when using Supabase to store PHI. The hosted Supabase platform has the necessary controls to meet HIPAA requirements. These controls are not supported out of the box in self-hosted Supabase. HIPAA controls extend further than the Supabase product, encompassing legal agreements (BAAs) with providers, operating controls and policies. Achieving HIPAA compliance with self-hosted Supabase is out of scope for this documentation and you should consult your auditor for further guidance. ### Customer responsibilities[#](https://supabase.com/docs/guides/security/hipaa-compliance#customer-responsibilities) Covered entities (the customer) are organizations that directly handle PHI, such as health plans, healthcare clearinghouses, and healthcare providers that conduct certain electronic transactions. 1. **Compliance with HIPAA Rules**: Covered entities must comply with the [HIPAA Privacy Rule](https://www.hhs.gov/hipaa/for-professionals/privacy/index.html) , [Security Rule](https://www.hhs.gov/hipaa/for-professionals/security/index.html) , and [Breach Notification Rule](https://www.hhs.gov/hipaa/for-professionals/breach-notification/index.html) to protect the privacy and security of ePHI. 2. **Business Associate Agreements (BAAs)**: Customers must sign a BAA with Supabase. When the covered entity engages a business associate to help carry out its healthcare activities, it must have a written BAA. This agreement outlines the business associate's responsibilities and requires them to comply with HIPAA Rules. 3. **Internal Compliance Programs**: Customers must [configure their HIPAA projects](https://supabase.com/docs/guides/platform/hipaa-projects) and follow the guidance given by the security advisor. Covered entities are responsible for implementing internal processes and compliance programs to ensure they meet HIPAA requirements. ### Supabase responsibilities[#](https://supabase.com/docs/guides/security/hipaa-compliance#supabase-responsibilities) Supabase as the business associate, and the vendors used by Supabase, are the entities that perform functions or activities on behalf of the customer. 1. **Direct Liability**: Supabase is directly liable for compliance with certain provisions of the HIPAA Rules. This means Supabase has to implement safeguards to protect ePHI and report breaches to the customer. 2. **Compliance with BAAs**: Supabase must comply with the terms of the BAA, which includes implementing appropriate administrative, physical, and technical safeguards to protect ePHI. 3. **Vendor Management**: Supabase must also ensure that our vendors, who may have access to ePHI, comply with HIPAA Rules. This is done through a BAA with each vendor. Staying compliant and secure[#](https://supabase.com/docs/guides/security/hipaa-compliance#staying-compliant-and-secure) ------------------------------------------------------------------------------------------------------------------------- Compliance is a continuous process and should not be treated as a point-in-time audit of controls. Supabase applies all the necessary privacy and security controls to ensure HIPAA compliance at audit time, but also has additional checks and monitoring in place to ensure those controls are not disabled or altered in between audit periods. Customers commit to doing the same in their HIPAA environments. Supabase provides a growing set of checks that warn customers of changes to their projects that disable or weaken HIPAA required controls. Customers will receive warnings and guidance via the Security Advisor, however the responsibility of applying the recommended controls falls directly to the customer. Our [shared responsibility model](https://supabase.com/docs/guides/deployment/shared-responsibility-model#managing-healthcare-data) document discusses both HIPAA and general data management best practices, how this responsibility is shared between customers and Supabase, and how to stay compliant. Frequently asked questions[#](https://supabase.com/docs/guides/security/hipaa-compliance#frequently-asked-questions) --------------------------------------------------------------------------------------------------------------------- **What is the difference between SOC 2 and HIPAA?** Both are frameworks for protecting sensitive data, however they serve two different purposes. They share many security and privacy controls and meeting the controls of one normally means being close to complying with the other. The main differentiator comes down to purpose and scope. * SOC 2 is not industry-specific and can be applied to any service organization that handles customer data. * HIPAA is a federal regulation in the United States. HIPAA sets standards for the privacy and security of PHI/ePHI, ensuring that patient data is handled confidentially and securely. **Are Supabase HIPAA environments also SOC 2 compliant?** Yes. Supabase applies the same SOC 2 controls to all environments, with additional controls being applied to HIPAA environments. **How often is Supabase audited?** Supabase undergoes annual audits. The HIPAA controls are audited during the same audit period as the SOC 2 controls. Resources[#](https://supabase.com/docs/guides/security/hipaa-compliance#resources) ----------------------------------------------------------------------------------- 1. [Health Insurance Portability and Accountability Act (HIPAA)](https://www.hhs.gov/hipaa/for-professionals/privacy/laws-regulations/index.html) 2. [HIPAA Privacy Rule](https://www.hhs.gov/hipaa/for-professionals/privacy/index.html) 3. [Security Rule](https://www.hhs.gov/hipaa/for-professionals/security/index.html) 4. [Breach Notification Rule](https://www.hhs.gov/hipaa/for-professionals/breach-notification/index.html) 5. [Configuring HIPAA projects](https://supabase.com/docs/guides/platform/hipaa-projects) on Supabase 6. [Shared Responsibility Model](https://supabase.com/docs/guides/deployment/shared-responsibility-model) 7. [HIPAA shared responsibility](https://supabase.com/docs/guides/deployment/shared-responsibility-model#managing-healthcare-data) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/security/hipaa-compliance%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/security/hipaa-compliance%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Restoring a downloaded backup locally | Supabase Docs Local Development Restoring a downloaded backup locally ========================================= Restore a backup of a remote database on a local instance to inspect and extract data ----------------------------------------------------------------------------------------- * * * If your paused project has exceeded its [restoring time limit](https://supabase.com/docs/guides/platform/upgrading#time-limits) , you can download a backup from the dashboard and restore it to your local development environment. This might be useful for inspecting and extracting data from your paused project. If you want to restore your backup to a hosted Supabase project, follow the [Migrating within Supabase guide](https://supabase.com/docs/guides/platform/migrating-within-supabase) instead. Downloading your backup[#](https://supabase.com/docs/guides/local-development/restoring-downloaded-backup#downloading-your-backup) ----------------------------------------------------------------------------------------------------------------------------------- First, download your project's backup file from dashboard and identify its backup image version (following the `PG:` prefix): ![Project Paused: 90 Days Remaining](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fguides%2Fplatform%2Fpaused-dl-image-version.png&w=1920&q=75) Restoring your backup[#](https://supabase.com/docs/guides/local-development/restoring-downloaded-backup#restoring-your-backup) ------------------------------------------------------------------------------------------------------------------------------- Given Postgres version `15.6.1.115`, start Postgres locally with `db_cluster.backup` being the path to your backup file. 1supabase init2echo '15.6.1.115' > supabase/.temp/postgres-version3supabase db start --from-backup db_cluster.backup Note that the earliest Supabase Postgres version that supports a local restore is `15.1.0.55`. If your hosted project was running on earlier versions, you will likely run into errors during restore. Before submitting any support ticket, make sure you have attached the error logs from `supabase_db_*` docker container. Once your local database starts up successfully, you can connect using psql to verify that all your data is restored. 1psql 'postgresql://postgres:postgres@localhost:54322/postgres' If you want to use other services like Auth, Storage, and Studio dashboard together with your restored database, restart the local development stack. 1supabase stop2supabase start A Postgres database started with Supabase CLI is not production ready and should not be used outside of local development. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/local-development/restoring-downloaded-backup%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/local-development/restoring-downloaded-backup%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Reports | Supabase Docs Telemetry Reports =========== * * * Supabase Reports provide comprehensive observability for your project through dedicated monitoring dashboards for servers: * Database * Auth * Storage * Realtime * API systems Each report offers self-debugging tools to gain actionable insights for optimizing performance and troubleshooting issues. Reports are only available for projects hosted on the Supabase Cloud platform and are not available for self-hosted instances. Using reports[#](https://supabase.com/docs/guides/telemetry/reports#using-reports) ----------------------------------------------------------------------------------- You can filter reports by time range to focus on a specific period. Higher-tier plans provide access to longer time ranges. | Time Range | Free | Pro | Team | Enterprise | | --- | --- | --- | --- | --- | | Last 10 minutes | ✅ | ✅ | ✅ | ✅ | | Last 30 minutes | ✅ | ✅ | ✅ | ✅ | | Last 60 minutes | ✅ | ✅ | ✅ | ✅ | | Last 3 hours | ✅ | ✅ | ✅ | ✅ | | Last 24 hours | ✅ | ✅ | ✅ | ✅ | | Last 7 days | ❌ | ✅ | ✅ | ✅ | | Last 14 days | ❌ | ❌ | ✅ | ✅ | | Last 28 days | ❌ | ❌ | ✅ | ✅ | * * * API gateway[#](https://supabase.com/docs/guides/telemetry/reports#api-gateway) ------------------------------------------------------------------------------- The API Gateway report analyzes performance and traffic patterns managed by your project's API layer. | Chart | Description | Key Insights | | --- | --- | --- | | Total Requests | Overall API request volume | Traffic patterns and growth trends, including top routes | | Response Errors | Error rates with 4XX and 5XX status codes | API reliability and user experience issues, including top routes | | Response Speed | Average API response times | Performance bottlenecks and optimization targets, including top routes | | Network Traffic | Request and response egress usage | Data transfer patterns and cost implications | Auth[#](https://supabase.com/docs/guides/telemetry/reports#auth) ----------------------------------------------------------------- The Auth reports focus on user authentication patterns and behaviors within your Supabase project. | Chart | Description | Key Insights | | --- | --- | --- | | Active Users | Count of unique users performing auth actions | User engagement and retention patterns | | Sign In Attempts by Type | Breakdown of authentication methods used | Password vs OAuth vs magic link preferences | | Sign Ups | Total new user registrations | Growth trends and onboarding funnel performance | | API Gateway Auth Errors | Error rates grouped by status code | Authentication friction and security issues | | Password Reset Requests | Volume of password recovery attempts | User experience pain points | ### Auth API Gateway[#](https://supabase.com/docs/guides/telemetry/reports#auth-api-gateway) The Auth API Gateway reports focus on API requests related to authentication and user management. | Chart | Description | Key Insights | | --- | --- | --- | | Total Requests | Count of unique users performing auth actions | User engagement and retention patterns, including top routes | | Response Errors | Error rates with 4XX and 5XX status codes | API reliability and user experience issues, including top routes | | Response speed | Average response time for auth requests | Performance bottlenecks and optimization opportunities, including top routes | | Network Traffic | Ingress and egress usage | Data transfer costs and CDN effectiveness | Database[#](https://supabase.com/docs/guides/telemetry/reports#database) ------------------------------------------------------------------------- The Database report provides a comprehensive view into your Postgres instance's health and performance characteristics. These charts help you identify performance bottlenecks and resource constraints at a glance. The following charts are available for Free and Pro plans: | Chart | Available Plans | Description | Key Insights | | --- | --- | --- | --- | | Memory usage | Free, Pro | RAM usage percentage by the database | Memory pressure and resource utilization | | CPU usage | Free, Pro | Average CPU usage percentage | CPU-intensive query identification | | Disk IOPS | Free, Pro | Read/write operations per second with limits | IO bottleneck detection and workload analysis | | Database connections | Free, Pro | Number of pooler connections to the database | Connection pool monitoring | | Dedicated Pooler connections | All | Client connections to PgBouncer | Dedicated pooler connection monitoring | | Shared Pooler connections | All | Client connections to the shared pooler | Shared pooler usage patterns | | Shared Pooler connections | All | Client connections to the shared pooler | Shared pooler usage patterns | | Disk usage | Free, Pro | Disk space consumption breakdown | Storage capacity planning | | Database size | Free, Pro | Total database size and growth trends | Space consumption monitoring, including list of largest tables | ### Advanced Telemetry[#](https://supabase.com/docs/guides/telemetry/reports#advanced-telemetry) The following charts provide a more advanced and detailed view of your database performance and are available only for Team, Enterprise, and Platform plans. ### Memory usage[#](https://supabase.com/docs/guides/telemetry/reports#memory-usage) ![Memory usage chart](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fdatabase%2Freports%2Fmemory-usage-chart-light.png&w=3840&q=75) | Component | Description | | --- | --- | | **Used** | RAM actively used by Postgres and the operating system | | **Cache + buffers** | Memory used for page cache and OS buffers | | **Free** | Available unallocated memory | How it helps debug issues: | Issue | Description | | --- | --- | | Memory pressure detection | Identify when free memory is consistently low | | Cache effectiveness monitoring | Monitor cache performance for query optimization | | Memory leak detection | Detect inefficient memory usage patterns | Actions you can take: | Action | Description | | --- | --- | | [Upgrade compute size](https://supabase.com/docs/guides/platform/compute-and-disk#compute-size) | Increase available memory resources | | [Optimize queries](https://supabase.com/docs/content/guides/database/query-optimization) | Reduce memory consumption of expensive queries | | [Tune Postgres configuration](https://pgtune.leopard.in.ua/) | Improve memory management settings | | Implement application caching | Add query result caching to reduce memory load | ### CPU usage[#](https://supabase.com/docs/guides/telemetry/reports#cpu-usage) ![CPU usage chart](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fdatabase%2Freports%2Fcpu-usage-chart-light.png&w=3840&q=75) | Category | Description | | --- | --- | | **System** | CPU time for kernel operations | | **User** | CPU time for database queries and user processes | | **IOWait** | CPU time waiting for disk/network IO | | **IRQs** | CPU time handling interrupts | | **Other** | CPU time for miscellaneous tasks | How it helps debug issues: | Issue | Description | | --- | --- | | CPU-intensive query identification | Identify expensive queries when User CPU is high | | IO bottleneck detection | Detect disk/network issues when IOWait is elevated | | System overhead monitoring | Monitor resource contention and kernel overhead | Actions you can take: | Action | Description | | --- | --- | | [Optimize CPU-intensive queries](https://supabase.com/docs/content/guides/database/query-optimization) | Target queries causing high User CPU usage | | Address IO bottlenecks | Resolve disk/network issues when IOWait is high | | [Upgrade compute size](https://supabase.com/docs/guides/platform/compute-and-disk) | Increase available CPU capacity | | [Implement proper indexing](https://supabase.com/docs/guides/database/postgres/indexes) | Use query optimization techniques | ### Disk input/output operations per second (IOPS)[#](https://supabase.com/docs/guides/telemetry/reports#disk-inputoutput-operations-per-second-iops) ![Disk IOPS chart](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fdatabase%2Freports%2Fdisk-iops-chart-light.png&w=3840&q=75) This chart displays read and write IOPS with a reference line showing your compute size's maximum IOPS capacity. How it helps debug issues: | Issue | Description | | --- | --- | | Disk IO bottleneck identification | Identify when disk IO becomes a performance constraint | | Workload pattern analysis | Distinguish between read-heavy vs write-heavy operations | | Performance correlation | Spot disk activity spikes that correlate with performance issues | Actions you can take: | Action | Description | | --- | --- | | [Optimize indexing](https://supabase.com/docs/guides/database/postgres/indexes) | Reduce high read IOPS through better query indexing | | Consider [read replicas](https://supabase.com/docs/guides/platform/read-replicas) | Distribute read-heavy workloads across multiple instances | | Batch write operations | Reduce write IOPS by grouping database writes | | [Upgrade compute size](https://supabase.com/docs/guides/platform/compute-and-disk) | Increase IOPS limits with larger compute instances | ### Disk throughput[#](https://supabase.com/docs/guides/telemetry/reports#disk-throughput) Available on Team and Enterprise plans. This chart displays read and write throughput (bytes per second) with a reference line showing your compute size's maximum disk throughput. How it helps debug issues: | Issue | Description | | --- | --- | | Throughput bottleneck identification | Spot when disk bandwidth is saturated | | Workload pattern analysis | Differentiate read-heavy vs write-heavy bandwidth usage | | Performance correlation | Correlate spikes with query performance changes | Actions you can take: | Action | Description | | --- | --- | | [Optimize disk-intensive queries](https://supabase.com/docs/content/guides/database/query-optimization) | Reduce queries that perform excessive reads/writes | | Tune caching and batching | Minimize repeated disk access and improve throughput headroom | | [Upgrade compute size](https://supabase.com/docs/guides/platform/compute-and-disk) | Increase throughput limits for sustained workloads | | Review database design | Optimize schema and query patterns for efficiency | | [Add strategic indexes](http://localhost:3001/docs/guides/database/postgres/indexes) | Reduce sequential scans with appropriate indexing | ### Disk size[#](https://supabase.com/docs/guides/telemetry/reports#disk-size) ![Disk Size chart](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fdatabase%2Freports%2Fdisk-size-chart-light.png&w=3840&q=75) | Component | Description | | --- | --- | | **Database** | Space used by your actual database data (tables, indexes) | | **WAL** | Space used by Write-Ahead Logging | | **System** | Reserved space for system operations | How it helps debug issues: | Issue | Description | | --- | --- | | Space consumption monitoring | Track disk usage trends over time | | Growth pattern identification | Identify rapid growth requiring attention | | Capacity planning | Plan upgrades before hitting storage limits | Actions you can take: | Action | Description | | --- | --- | | Run [VACUUM](https://www.postgresql.org/docs/current/sql-vacuum.html)
operations | Reclaim dead tuple space and optimize storage | | Analyze large tables | Use CLI commands like `table-sizes` to identify optimization targets | | Implement data archival | Archive historical data to reduce active storage needs | | [Upgrade disk size](https://supabase.com/docs/guides/platform/database-size) | Increase storage capacity when approaching limits | ### Query Performance[#](https://supabase.com/docs/guides/telemetry/reports#query-performance) Links to the [Query Performance Advisory page](https://supabase.com/docs/guides/platform/performance#examine-query-performance) in the dashboard, which provides a detailed analysis of slow database queries ### Database connections[#](https://supabase.com/docs/guides/telemetry/reports#database-connections) ![Database connections chart](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fdatabase%2Freports%2Fdb-connections-chart-light.png&w=3840&q=75) | Connection Type | Description | | --- | --- | | **Postgres** | Direct connections from your application | | **PostgREST** | Connections from the PostgREST API layer | | **Reserved** | Administrative connections for Supabase services | | **Auth** | Connections from Supabase Auth service | | **Storage** | Connections from Supabase Storage service | | **Other roles** | Miscellaneous database connections | How it helps debug issues: | Issue | Description | | --- | --- | | Connection pool exhaustion | Identify when approaching maximum connection limits | | Connection leak detection | Spot applications not properly closing connections | | Service distribution monitoring | Monitor connection usage across different Supabase services | Actions you can take: | Action | Description | | --- | --- | | [Upgrade compute size](https://supabase.com/docs/guides/platform/compute-and-disk#compute-size) | Increase maximum connection limits | | Implement [connection pooling](https://supabase.com/docs/guides/database/connecting-to-postgres#shared-pooler) | Optimize connection management for high direct connection usage | | Review application code | Ensure proper connection handling and cleanup | ### Dedicated Pooler (PgBouncer) Client Connections[#](https://supabase.com/docs/guides/telemetry/reports#dedicated-pooler-pgbouncer-client-connections) Available on Team and Enterprise plans. This chart displays the number of PgBouncer connections over time. How it helps debug issues: | Issue | Description | | --- | --- | | Connection pool exhaustion | Identify when approaching maximum connection limits | | Connection leak detection | Spot applications not properly closing connections | | Service distribution monitoring | Monitor connection usage across different Supabase services | Actions you can take: | Action | Description | | --- | --- | | [Upgrade compute size](https://supabase.com/docs/guides/platform/compute-and-disk#compute-size) | Increase maximum connection limits | | Implement [connection pooling](https://supabase.com/docs/guides/database/connecting-to-postgres#shared-pooler) | Optimize connection management for high direct connection usage | | Review application code | Ensure proper connection handling and cleanup | ### Shared Pooler (Supavisor) Client Connections[#](https://supabase.com/docs/guides/telemetry/reports#shared-pooler-supavisor-client-connections) Available on Team and Enterprise plans. This chart displays the number of Supavisor connections over time. How it helps debug issues: | Issue | Description | | --- | --- | | Connection pool exhaustion | Identify when approaching maximum connection limits | | Connection leak detection | Spot applications not properly closing connections | | Service distribution monitoring | Monitor connection usage across different Supabase services | Actions you can take: | Action | Description | | --- | --- | | [Upgrade compute size](https://supabase.com/docs/guides/platform/compute-and-disk#compute-size) | Increase maximum connection limits | | Implement [connection pooling](https://supabase.com/docs/guides/database/connecting-to-postgres#shared-pooler) | Optimize connection management for high direct connection usage | | Review application code | Ensure proper connection handling and cleanup | ### Disk Usage[#](https://supabase.com/docs/guides/telemetry/reports#disk-usage) ### Database size[#](https://supabase.com/docs/guides/telemetry/reports#database-size) ![Disk Size chart](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fdatabase%2Freports%2Fdisk-size-chart-light.png&w=3840&q=75) | Component | Description | | --- | --- | | **Database** | Space used by your actual database data (tables, indexes) | | **WAL** | Space used by Write-Ahead Logging | | **System** | Reserved space for system operations | How it helps debug issues: | Issue | Description | | --- | --- | | Space consumption monitoring | Track disk usage trends over time | | Growth pattern identification | Identify rapid growth requiring attention | | Capacity planning | Plan upgrades before hitting storage limits | Actions you can take: | Action | Description | | --- | --- | | Run [VACUUM](https://www.postgresql.org/docs/current/sql-vacuum.html)
operations | Reclaim dead tuple space and optimize storage | | Analyze large tables | Use CLI commands like `table-sizes` to identify optimization targets | | Implement data archival | Archive historical data to reduce active storage needs | | [Upgrade disk size](https://supabase.com/docs/guides/platform/database-size) | Increase storage capacity when approaching limits | Edge Functions[#](https://supabase.com/docs/guides/telemetry/reports#edge-functions) ------------------------------------------------------------------------------------- The Edge Functions report provides insights into serverless function performance, execution patterns, and regional distribution across Supabase's global edge network. | Chart | Description | Key Insights | | --- | --- | --- | | Total Edge Function Invocations | Function response codes and error rates | Function reliability and error patterns | | Edge Function Execution Status Codes | Function response codes and error rates | Function reliability and error patterns | | Edge Function Execution Time | Average function duration and performance | Performance optimization opportunities | | Edge Function Invocations by Region | Geographic distribution of function calls | Global usage patterns and latency optimization | PostgREST[#](https://supabase.com/docs/guides/telemetry/reports#postgrest) --------------------------------------------------------------------------- The PostgREST report provides insights into RESTful API performance, request patterns, and response characteristics. | Chart | Description | Key Insights | | --- | --- | --- | | Total Requests | HTTP requests to PostgREST endpoints | API usage alongside WebSocket activity | | Response Errors | Error rates with 4XX and 5XX status codes | API reliability and user experience issues, including top routes | | Response Speed | Average response time for PostgREST requests | Performance bottlenecks and optimization opportunities, including top routes | | Network Traffic | Ingress and egress usage | Data transfer costs and CDN effectiveness | Realtime[#](https://supabase.com/docs/guides/telemetry/reports#realtime) ------------------------------------------------------------------------- The Realtime report tracks WebSocket connections, channel activity, and real-time event patterns in your Supabase project. | Chart | Description | Key Insights | | --- | --- | --- | | Connected Clients | Active WebSocket connections over time | Concurrent user activity and connection stability | | Broadcast Events | Broadcast events over time | Real-time feature usage patterns | | Presence Events | Presence events over time | Real-time feature usage patterns | | Postgres Changes Events | Postgres Changes events over time | Real-time feature usage patterns | | Rate of Channel Joins | Frequency of new channel subscriptions | User engagement with real-time features | | Message Payload Size | Median size of message payloads sent | Payload size that is being transmitted | | Broadcast From Database Replication Lag | Median latency between database commit and broadcast when using broadcast from database | Latency to Broadcast from the database | | Read/Write Private Channel Subscription RLS Execution Time | Median time to authorize private channels | `realtime.messages` RLS policies performance | | Total Requests | HTTP requests to Realtime endpoints | API usage alongside WebSocket activity | | Response Speed | Performance of Realtime API endpoints | Infrastructure optimization opportunities | ### Realtime API Gateway[#](https://supabase.com/docs/guides/telemetry/reports#realtime-api-gateway) The Realtime API Gateway reports focus on API requests related to Realtime functionality. | Chart | Description | Key Insights | | --- | --- | --- | | Total Requests | HTTP requests to Realtime endpoints | API usage alongside WebSocket activity, including top routes | | Response Errors | HTTP requests to Realtime endpoints | API usage alongside WebSocket activity, including top routes | | Response Speed | Performance of Realtime API endpoints | Infrastructure optimization opportunities, including top routes | Storage[#](https://supabase.com/docs/guides/telemetry/reports#storage) ----------------------------------------------------------------------- The Storage report provides visibility into how your Supabase Storage is being utilized, including request patterns, performance characteristics, and caching effectiveness. | Chart | Description | Key Insights | | --- | --- | --- | | Total Requests | Overall request volume to Storage | Traffic patterns and usage trends, including top routes | | Response Speed | Average response time for storage requests | Performance bottlenecks and optimization opportunities, including top routes | | Network Traffic | Ingress and egress usage | Data transfer costs and CDN effectiveness | | Request Caching | Cache hit rates and miss patterns | CDN performance and cost optimization, including top routes | ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/telemetry/reports%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/telemetry/reports%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Managing config and secrets | Supabase Docs Local Development Managing config and secrets =============================== * * * The Supabase CLI uses a `config.toml` file to manage local configuration. This file is located in the `supabase` directory of your project. Config reference[#](https://supabase.com/docs/guides/local-development/managing-config#config-reference) --------------------------------------------------------------------------------------------------------- The `config.toml` file is automatically created when you run `supabase init`. There are a wide variety of options available, which can be found in the [CLI Config Reference](https://supabase.com/docs/guides/cli/config) . For example, to enable the "Apple" OAuth provider for local development, you can append the following information to `config.toml`: 1[auth.external.apple]2enabled = false3client_id = ""4secret = ""5redirect_uri = "" # Overrides the default auth redirectUrl. Using secrets inside config.toml[#](https://supabase.com/docs/guides/local-development/managing-config#using-secrets-inside-configtoml) ---------------------------------------------------------------------------------------------------------------------------------------- You can reference environment variables within the `config.toml` file using the `env()` function. This will detect any values stored in an `.env` file at the root of your project directory. This is particularly useful for storing sensitive information like API keys, and any other values that you don't want to check into version control. 1.2├── .env3├── .env.example4└── supabase5 └── config.toml Do NOT commit your `.env` into git. Be sure to configure your `.gitignore` to exclude this file. For example, if your `.env` contained the following values: 1GITHUB_CLIENT_ID=""2GITHUB_SECRET="" Then you would reference them inside of our `config.toml` like this: 1[auth.external.github]2enabled = true3client_id = "env(GITHUB_CLIENT_ID)"4secret = "env(GITHUB_SECRET)"5redirect_uri = "" # Overrides the default auth redirectUrl. ### Going further[#](https://supabase.com/docs/guides/local-development/managing-config#going-further) For more advanced secrets management workflows, including: * **Using dotenvx for encrypted secrets**: Learn how to securely manage environment variables across different branches and environments * **Branch-specific secrets**: Understand how to manage secrets for different deployment environments * **Encrypted configuration values**: Use encrypted values directly in your `config.toml` See the [Managing secrets for branches](https://supabase.com/docs/guides/deployment/branching#managing-secrets-for-branches) section in our branching documentation, or check out the [dotenvx example repository](https://github.com/supabase/supabase/blob/master/examples/slack-clone/nextjs-slack-clone-dotenvx/README.md) for a complete implementation. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/local-development/managing-config%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/local-development/managing-config%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Metrics API | Supabase Docs Telemetry Metrics API =============== * * * Every Supabase project exposes a [Prometheus](https://prometheus.io/) \-compatible **Metrics API** endpoint that surfaces ~200 Postgres performance and health series. You can scrape it into any observability stack to power custom dashboards, alerting rules, or long-term retention that goes beyond what Supabase Studio provides out of the box. The Metrics API is currently in beta. Metric names and labels might evolve as we expand the dataset, and the feature is not available in self-hosted Supabase instances. What you can do with the Metrics API[#](https://supabase.com/docs/guides/telemetry/metrics#what-you-can-do-with-the-metrics-api) --------------------------------------------------------------------------------------------------------------------------------- * Stream database CPU, IO, WAL, connection, and query stats into Prometheus-compatible systems. * Combine Supabase metrics with application signals in Grafana, Datadog, or any other observability vendor. * Reuse our [supabase-grafana dashboard JSON](https://github.com/supabase/supabase-grafana) to bootstrap over 200 ready-made charts. * Build your own alerting policies (right-sizing, saturation detection, index regression, and more). What you can do with the Metrics API Choose your monitoring stack[#](https://supabase.com/docs/guides/telemetry/metrics#choose-your-monitoring-stack) ----------------------------------------------------------------------------------------------------------------- Pick the workflow that best matches your tooling. Cards link to Supabase-authored guides or vendor integration docs, and some include a “Community” pill when there’s an accompanying vendor reference. [Grafana Cloud (SaaS)\ \ Use Grafana Cloud’s managed Prometheus (works on Free + Pro tiers) and import the Supabase dashboard without running any infrastructure.\ \ Supabase guideCommunity](https://supabase.com/docs/guides/telemetry/metrics/grafana-cloud) [Grafana + self-hosted Prometheus\ \ Run Prometheus yourself following the official installation guidance and pair it with Grafana plus our dashboard JSON and alert pack.\ \ Supabase guide](https://supabase.com/docs/guides/telemetry/metrics/grafana-self-hosted) [Datadog\ \ Scrape the Metrics API with the Datadog Agent or Prometheus remote write and monitor Supabase alongside your app telemetry.\ \ Community](https://docs.datadoghq.com/integrations/supabase/) [Vendor-agnostic / BYO Prometheus\ \ Connect AWS AMP, Grafana Mimir, VictoriaMetrics, or any Prometheus-compatible SaaS with the same scrape job pattern.\ \ Supabase guide](https://supabase.com/docs/guides/telemetry/metrics/vendor-agnostic) ![Supabase Grafana dashboard showcasing database metrics](https://supabase.com/docs/img/guides/platform/supabase-grafana-prometheus.png) Additional resources[#](https://supabase.com/docs/guides/telemetry/metrics#additional-resources) ------------------------------------------------------------------------------------------------- * [Supabase Grafana repository](https://github.com/supabase/supabase-grafana) for dashboard JSON and alert examples. * [Grafana Cloud’s Supabase integration doc](https://grafana.com/docs/grafana-cloud/monitor-infrastructure/integrations/integration-reference/integration-supabase/) (community-maintained, built on this Metrics API). * [Datadog’s Supabase integration doc](https://docs.datadoghq.com/integrations/supabase/) (community-maintained, built on this Metrics API). * [Log Drains](https://supabase.com/docs/guides/telemetry/log-drains) for exporting event-based telemetry alongside metrics. * [Query Performance report](https://supabase.com/dashboard/project/_/observability/query-performance) for built-in visualizations based on the same underlying metrics. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/telemetry/metrics%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/telemetry/metrics%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Local Development & CLI | Supabase Docs Local Development Local Development & CLI =========================== Learn how to develop locally and use the Supabase CLI --------------------------------------------------------- * * * Develop locally while running the Supabase stack on your machine. As a prerequisite, you must install a container runtime compatible with Docker APIs. * [Docker Desktop](https://docs.docker.com/desktop/) (macOS, Windows, Linux) * [Rancher Desktop](https://rancherdesktop.io/) (macOS, Windows, Linux) * [Podman](https://podman.io/) (macOS, Windows, Linux) * [OrbStack](https://orbstack.dev/) (macOS) Quickstart[#](https://supabase.com/docs/guides/local-development#quickstart) ----------------------------------------------------------------------------- 1. Install the Supabase CLI: npmyarnpnpmbrew 1npm install supabase --save-dev 2. In your repo, initialize the Supabase project: npmyarnpnpmbrew 1npx supabase init 3. Start the Supabase stack: npmyarnpnpmbrew 1npx supabase start 4. View your local Supabase instance at [http://localhost:54323](http://localhost:54323/) . If your local development machine is connected to an untrusted public network, you should create a separate docker network and bind to 127.0.0.1 before starting the local development stack. This restricts network access to only your localhost machine. 1docker network create -o 'com.docker.network.bridge.host_binding_ipv4=127.0.0.1' local-network2npx supabase start --network-id local-network You should never expose your local development stack publicly. Local development[#](https://supabase.com/docs/guides/local-development#local-development) ------------------------------------------------------------------------------------------- Local development with Supabase allows you to work on your projects in a self-contained environment on your local machine. Working locally has several advantages: 1. Faster development: You can make changes and see results instantly without waiting for remote deployments. 2. Offline work: You can continue development even without an internet connection. 3. Cost-effective: Local development is free and doesn't consume your project's quota. 4. Enhanced privacy: Sensitive data remains on your local machine during development. 5. Easy testing: You can experiment with different configurations and features without affecting your production environment. To get started with local development, you'll need to install the [Supabase CLI](https://supabase.com/docs/guides/local-development#cli) and Docker. The Supabase CLI allows you to start and manage your local Supabase stack, while Docker is used to run the necessary services. Once set up, you can initialize a new Supabase project, start the local stack, and begin developing your application using local Supabase services. This includes access to a local Postgres database, Auth, Storage, and other Supabase features. CLI[#](https://supabase.com/docs/guides/local-development#cli) --------------------------------------------------------------- The Supabase CLI is a powerful tool that enables developers to manage their Supabase projects directly from the terminal. It provides a suite of commands for various tasks, including: * Setting up and managing local development environments * Generating TypeScript types for your database schema * Handling database migrations * Managing environment variables and secrets * Deploying your project to the Supabase platform With the CLI, you can streamline your development workflow, automate repetitive tasks, and maintain consistency across different environments. It's an essential tool for both local development and CI/CD pipelines. See the [CLI Getting Started guide](https://supabase.com/docs/guides/local-development/cli/getting-started) for more information. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/local-development%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/local-development%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Telemetry | Supabase Docs Telemetry Telemetry ============= * * * Telemetry helps you understand what’s happening inside your app by collecting logs, metrics, and traces. * **Logs** capture individual events, such as errors or warnings, providing details about what happened at a specific moment. * **Metrics** track numerical data over time, like request latency or database query performance, helping you spot trends. * **Traces** show the flow of a request through different services, helping you debug slow or failing operations. Supabase is working towards full support for the [OpenTelemetry](https://opentelemetry.io/) standard, making it easier to integrate with observability tools. This section provides guidance on telemetry in Supabase, including how to work with Supabase Logs. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/telemetry%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/telemetry%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Advanced Log Filtering | Supabase Docs Telemetry Advanced Log Filtering ========================== * * * Querying the logs ================= Understanding field references[#](https://supabase.com/docs/guides/telemetry/advanced-log-filtering#understanding-field-references) ------------------------------------------------------------------------------------------------------------------------------------ The log tables are queried with a subset of BigQuery SQL syntax. They all have three columns: `event_message`, `timestamp`, and `metadata`. | column | description | | --- | --- | | timestamp | time event was recorded | | event\_message | the log's message | | metadata | information about the event | The `metadata` column is an array of JSON objects that stores important details about each recorded event. For example, in the Postgres table, the `metadata.parsed.error_severity` field indicates the error level of an event. To work with its values, you need to `unnest` them using a `cross join`. This approach is commonly used with JSON and array columns, so it might look a bit unfamiliar if you're not used to working with these data types. 1select2 event_message,3 parsed.error_severity,4 parsed.user_name5from6 postgres_logs7 -- extract first layer8 cross join unnest(postgres_logs.metadata) as metadata9 -- extract second layer10 cross join unnest(metadata.parsed) as parsed; Expanding results[#](https://supabase.com/docs/guides/telemetry/advanced-log-filtering#expanding-results) ---------------------------------------------------------------------------------------------------------- Logs returned by queries may be difficult to read in table format. A row can be double-clicked to expand the results into more readable JSON: ![Expanding log results](https://supabase.com/docs/img/guides/platform/expanded-log-results.png) Filtering with [regular expressions](https://en.wikipedia.org/wiki/Regular_expression) [#](https://supabase.com/docs/guides/telemetry/advanced-log-filtering#filtering-with-regular-expressions) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- The Logs use BigQuery Style regular expressions with the [regexp\_contains function](https://cloud.google.com/bigquery/docs/reference/standard-sql/string_functions#regexp_contains) . In its most basic form, it will check if a string is present in a specified column. 1select2 cast(timestamp as datetime) as timestamp,3 event_message,4 metadata5from postgres_logs6where regexp_contains(event_message, 'is present'); There are multiple operators that you should consider using: ### Find messages that start with a phrase[#](https://supabase.com/docs/guides/telemetry/advanced-log-filtering#find-messages-that-start-with-a-phrase) `^` only looks for values at the start of a string 1-- find only messages that start with connection2regexp_contains(event_message, '^connection') ### Find messages that end with a phrase:[#](https://supabase.com/docs/guides/telemetry/advanced-log-filtering#find-messages-that-end-with-a-phrase) `$` only looks for values at the end of the string 1-- find only messages that ends with port=123452regexp_contains(event_message, '$port=12345') ### Ignore case sensitivity:[#](https://supabase.com/docs/guides/telemetry/advanced-log-filtering#ignore-case-sensitivity) `(?i)` ignores capitalization for all proceeding characters 1-- find all event_messages with the word "connection"2regexp_contains(event_message, '(?i)COnnecTion') ### Wildcards:[#](https://supabase.com/docs/guides/telemetry/advanced-log-filtering#wildcards) `.` can represent any string of characters 1-- find event_messages like "helloworld"2regexp_contains(event_message, 'hello.world') ### Alphanumeric ranges:[#](https://supabase.com/docs/guides/telemetry/advanced-log-filtering#alphanumeric-ranges) `[1-9a-zA-Z]` finds any strings with only numbers and letters 1-- find event_messages that contain a number between 1 and 5 (inclusive)2regexp_contains(event_message, '[1-5]') ### Repeated values:[#](https://supabase.com/docs/guides/telemetry/advanced-log-filtering#repeated-values) `x*` zero or more x `x+` one or more x `x?` zero or one x `x{4,}` four or more x `x{3}` exactly 3 x 1-- find event_messages that contains any sequence of 3 digits2regexp_contains(event_message, '[0-9]{3}') ### Escaping reserved characters:[#](https://supabase.com/docs/guides/telemetry/advanced-log-filtering#escaping-reserved-characters) `\.` interpreted as period `.` instead of as a wildcard 1-- escapes .2regexp_contains(event_message, 'hello world\.') ### `or` statements:[#](https://supabase.com/docs/guides/telemetry/advanced-log-filtering#or-statements) `x|y` any string with `x` or `y` present 1-- find event_messages that have the word 'started' followed by either the word "host" or "authenticated"2regexp_contains(event_message, 'started host|authenticated') ### `and`/`or`/`not` statements in SQL:[#](https://supabase.com/docs/guides/telemetry/advanced-log-filtering#and--or--not-statements-in-sql) `and`, `or`, and `not` are all native terms in SQL and can be used in conjunction with regular expressions to filter results 1select2 cast(timestamp as datetime) as timestamp,3 event_message,4 metadata5from postgres_logs6where7 (regexp_contains(event_message, 'connection') and regexp_contains(event_message, 'host'))8 or not regexp_contains(event_message, 'received'); ### Filtering and unnesting example[#](https://supabase.com/docs/guides/telemetry/advanced-log-filtering#filtering-and-unnesting-example) **Filter for Postgres** 1select2 cast(postgres_logs.timestamp as datetime) as timestamp,3 parsed.error_severity,4 parsed.user_name,5 event_message6from7 postgres_logs8 cross join unnest(metadata) as metadata9 cross join unnest(metadata.parsed) as parsed10where regexp_contains(parsed.error_severity, 'ERROR|FATAL|PANIC')11order by timestamp desc12limit 100; Limitations[#](https://supabase.com/docs/guides/telemetry/advanced-log-filtering#limitations) ---------------------------------------------------------------------------------------------- ### Log tables cannot be joined together[#](https://supabase.com/docs/guides/telemetry/advanced-log-filtering#log-tables-cannot-be-joined-together) Each product table operates independently without the ability to join with other log tables. This may change in the future. ### The `with` keyword and subqueries are not supported[#](https://supabase.com/docs/guides/telemetry/advanced-log-filtering#the-with-keyword-and-subqueries-are-not-supported) The parser does not yet support `with` and subquery statements. ### The `ilike` and `similar to` keywords are not supported[#](https://supabase.com/docs/guides/telemetry/advanced-log-filtering#the-ilike-and-similar-to-keywords-are-not-supported) Although `like` and other comparison operators can be used, `ilike` and `similar to` are incompatible with BigQuery's variant of SQL. `regexp_contains` can be used as an alternative. ### The wildcard operator `*` to select columns is not supported[#](https://supabase.com/docs/guides/telemetry/advanced-log-filtering#the-wildcard-operator--to-select-columns-is-not-supported) The log parser is not able to parse the `*` operator for column selection. Instead, you can access all fields from the `metadata` column: 1select2 cast(postgres_logs.timestamp as datetime) as timestamp,3 event_message,4 metadata5from6 7order by timestamp desc8limit 100; ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/telemetry/advanced-log-filtering%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/telemetry/advanced-log-filtering%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Settings | Supabase Docs Realtime Settings ============ Realtime Settings that allow you to configure your Realtime usage. ---------------------------------------------------------------------- * * * Settings[#](https://supabase.com/docs/guides/realtime/settings#settings) ------------------------------------------------------------------------- All changes made in this screen will disconnect all your connected clients to ensure Realtime starts with the appropriate settings and all changes are stored in Supabase middleware. ![Usage page navigation bar](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fguides%2Fplatform%2Frealtime%2Frealtime-settings--light.png&w=3840&q=75) You can set the following settings using the Realtime Settings screen in your Dashboard: * Enable Realtime service: Determines if the Realtime service is enabled or disabled for your project. * Channel Restrictions: You can toggle this settings to set Realtime to allow public channels or set it to use only private channels with [Realtime Authorization](https://supabase.com/docs/guides/realtime/authorization) . * Database connection pool size: Determines the number of connections used for Realtime Authorization RLS checking * Max concurrent clients: Determines the maximum number of clients that can be connected * Max events per second: Determines the maximum number of events per second that can be sent * Max presence events per second: Determines the maximum number of presence events per second that can be sent * Max payload size in KB: Determines the maximum number of payload size in KB that can be sent ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/realtime/settings%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/realtime/settings%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Log Drains | Supabase Docs Telemetry Log Drains ============== * * * Log drains send all logs of the Supabase stack to one or more desired destinations. It is only available for customers on Pro, Team and Enterprise Plans. Log drains are available in the dashboard under [Project Settings > Log Drains](https://supabase.com/dashboard/project/_/settings/log-drains) . You can read about the initial announcement [here](https://supabase.com/blog/log-drains) and vote for your preferred drains in [this discussion](https://github.com/orgs/supabase/discussions/28324?sort=top) . Supported destinations ====================== The following table lists the supported destinations and the required setup configuration: | Destination | Transport Method | Configuration | | --- | --- | --- | | Generic HTTP endpoint | HTTP | URL
HTTP Version
Gzip
Headers | | Datadog | HTTP | API Key
Region | | Loki | HTTP | URL
Headers | | Sentry | HTTP | DSN | | Amazon S3 | AWS SDK | S3 Bucket
Region
Access Key ID
Secret Access Key
Batch Timeout | | OTLP | HTTP | Endpoint
Protocol
Gzip
Headers | HTTP requests are batched with a max of 250 logs or 1 second intervals, whichever happens first. Logs are compressed via Gzip if the destination supports it. Generic HTTP endpoint[#](https://supabase.com/docs/guides/telemetry/log-drains#generic-http-endpoint) ------------------------------------------------------------------------------------------------------ Logs are sent as a POST request with a JSON body. Both HTTP/1 and HTTP/2 protocols are supported. Custom headers can optionally be configured for all requests. Note that requests are **unsigned**. Unsigned requests to HTTP endpoints are temporary and all requests will signed in the near future. Edge Function Walkthrough (Uncompressed) Edge Function Gzip Example Datadog logs[#](https://supabase.com/docs/guides/telemetry/log-drains#datadog-logs) ------------------------------------------------------------------------------------ Logs sent to Datadog have the name of the log source set on the `service` field of the event and the source set to `Supabase`. Logs are gzipped before they are sent to Datadog. The payload message is a JSON string of the raw log event, prefixed with the event timestamp. To setup Datadog log drain, generate a Datadog API key [here](https://app.datadoghq.com/organization-settings/api-keys) and the location of your Datadog site. Walkthrough Example destination configuration If you are interested in other log drains, upvote them [here](https://github.com/orgs/supabase/discussions/28324) Loki[#](https://supabase.com/docs/guides/telemetry/log-drains#loki) -------------------------------------------------------------------- Logs sent to the Loki HTTP API are specifically formatted according to the HTTP API requirements. See the official Loki HTTP API documentation for [more details](https://grafana.com/docs/loki/latest/reference/loki-http-api/#ingest-logs) . Events are batched with a maximum of 250 events per request. The log source and product name will be used as stream labels. The `event_message` and `timestamp` fields will be dropped from the events to avoid duplicate data. Loki must be configured to accept **structured metadata**, and it is advised to increase the default maximum number of structured metadata fields to at least 500 to accommodate large log event payloads of different products. Sentry[#](https://supabase.com/docs/guides/telemetry/log-drains#sentry) ------------------------------------------------------------------------ Logs are sent to Sentry as part of [Sentry's Logging Product](https://docs.sentry.io/product/explore/logs/) . Ingesting Supabase logs as Sentry errors is currently not supported. To setup the Sentry log drain, you need to do the following: 1. Grab your DSN from your [Sentry project settings](https://docs.sentry.io/concepts/key-terms/dsn-explainer/) . It should be of the format `{PROTOCOL}://{PUBLIC_KEY}:{SECRET_KEY}@{HOST}{PATH}/{PROJECT_ID}`. 2. Create log drain in [Supabase dashboard](https://supabase.com/dashboard/project/_/settings/log-drains) 3. Watch for events in the [Sentry Logs page](https://sentry.io/explore/logs/) All fields from the log event are attached as attributes to the Sentry log, which can be used for filtering and grouping in the Sentry UI. There are no limits to cardinality or the number of attributes that can be attached to a log. If you are self-hosting Sentry, Sentry Logs are only supported in self-hosted version [25.9.0](https://github.com/getsentry/self-hosted/releases/tag/25.9.0) and later. Axiom[#](https://supabase.com/docs/guides/telemetry/log-drains#axiom) ---------------------------------------------------------------------- Logs sent to a specified Axiom's dataset as JSON of a raw log event, with timestamp modified to be parsed by ingestion endpoint. To set up the Axiom log drain, you have to: 1. Create a dataset for ingestion in Axiom Console -> Datasets 2. Generate an Axiom API Token with permission to ingest into the created dataset (see [Axiom docs](https://axiom.co/docs/reference/tokens#create-basic-api-token) ) 3. Create log drain in [Supabase dashboard](https://supabase.com/dashboard/project/_/settings/log-drains) , providing: * Name of the dataset * API token 4. Watch for events in the Stream panel of Axiom Console Amazon S3[#](https://supabase.com/docs/guides/telemetry/log-drains#amazon-s3) ------------------------------------------------------------------------------ Logs are written to an existing S3 bucket that you own. Required configuration when creating an S3 Log Drain: * S3 Bucket: the name of an existing S3 bucket. * Region: the AWS region where the bucket is located. * Access Key ID: used for authentication. * Secret Access Key: used for authentication. * Batch Timeout (ms): maximum time to wait before flushing a batch. Recommended 2000-5000ms. Ensure the AWS account tied to the Access Key ID has permissions to write to the specified S3 bucket. OpenTelemetry protocol (OTLP)[#](https://supabase.com/docs/guides/telemetry/log-drains#opentelemetry-protocol-otlp) -------------------------------------------------------------------------------------------------------------------- Logs are sent to any OTLP-compatible endpoint using the OpenTelemetry Protocol over HTTP with Protocol Buffers encoding. OTLP is an open-standard protocol for telemetry data, making it compatible with many observability platforms including: * OpenTelemetry Collector * Grafana Cloud * New Relic * Honeycomb * Datadog (OTLP ingestion) * Elastic * And many more Required configuration when creating an OTLP Log Drain: * Endpoint: The full URL of your OTLP HTTP endpoint (typically ending in `/v1/logs`) * Protocol: Currently only `http/protobuf` is supported * Gzip: Enable compression to reduce bandwidth (recommended: enabled) * Headers: Optional authentication headers (e.g., `Authorization`, `X-API-Key`) Logs are sent as OTLP log record messages using Protocol Buffers encoding, following the [OpenTelemetry Logs specification](https://opentelemetry.io/docs/specs/otel/logs/) . Ensure your OTLP endpoint is configured to accept logs at the `/v1/logs` path with `application/x-protobuf` content type. OpenTelemetry Collector Example Authentication Examples Pricing[#](https://supabase.com/docs/guides/telemetry/log-drains#pricing) -------------------------------------------------------------------------- For a detailed breakdown of how charges are calculated, refer to [Manage Log Drain usage](https://supabase.com/docs/guides/platform/manage-your-usage/log-drains) . ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/telemetry/log-drains%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/telemetry/log-drains%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Realtime Pricing | Supabase Docs Realtime Realtime Pricing ==================== * * * You are charged for the number of Realtime messages and the number of Realtime peak connections. Messages[#](https://supabase.com/docs/guides/realtime/pricing#messages) ------------------------------------------------------------------------ $2.50 per 1 million messages. You are only charged for usage exceeding your subscription plan's quota. | Plan | Quota | Over-Usage | | --- | --- | --- | | Free | 2 million | \- | | Pro | 5 million | $2.50 per 1 million messages | | Team | 5 million | $2.50 per 1 million messages | | Enterprise | Custom | Custom | For a detailed explanation of how charges are calculated, refer to [Manage Realtime Messages usage](https://supabase.com/docs/guides/platform/manage-your-usage/realtime-messages) . Peak connections[#](https://supabase.com/docs/guides/realtime/pricing#peak-connections) ---------------------------------------------------------------------------------------- $10 per 1,000 peak connections. You are only charged for usage exceeding your subscription plan's quota. | Plan | Quota | Over-Usage | | --- | --- | --- | | Free | 200 | \- | | Pro | 500 | $10 per 1,000 peak connections | | Team | 500 | $10 per 1,000 peak connections | | Enterprise | Custom | Custom | For a detailed explanation of how charges are calculated, refer to [Manage Realtime Peak Connections usage](https://supabase.com/docs/guides/platform/manage-your-usage/realtime-peak-connections) . ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/realtime/pricing%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/realtime/pricing%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Branching | Supabase Docs Home Branching ============= Use Supabase Branches to test and preview changes ----------------------------------------------------- * * * Use branching to safely experiment with changes to your Supabase project. Supabase branches create separate environments that spin off from your main project. You can use these branching environments to create and test changes like new configurations, database schemas, or features without affecting your production setup. When you're ready to ship your changes, merge your branch to update your production instance with the new changes. How branching works[#](https://supabase.com/docs/guides/deployment/branching#how-branching-works) -------------------------------------------------------------------------------------------------- * **Separate Environments**: Each branch is a separate environment with its own Supabase instance and API credentials. * **Preview Branches**: Preview branches are ephemeral and best suited for focused testing. They are automatically paused after inactivity or deleted when a PR is merged or closed. * **Persistent Branches**: Persistent branches are long-lived and recommended for environments like staging, QA, or development. Unlike preview branches, they aren't automatically paused or deleted due to inactivity or when a PR is merged or closed. * **Managing Branches**: You can create, review, and merge branches either automatically via our [GitHub integration](https://supabase.com/docs/guides/deployment/branching/github-integration) or directly [through the dashboard](https://supabase.com/docs/guides/deployment/branching/dashboard) (currently in beta). All branches show up in the branches page in the dashboard, regardless of how they were created. * **Data-less**: New branches do not start with any data from your main project. This is meant to better protect your sensitive production data. To start your branches with data, you can use a [seed file](https://supabase.com/docs/guides/deployment/branching/github-integration#seeding) if using the GitHub integration. Deploying to production[#](https://supabase.com/docs/guides/deployment/branching#deploying-to-production) ---------------------------------------------------------------------------------------------------------- When you merge any branch into your main project, Supabase automatically runs a deployment workflow to deploy your changes to production. The deployment workflow is expressed as a Directed Acyclic Graph where each node represents one of the following deployment steps. 1. **Clone** - Checks out your repository at the specified git branch (optional for [Branching via Dashboard](https://supabase.com/docs/guides/deployment/branching/dashboard) ) 2. **Pull** - Retrieves database migrations from your main project (also initialises the migration history table when Branching via Dashboard) 3. **Health** - Waits up to 2 minutes for all Supabase services on your branch to be running and healthy, including Auth, API, Database, Storage, and Realtime 4. **Configure** - Updates service configurations based on your config.toml file (only available for [Branching via GitHub](https://supabase.com/docs/guides/deployment/branching/github-integration) ) 5. **Migrate** - Applies pending database migrations and vault secrets to your branch 6. **Seed** - Runs seed files to populate your branch with initial data (must be [enabled in config.toml](https://supabase.com/docs/guides/deployment/branching/configuration#branch-configuration-with-remotes) for persistent branches) 7. **Deploy** - Deploys any changed Edge Functions and updates function secrets If a parent deployment step fails, all dependent child steps will be skipped. For instance, if your database migrations failed at step 5, our runner will not seed your branch because step 6 is skipped. If you are using GitHub integration, the same deployment workflow will be run on every commit pushed to your git branch. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/deployment/branching%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/deployment/branching%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Listening to Postgres Changes with Flutter | Supabase Docs Realtime Listening to Postgres Changes with Flutter ============================================== * * * The Postgres Changes extension listens for database changes and sends them to clients which enables you to receive database changes in real-time. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/realtime/realtime-listening-flutter%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/realtime/realtime-listening-flutter%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Using Realtime Presence with Flutter | Supabase Docs Realtime Using Realtime Presence with Flutter ======================================== * * * Use Supabase Presence to display the currently online users on your Flutter application. Displaying the list of currently online users is a common feature for real-time collaborative applications. Supabase Presence makes it easy to track users joining and leaving the session so that you can make a collaborative app. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/realtime/realtime-user-presence%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/realtime/realtime-user-presence%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Customizing email templates | Supabase Docs Local Development Customizing email templates =============================== Customize local email templates via the config file. -------------------------------------------------------- * * * You can customize the email templates for local development by [editing the `config.toml` file](https://supabase.com/docs/guides/local-development/cli/config#auth-config) . Configuring templates[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#configuring-templates) ------------------------------------------------------------------------------------------------------------------------------- You should provide a relative URL to the `content_path` parameter, pointing to an HTML file which contains the template. For example: ### Authentication email templates[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#authentication-email-templates) supabase/config.tomlsupabase/templates/invite.html 1[auth.email.template.invite]2subject = "You are invited to Acme Inc"3content_path = "./supabase/templates/invite.html" ### Security notification email templates[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#security-notification-email-templates) supabase/config.tomltemplates/password\_changed\_notification.html 1[auth.email.notification.password_changed]2enabled = true3subject = "Your password has been changed"4content_path = "./templates/password_changed_notification.html" Available authentication email templates[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#available-authentication-email-templates) --------------------------------------------------------------------------------------------------------------------------------------------------------------------- There are several authentication-related email templates which can be configured. Each template serves a specific authentication flow: ### `auth.email.template.invite`[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#authemailtemplateinvite) **Default subject**: "You have been invited" **When sent**: When a user is invited to join your application via email invitation **Purpose**: Invite users who don't yet have an account to sign up **Content**: Contains a link for the invited user to accept the invitation and create their account ### `auth.email.template.confirmation`[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#authemailtemplateconfirmation) **Default subject**: "Confirm Your Signup" **When sent**: When a user signs up and needs to verify their email address **Purpose**: Ask users to confirm their email address after signing up **Content**: Contains a confirmation link to verify the user's email address ### `auth.email.template.recovery`[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#authemailtemplaterecovery) **Default subject**: "Reset Your Password" **When sent**: When a user requests a password reset **Purpose**: Allow users to reset their password if they forget it **Content**: Contains a link to reset the user's password ### `auth.email.template.magic_link`[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#authemailtemplatemagiclink) **Default subject**: "Your Magic Link" **When sent**: When a user requests a magic link for passwordless authentication **Purpose**: Allow users to sign in via a one-time link sent to their email **Content**: Contains a secure link that automatically logs the user in when clicked ### `auth.email.template.email_change`[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#authemailtemplateemailchange) **Default subject**: "Confirm Email Change" **When sent**: When a user requests to change their email address **Purpose**: Ask users to verify their new email address after changing it **Content**: Contains a confirmation link to verify the new email address ### `auth.email.template.reauthentication`[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#authemailtemplatereauthentication) **Default subject**: "Confirm Reauthentication" **When sent**: When a user needs to re-authenticate for sensitive operations **Purpose**: Ask users to re-authenticate before performing a sensitive action **Content**: Contains a 6-digit OTP code for verification Available security notification email templates[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#available-security-notification-email-templates) ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- There are several security notification email templates which can be configured. These emails are only sent to users if the respective security notifications have been enabled at the project-level: ### `auth.email.notification.password_changed`[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#authemailnotificationpasswordchanged) **Default subject**: "Your password has been changed" **When sent**: When a user's password is changed **Purpose**: Notify users when their password has changed **Content**: Confirms that the password for the account has been changed ### `auth.email.notification.email_changed`[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#authemailnotificationemailchanged) **Default subject**: "Your email address has been changed" **When sent**: When a user's email address is changed **Purpose**: Notify users when their email address has changed **Content**: Confirms the change from the old email to the new email address ### `auth.email.notification.phone_changed`[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#authemailnotificationphonechanged) **Default subject**: "Your phone number has been changed" **When sent**: When a user's phone number is changed **Purpose**: Notify users when their phone number has changed **Content**: Confirms the change from the old phone number to the new phone number ### `auth.email.notification.mfa_factor_enrolled`[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#authemailnotificationmfafactorenrolled) **Default subject**: "A new MFA factor has been enrolled" **When sent**: When a new MFA factor is added to the user's account **Purpose**: Notify users when a new multi-factor authentication method has been added to their account **Content**: Confirms that a new MFA factor type has been enrolled ### `auth.email.notification.mfa_factor_unenrolled`[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#authemailnotificationmfafactorunenrolled) **Default subject**: "An MFA factor has been unenrolled" **When sent**: When an MFA factor is removed from the user's account **Purpose**: Notify users when a multi-factor authentication method has been removed from their account **Content**: Confirms that an MFA factor type has been unenrolled ### `auth.email.notification.identity_linked`[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#authemailnotificationidentitylinked) **Default subject**: "A new identity has been linked" **When sent**: When a new identity is linked to the account **Purpose**: Notify users when a new identity has been linked to their account **Content**: Confirms that a new identity has been linked ### `auth.email.notification.identity_unlinked`[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#authemailnotificationidentityunlinked) **Default subject**: "An identity has been unlinked" **When sent**: When an identity has been unlinked from the account **Purpose**: Notify users when an identity has been unlinked from their account **Content**: Confirms that an identity has been unlinked Template variables[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#template-variables) ------------------------------------------------------------------------------------------------------------------------- The templating system provides the following variables for use: ### `ConfirmationURL`[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#confirmationurl) Contains the confirmation URL. For example, a signup confirmation URL would look like: 1https://project-ref.supabase.co/auth/v1/verify?token={{ .TokenHash }}&type=email&redirect_to=https://example.com/path **Usage** 1

Click here to confirm: {{ .ConfirmationURL }}

### `Token`[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#token) Contains a 6-digit One-Time-Password (OTP) that can be used instead of the `ConfirmationURL`. **Usage** 1

Here is your one time password: {{ .Token }}

### `TokenHash`[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#tokenhash) Contains a hashed version of the `Token`. This is useful for constructing your own email link in the email template. **Usage** 1

Follow this link to confirm your user:

2

3 Confirm your email6

### `SiteURL`[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#siteurl) Contains your application's Site URL. This can be configured in your project's [authentication settings](https://supabase.com/dashboard/project/_/auth/url-configuration) . **Usage** 1

Visit here to log in.

### `Email`[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#email) Contains the user's email address. **Usage** 1

A recovery request was sent to {{ .Email }}.

### `NewEmail`[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#newemail) Contains the new user's email address. This is only available in the `email_change` email template. **Usage** 1

You are requesting to update your email address to {{ .NewEmail }}.

### `OldEmail`[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#oldemail) Contains the user's old email address. This is only available in the `email_changed_notification` email template. **Usage** 1

The email address for your account has been changed from {{ .OldEmail }} to {{ .Email }}.

### `Phone`[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#phone) Contains the user's new phone number. This is only available in the `phone_changed_notification` email template. **Usage** 1

The phone number for your account has been changed from {{ .OldPhone }} to {{ .Phone }}.

### `OldPhone`[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#oldphone) Contains the user's old phone number. This is only available in the `phone_changed_notification` email template. **Usage** 1

The phone number for your account has been changed from {{ .OldPhone }} to {{ .Phone }}.

### `Provider`[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#provider) Contains the provider of the newly linked/unlinked identity. This is only available in the `identity_linked_notification` and `identity_unlinked_notification` email templates. **Usage** 1

A new identity ({{ .Provider }}) has been linked to your account.

### `FactorType`[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#factortype) Contains the type of the newly enrolled/unenrolled MFA factor. This is only available in the `mfa_factor_enrolled_notification` and `mfa_factor_unenrolled_notification` email templates. **Usage** 1

A new factor ({{ .FactorType }}) has been enrolled for your account.

Deploying email templates[#](https://supabase.com/docs/guides/local-development/customizing-email-templates#deploying-email-templates) --------------------------------------------------------------------------------------------------------------------------------------- These settings are for local development. To apply the changes locally, stop and restart the Supabase containers: 1supabase stop && supabase start For hosted projects managed by Supabase, copy the templates into the [Email Templates](https://supabase.com/dashboard/project/_/auth/templates) section of the Dashboard. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/local-development/customizing-email-templates%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/local-development/customizing-email-templates%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # SQL to REST API Translator | Supabase Docs REST API SQL to REST API Translator ============================== Translate SQL queries to HTTP requests and Supabase client code ------------------------------------------------------------------- * * * Sometimes it's challenging to translate SQL queries to the equivalent [PostgREST](https://postgrest.org/) request or Supabase client code. Use this tool to help with this translation. PostgREST supports a subset of SQL, so not all SQL queries will translate. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/api/sql-to-rest%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/api/sql-to-rest%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Realtime Concepts | Supabase Docs Realtime Realtime Concepts ===================== * * * Concepts[#](https://supabase.com/docs/guides/realtime/concepts#concepts) ------------------------------------------------------------------------- There are several concepts and terminology that is useful to understand how Realtime works. * **Channels**: the foundation of Realtime. Think of them as rooms where clients can communicate and listen to events. Channels are identified by a topic name and if they are public or private. * **Topics**: the name of the channel. They are used to identify the channel and are a string used to identify the channel. * **Events**: the type of messages that can be sent and received. * **Payload**: the actual data that is sent and received and that the user will act upon. * **Concurrent Connections**: number of total channels subscribed for all clients. Channels[#](https://supabase.com/docs/guides/realtime/concepts#channels) ------------------------------------------------------------------------- Channels are the foundation of Realtime. Think of them as rooms where clients can communicate and listen to events. Channels are identified by a topic name and if they are public or private. For private channels, you need to use [Realtime Authorization](https://supabase.com/docs/guides/realtime/authorization) to control access to the channel and if they are able to send messages. For public channels, any user can subscribe to the channel, send and receive messages. You can set your project to use only private channels or both private and public channels in the [Realtime Settings](https://supabase.com/docs/guides/realtime/settings) . If you have a private channel and a public channel with the same topic name, Realtime sees them as unique channels and won't send messages between them. Database resources[#](https://supabase.com/docs/guides/realtime/concepts#database-resources) --------------------------------------------------------------------------------------------- ### Database connections[#](https://supabase.com/docs/guides/realtime/concepts#database-connections) Realtime uses several database connections to perform various operations. You can configure some of these connections through [Realtime Settings](https://supabase.com/docs/guides/realtime/settings) . The connections include: * **Migrations**: Two temporary connections to run database migrations when needed * **Authorization**: Configurable connection pool to check authorization policies on join that are always started. * **Broadcast from database**: One connection to receive data from replication slot used to broadcast the changes to the clients that is always started. * **Postgres Changes**: Multiple connection pools required. These pools are only started if you use Postgres Changes. * **Subscription management**: To manage the subscribers to Postgres Changes * **Subscription cleanup**: To cleanup the subscribers to Postgres Changes * **WAL pull**: To pull the changes from the database The number of connections varies based on your compute add-on size and configuration. The following table shows the default connection pool sizes for different compute add-on variants: | Compute Add-on | Broadcast from database | Authorization Pool Size | Subscription management | Subscription cleanup | WAL pull | | --- | --- | --- | --- | --- | --- | | Nano | 1 | 2 | 2 | 2 | 2 | | Micro | 1 | 2 | 2 | 2 | 2 | | Small | 1 | 5 | 4 | 4 | 4 | | Medium | 1 | 5 | 4 | 4 | 4 | | Large | 1 | 5 | 4 | 4 | 4 | | XL | 1 | 10 | 7 | 7 | 7 | | 2XL | 1 | 10 | 7 | 7 | 7 | | 4XL | 1 | 10 | 7 | 7 | 7 | | 8XL | 1 | 15 | 9 | 9 | 9 | | 12XL | 1 | 15 | 9 | 9 | 9 | | 16XL | 1 | 15 | 9 | 9 | 9 | | \>16XL | 1 | 15 | 9 | 9 | 9 | You can customize `Authorization Pool Size` through the `Database connection pool size` parameter in your Realtime configuration. If not specified, the default values shown in the table will be used. ### Replication slots[#](https://supabase.com/docs/guides/realtime/concepts#replication-slots) Realtime also uses, at maximum, 2 replication slots. * **Broadcast from database**: To broadcast the changes from the database to the clients * **Postgres Changes**: To listen to changes from the database ### Schema and tables[#](https://supabase.com/docs/guides/realtime/concepts#schema-and-tables) The `realtime` schema creates the following tables: * `schema_migrations` - To track the migrations that have been run on the database from Realtime * `subscription` - Track the subscribers to Postgres Changes * `messages` - Partitioned table per day that's used for Authorization and Broadcast from database * **Authorization**: To check the authorization policies on join by checking if a given user can read and write to this table * **Broadcast from database**: Replication slot tracks a publication to this table to broadcast the changes to the connected clients. * The schema from the table is the following: 1create table realtime.messages (2topic text not null, -- The topic of the message3extension text not null, -- The extension of the message (presence, broadcast)4payload jsonb null, -- The payload of the message5event text null, -- The event of the message6private boolean null default false, -- If the message is going to use a private channel7updated_at timestamp without time zone not null default now(), -- The timestamp of the message8inserted_at timestamp without time zone not null default now(), -- The timestamp of the message9id uuid not null default gen_random_uuid (), -- The id of the message10constraint messages_pkey primary key (id, inserted_at)) partition by RANGE (inserted_at); Realtime has a cleanup process that will delete tables older than 3 days. ### Functions[#](https://supabase.com/docs/guides/realtime/concepts#functions) Realtime creates two functions on your database: * `realtime.send` - Inserts an entry into `realtime.messages` table that will trigger the replication slot to broadcast the changes to the clients. It also captures errors to prevent the trigger from breaking. * `realtime.broadcast_changes` - uses `realtime.send` to broadcast the changes with a format that is compatible with Postgres Changes ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/realtime/concepts%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/realtime/concepts%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Quickstart | Supabase Docs Cron Quickstart ============== * * * Job names are case sensitive and cannot be edited once created. Attempting to create a second Job with the same name (and case) will overwrite the first Job. Schedule a job[#](https://supabase.com/docs/guides/cron/quickstart#schedule-a-job) ----------------------------------------------------------------------------------- DashboardSQL 1. Go to the [Jobs](https://supabase.com/dashboard/project/_/integrations/cron/jobs) section to schedule your first Job. 2. Click on `Create job` button or navigate to the new Cron Job form [here](https://supabase.com/dashboard/project/_/integrations/cron/jobs?new=true) . 3. Name your Cron Job. 4. Choose a schedule for your Job by inputting cron syntax (refer to the syntax chart in the form) or natural language. 5. Input SQL snippet or select a Database function, HTTP request, or Supabase Edge Function. Cron syntax You can input seconds for your Job schedule interval as long as you're on Postgres version 15.1.1.61 or later. Edit a job[#](https://supabase.com/docs/guides/cron/quickstart#edit-a-job) --------------------------------------------------------------------------- DashboardSQL 1. Go to the [Jobs](https://supabase.com/dashboard/project/_/integrations/cron/jobs) section and find the Job you'd like to edit. 2. Click on the three vertical dots menu on the right side of the Job and click `Edit cron job`. 3. Make your changes and then click `Save cron job`. Activate/Deactivate a job[#](https://supabase.com/docs/guides/cron/quickstart#activatedeactivate-a-job) -------------------------------------------------------------------------------------------------------- DashboardSQL 1. Go to the [Jobs](https://supabase.com/dashboard/project/_/integrations/cron/jobs) section and find the Job you'd like to unschedule. 2. Toggle the `Active`/`Inactive` switch next to Job name. Unschedule a job[#](https://supabase.com/docs/guides/cron/quickstart#unschedule-a-job) --------------------------------------------------------------------------------------- DashboardSQL 1. Go to the [Jobs](https://supabase.com/dashboard/project/_/integrations/cron/jobs) section and find the Job you'd like to delete. 2. Click on the three vertical dots menu on the right side of the Job and click `Delete cron job`. 3. Confirm deletion by entering the Job name. Inspecting job runs[#](https://supabase.com/docs/guides/cron/quickstart#inspecting-job-runs) --------------------------------------------------------------------------------------------- DashboardSQL 1. Go to the [Jobs](https://supabase.com/dashboard/project/_/integrations/cron/jobs) section and find the Job you want to see the runs of. 2. Click on the `History` button next to the Job name. Examples[#](https://supabase.com/docs/guides/cron/quickstart#examples) ----------------------------------------------------------------------- ### Delete data every week[#](https://supabase.com/docs/guides/cron/quickstart#delete-data-every-week) Delete old data every Saturday at 3:30AM (GMT): 1select cron.schedule (2 'saturday-cleanup', -- name of the cron job3 '30 3 * * 6', -- Saturday at 3:30AM (GMT)4 $$ delete from events where event_time < now() - interval '1 week' $$5); ### Run a vacuum every day[#](https://supabase.com/docs/guides/cron/quickstart#run-a-vacuum-every-day) Vacuum every day at 3:00AM (GMT): 1select cron.schedule('nightly-vacuum', '0 3 * * *', 'VACUUM'); ### Call a database function every 5 minutes[#](https://supabase.com/docs/guides/cron/quickstart#call-a-database-function-every-5-minutes) Create a [`hello_world()`](https://supabase.com/docs/guides/database/functions?language=sql#simple-functions) database function and then call it every 5 minutes: 1select cron.schedule('call-db-function', '*/5 * * * *', 'SELECT hello_world()'); ### Call a database stored procedure[#](https://supabase.com/docs/guides/cron/quickstart#call-a-database-stored-procedure) To use a stored procedure, you can call it like this: 1select cron.schedule('call-db-procedure', '*/5 * * * *', 'CALL my_procedure()'); ### Invoke Supabase Edge Function every 30 seconds[#](https://supabase.com/docs/guides/cron/quickstart#invoke-supabase-edge-function-every-30-seconds) Make a POST request to a Supabase Edge Function every 30 seconds: 1select2 cron.schedule(3 'invoke-function-every-half-minute',4 '30 seconds',5 $$6 select7 net.http_post(8 url:='https://project-ref.supabase.co/functions/v1/function-name',9 headers:=jsonb_build_object('Content-Type','application/json', 'Authorization', 'Bearer ' || 'YOUR_ANON_KEY'),10 body:=jsonb_build_object('time', now() ),11 timeout_milliseconds:=500012 ) as request_id;13 $$14 ); This requires the [`pg_net` extension](https://supabase.com/docs/guides/database/extensions/pg_net) to be enabled. Caution: Scheduling system maintenance[#](https://supabase.com/docs/guides/cron/quickstart#caution-scheduling-system-maintenance) ---------------------------------------------------------------------------------------------------------------------------------- Be extremely careful when setting up Jobs for system maintenance tasks as they can have unintended consequences. For instance, scheduling a command to terminate idle connections with `pg_terminate_backend(pid)` can disrupt critical background processes like nightly backups. Often, there is an existing Postgres setting, such as `idle_session_timeout`, that can perform these common maintenance tasks without the risk. Reach out to [Supabase Support](https://supabase.com/support) if you're unsure if that applies to your use case. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/cron/quickstart%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/cron/quickstart%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Deployment & Branching | Supabase Docs Home Deployment & Branching ========================== * * * Deploying your app makes it live and accessible to users. Usually, you deploy an app to at least two environments: a production environment for users and (one or multiple) staging or preview environments for developers. Supabase provides several options for environment management and deployment. Environment management[#](https://supabase.com/docs/guides/deployment#environment-management) ---------------------------------------------------------------------------------------------- You can maintain separate development, staging, and production environments for Supabase: * **Development**: Develop with a local Supabase stack using the [Supabase CLI](https://supabase.com/docs/guides/local-development) . * **Staging**: Use [branching](https://supabase.com/docs/guides/deployment/branching) to create staging or preview environments. You can use persistent branches for a long-lived staging setup, or ephemeral branches for short-lived previews (which are often tied to a pull request). * **Production**: If you have branching enabled, you can use the Supabase GitHub integration to automatically push your migration files when you merge a pull request. Alternatively, you can set up your own continuous deployment pipeline using the Supabase CLI. ##### Self-hosting Read the [self-hosting guides](https://supabase.com/docs/guides/self-hosting) for instructions on hosting your own Supabase stack. Deployment[#](https://supabase.com/docs/guides/deployment#deployment) ---------------------------------------------------------------------- You can automate deployments using: * The [Supabase GitHub integration](https://supabase.com/dashboard/project/_/settings/integrations) (with branching enabled) * The [Supabase CLI](https://supabase.com/docs/guides/local-development) in your own continuous deployment pipeline * The [Supabase Terraform provider](https://supabase.com/docs/guides/deployment/terraform) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/deployment%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/deployment%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Data REST API | Supabase Docs REST API Data REST API ================= * * * Supabase auto-generates an API directly from your database schema allowing you to connect to your database through a restful interface, directly from the browser. The API is auto-generated from your database and is designed to get you building as fast as possible, without writing a single line of code. You can use them directly from the browser (two-tier architecture), or as a complement to your own API server (three-tier architecture). Features [#](https://supabase.com/docs/guides/api#rest-api-overview) --------------------------------------------------------------------- Supabase provides a RESTful API using [PostgREST](https://postgrest.org/) . This is a very thin API layer on top of Postgres. It exposes everything you need from a CRUD API at the URL `https://.supabase.co/rest/v1/`. The REST interface is automatically reflected from your database's schema and is: * **Instant and auto-generated.** As you update your database the changes are immediately accessible through your API. * **Self documenting.** Supabase generates documentation in the Dashboard which updates as you make database changes. * **Secure.** The API is configured to work with PostgreSQL's Row Level Security, provisioned behind an API gateway with key-auth enabled. * **Fast.** Our benchmarks for basic reads are more than 300% faster than Firebase. The API is a very thin layer on top of Postgres, which does most of the heavy lifting. * **Scalable.** The API can serve thousands of simultaneous requests, and works well for Serverless workloads. The reflected API is designed to retain as much of Postgres' capability as possible including: * Basic CRUD operations (Create/Read/Update/Delete) * Arbitrarily deep relationships among tables/views, functions that return table types can also nest related tables/views. * Works with Postgres Views, Materialized Views and Foreign Tables * Works with Postgres Functions * User defined computed columns and computed relationships * The Postgres security model - including Row Level Security, Roles, and Grants. The REST API resolves all requests to a single SQL statement leading to fast response times and high throughput. Reference: * [Docs](https://postgrest.org/) * [Source Code](https://github.com/PostgREST/postgrest) API URL and keys[#](https://supabase.com/docs/guides/api#api-url-and-keys) --------------------------------------------------------------------------- You can find the API URL and Keys in the [Dashboard](https://supabase.com/dashboard/project/_/settings/api-keys) . ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/api%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/api%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Build an API route in less than 2 minutes. | Supabase Docs REST API Build an API route in less than 2 minutes. ============================================== Create your first API route by creating a table called `todos` to store tasks. ---------------------------------------------------------------------------------- * * * Let's create our first REST route which we can query using `cURL` or the browser. We'll create a database table called `todos` for storing tasks. This creates a corresponding API route `/rest/v1/todos` which can accept `GET`, `POST`, `PATCH`, & `DELETE` requests. 1 ### Set up a Supabase project with a 'todos' table [Create a new project](https://supabase.com/dashboard) in the Supabase Dashboard. After your project is ready, create a table in your Supabase database. You can do this with either the Table interface or the [SQL Editor](https://supabase.com/dashboard/project/_/sql) . SQLDashboard 1-- Create a table called "todos"2-- with a column to store tasks.3create table todos (4 id serial primary key,5 task text6); 2 ### Allow public access Let's turn on Row Level Security for this table and allow public access. 1-- Turn on security2alter table "todos"3enable row level security;45-- Allow anonymous access6create policy "Allow public access"7 on todos8 for select9 to anon10 using (true); 3 ### Insert some dummy data Now we can add some data to our table which we can access through our API. 1insert into todos (task)2values3 ('Create tables'),4 ('Enable security'),5 ('Add data'),6 ('Fetch data from the API'); 4 ### Fetch the data Find your API URL and Keys in your Dashboard [API Settings](https://supabase.com/dashboard/project/_/settings/api) . You can now query your "todos" table by appending `/rest/v1/todos` to the API URL. Copy this block of code, substitute `` and ``, then run it from a terminal. 1curl 'https://.supabase.co/rest/v1/todos' \2-H "apikey: " \3-H "Authorization: Bearer " Bonus[#](https://supabase.com/docs/guides/api/quickstart#bonus) ---------------------------------------------------------------- There are several options for accessing your data: ### Browser[#](https://supabase.com/docs/guides/api/quickstart#browser) You can query the route in your browser, by appending the `anon` key as a query parameter: `https://.supabase.co/rest/v1/todos?apikey=` ### Client libraries[#](https://supabase.com/docs/guides/api/quickstart#client-libraries) We provide a number of [Client Libraries](https://github.com/supabase/supabase#client-libraries) . JavaScriptDartPythonSwift 1const { data, error } = await supabase.from('todos').select() ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/api/quickstart%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/api/quickstart%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Benchmarks | Supabase Docs Realtime Benchmarks ============== Scalability Benchmarks for Supabase Realtime. ------------------------------------------------- * * * This guide explores the scalability of Realtime's features: Broadcast, Presence, and Postgres Changes. Methodology[#](https://supabase.com/docs/guides/realtime/benchmarks#methodology) --------------------------------------------------------------------------------- * The benchmarks are conducted using k6, an open-source load testing tool, against a Realtime Cluster deployed on AWS. * The cluster configurations use 2-6 nodes, tested in both single-region and multi-region setups, all connected to a single Supabase project. * The load generators (k6 servers) are deployed on AWS to minimize network latency impact on the results. * Tests are executed with a full load from the start without warm-up runs. The metrics collected include: message throughput, latency percentiles, CPU and memory utilization, and connection success rates. Note that performance in production environments may vary based on factors such as network conditions, hardware specifications, and specific usage patterns. Workloads[#](https://supabase.com/docs/guides/realtime/benchmarks#workloads) ----------------------------------------------------------------------------- The proposed workloads are designed to demonstrate Supabase Realtime's throughput and scalability. These benchmarks focus on core functionality and common usage patterns. The benchmarking results include the following workloads: 1. **Broadcast Performance** 2. **Payload Size Impact on Broadcast** 3. **Large-Scale Broadcasting** 4. **Authentication and New Connection Rate** 5. **Database Events** Results[#](https://supabase.com/docs/guides/realtime/benchmarks#results) ------------------------------------------------------------------------- ### Broadcast: Using WebSockets[#](https://supabase.com/docs/guides/realtime/benchmarks#broadcast-using-websockets) This workload evaluates the system's capacity to handle multiple concurrent WebSocket connections and sending Broadcast messages via the WebSocket. Each virtual user (VU) in the test: * Establishes and maintains a WebSocket connection * Joins two distinct channels: * An echo channel (1 user per channel) for direct message reflection * A broadcast channel (6 users per channel) for group communication * Generates traffic by sending 2 messages per second to each joined channel for 10 minutes ![Broadcast Performance](https://supabase.com/docs/img/guides/realtime/broadcast-performance.png) | Metric | Value | | --- | --- | | Concurrent Users | 32\_000 | | Total Channel Joins | 64\_000 | | Message Throughput | 224\_000 msgs/sec | | Median Latency | 6 ms | | Latency (p95) | 28 ms | | Latency (p99) | 213 ms | | Data Received | 6.4 MB/s (7.9 GB total) | | Data Sent | 23 KB/s (28 MB total) | | New Connection Rate | 320 conn/sec | | Channel Join Rate | 640 joins/sec | ### Broadcast: Using the database[#](https://supabase.com/docs/guides/realtime/benchmarks#broadcast-using-the-database) This workload evaluates the system's capacity to send Broadcast messages from the database using the `realtime.broadcast_changes` function. Each virtual user (VU) in the test: * Establishes and maintains a WebSocket connection * Joins a distinct channel: * A single channel (100 users per channel) for group communication * Database has a trigger set to run `realtime.broadcast_changes` on every insert * Database triggers 10\_000 inserts per second ![Broadcast from Database Performance](https://supabase.com/docs/img/guides/realtime/broadcast-from-database-performance.png) | Metric | Value | | --- | --- | | Concurrent Users | 80\_000 | | Total Channel Joins | 160\_000 | | Message Throughput | 10\_000 msgs/sec | | Median Latency | 46 ms | | Latency (p95) | 132 ms | | Latency (p99) | 159 ms | | Data Received | 1.7 MB/s (42 GB total) | | Data Sent | 0.4 MB/s (4 GB total) | | New Connection Rate | 2000 conn/sec | | Channel Join Rate | 4000 joins/sec | ### Broadcast: Impact of payload size[#](https://supabase.com/docs/guides/realtime/benchmarks#broadcast-impact-of-payload-size) This workload tests the system's performance with different message payload sizes to understand how data volume affects throughput and latency. Each virtual user (VU) follows the same connection pattern as the broadcast test, but with varying message sizes: * Establishes and maintains a WebSocket connection * Joins two distinct channels: * An echo channel (1 user per channel) for direct message reflection * A broadcast channel (6 users per channel) for group communication * Sends messages with payloads of 1KB, 10KB, and 50KB * Generates traffic by sending 2 messages per second to each joined channel for 5 minutes #### 1KB payload[#](https://supabase.com/docs/guides/realtime/benchmarks#1kb-payload) ![1KB Payload Broadcast Performance](https://supabase.com/docs/img/guides/realtime/payload-size-1kb.png) #### 10KB payload[#](https://supabase.com/docs/guides/realtime/benchmarks#10kb-payload) ![10KB Payload Broadcast Performance](https://supabase.com/docs/img/guides/realtime/payload-size-10kb.png) #### 50KB payload[#](https://supabase.com/docs/guides/realtime/benchmarks#50kb-payload) ![50KB Payload Broadcast Performance](https://supabase.com/docs/img/guides/realtime/payload-size-50kb-small.png) | Metric | 1KB Payload | 10KB Payload | 50KB Payload | 50KB Payload (Reduced Load) | | --- | --- | --- | --- | --- | | Concurrent Users | 4\_000 | 4\_000 | 4\_000 | 2\_000 | | Message Throughput | 28\_000 msgs/sec | 28\_000 msgs/sec | 28\_000 msgs/sec | 14\_000 msgs/sec | | Median Latency | 13 ms | 16 ms | 27 ms | 19 ms | | Latency (p95) | 36 ms | 42 ms | 81 ms | 39 ms | | Latency (p99) | 85 ms | 93 ms | 146 ms | 82 ms | | Data Received | 31.2 MB/s (10.4 GB) | 268 MB/s (72 GB) | 1284 MB/s (348 GB) | 644 MB/s (176 GB) | | Data Sent | 9.2 MB/s (3.1 GB) | 76 MB/s (20.8 GB) | 384 MB/s (104 GB) | 192 MB/s (52 GB) | > Note: The final column shows results with reduced load (2,000 users) for the 50KB payload test, demonstrating how the system performs with larger payloads under different concurrency levels. ### Broadcast: Scalability scenarios[#](https://supabase.com/docs/guides/realtime/benchmarks#broadcast-scalability-scenarios) This workload demonstrates Realtime's capability to handle high-scale scenarios with a large number of concurrent users and broadcast channels. The test simulates a scenario where each user participates in group communications with periodic message broadcasts. Each virtual user (VU): * Establishes and maintains a WebSocket connection (30-120 minutes) * Joins 2 broadcast channels * Sends 1 message per minute to each joined channel * Each message is broadcast to 100 other users ![Large Broadcast Performance](https://supabase.com/docs/img/guides/realtime/broadcast-large.png) | Metric | Value | | --- | --- | | Concurrent Users | 250\_000 | | Total Channel Joins | 500\_000 | | Users per Channel | 100 | | Message Throughput | \>800\_000 msgs/sec | | Median Latency | 58 ms | | Latency (p95) | 279 ms | | Latency (p99) | 508 ms | | Data Received | 68 MB/s (600 GB) | | Data Sent | 0.64 MB/s (5.7 GB) | ### Realtime Auth[#](https://supabase.com/docs/guides/realtime/benchmarks#realtime-auth) This workload demonstrates Realtime's capability to handle large amounts of new connections per second and channel joins per second with Authentication Row Level Security (RLS) enabled for these channels. The test simulates a scenario where large volumes of users connect to realtime and participate in auth protected communications. Each virtual user (VU): * Establishes and maintains a WebSocket connection (2.5 minutes) * Joins 2 broadcast channels * Sends 1 message per minute to each joined channel * Each message is broadcast to 100 other users ![Broadcast Auth Performance](https://supabase.com/docs/img/guides/realtime/broadcast-auth.png) | Metric | Value | | --- | --- | | Concurrent Users | 50\_000 | | Total Channel Joins | 100\_000 | | Users per Channel | 100 | | Message Throughput | \>150\_000 msgs/sec | | New Connection Rate | 500 conn/sec | | Channel Join Rate | 1000 joins/sec | | Median Latency | 19 ms | | Latency (p95) | 49 ms | | Latency (p99) | 96 ms | ### Postgres Changes[#](https://supabase.com/docs/guides/realtime/benchmarks#postgres-changes) Realtime systems usually require forethought because of their scaling dynamics. For the `Postgres Changes` feature, every change event must be checked to see if the subscribed user has access. For instance, if you have 100 users subscribed to a table where you make a single insert, it will then trigger 100 "reads": one for each user. There can be a database bottleneck which limits message throughput. If your database cannot authorize the changes rapidly enough, the changes will be delayed until you receive a timeout. Database changes are processed on a single thread to maintain the change order. That means compute upgrades don't have a large effect on the performance of Postgres change subscriptions. You can estimate the expected maximum throughput for your database below. If you are using Postgres Changes at scale, you should consider using a separate "public" table without RLS and filters. Alternatively, you can use Realtime server-side only and then re-stream the changes to your clients using a Realtime Broadcast. Enter your database settings to estimate the maximum throughput for your instance: Don't forget to run your own benchmarks to make sure that the performance is acceptable for your use case. Supabase continues to make improvements to Realtime's Postgres Changes. If you are uncertain about your use case performance, reach out using the [Support Form](https://supabase.com/dashboard/support/new) . The support team can advise on the best solution for each use-case. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/realtime/benchmarks%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/realtime/benchmarks%20so%20I%20can%20ask%20questions%20about%20its%20contents) #### Set your expected parameters Compute: MicroSmall to mediumLarge to 16XL Filters: NoYes RLS: NoYes Connected clients: 5005,00010,00030,000 #### Current maximum possible throughput | Total DB changes /sec | Max messages per client /sec | Max total messages /sec | Latency p95 | | --- | --- | --- | --- | | 64 | 64 | 32,000 | 238ms | View raw throughput table --- # Realtime Limits | Supabase Docs Realtime Realtime Limits =================== * * * Our cluster supports millions of concurrent connections and message throughput for production workloads. Upgrade your plan to increase your limits. Without a spend cap, or on an Enterprise plan, some limits are still in place to protect budgets. All limits are configurable per project. [Contact support](https://supabase.com/dashboard/support/new) if you need your limits increased. Limits by plan[#](https://supabase.com/docs/guides/realtime/limits#limits-by-plan) ----------------------------------------------------------------------------------- | | Free | Pro | Pro (no spend cap) | Team | Enterprise | | --- | --- | --- | --- | --- | --- | | **Concurrent connections** | 200 | 500 | 10,000 | 10,000 | 10,000+ | | **Messages per second** | 100 | 500 | 2,500 | 2,500 | 2,500+ | | **Channel joins per second** | 100 | 500 | 2,500 | 2,500 | 2,500+ | | **Channels per connection** | 100 | 100 | 100 | 100 | 100+ | | **Presence keys per object** | 10 | 10 | 10 | 10 | 10+ | | **Presence messages per second** | 20 | 50 | 1,000 | 1,000 | 1,000+ | | **Broadcast payload size** | 256 KB | 3,000 KB | 3,000 KB | 3,000 KB | 3,000+ KB | | **Postgres change payload size ([**read more**](https://supabase.com/docs/guides/realtime/limits#postgres-changes-payload-limit)
)** | 1,024 KB | 1,024 KB | 1,024 KB | 1,024 KB | 1,024+ KB | Beyond the Free and Pro Plan you can customize your limits by [contacting support](https://supabase.com/dashboard/support/new) . Limit errors[#](https://supabase.com/docs/guides/realtime/limits#limit-errors) ------------------------------------------------------------------------------- When you exceed a limit, errors will appear in the backend logs and client-side messages in the WebSocket connection. * **Logs**: check the [Realtime logs](https://supabase.com/dashboard/project/_/database/realtime-logs) inside your project Dashboard. * **WebSocket errors**: Use your browser's developer tools to find the WebSocket initiation request and view individual messages. ##### Realtime Inspector You can use the [Realtime Inspector](https://realtime.supabase.com/inspector/new) to reproduce an error and share those connection details with Supabase support. Some limits can cause a Channel join to be refused. Realtime will reply with one of the following WebSocket messages: ### `too_many_channels`[#](https://supabase.com/docs/guides/realtime/limits#toomanychannels) Too many channels currently joined for a single connection. ### `too_many_connections`[#](https://supabase.com/docs/guides/realtime/limits#toomanyconnections) Too many total concurrent connections for a project. ### `too_many_joins`[#](https://supabase.com/docs/guides/realtime/limits#toomanyjoins) Too many Channel joins per second. ### `tenant_events`[#](https://supabase.com/docs/guides/realtime/limits#tenantevents) Connections will be disconnected if your project is generating too many messages per second. `supabase-js` will reconnect automatically when the message throughput decreases below your plan limit. An `event` is a WebSocket message delivered to, or sent from a client. Postgres changes payload limit[#](https://supabase.com/docs/guides/realtime/limits#postgres-changes-payload-limit) ------------------------------------------------------------------------------------------------------------------- When this limit is reached, the `new` and `old` record payloads only include the fields with a value size of less than or equal to 64 bytes. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/realtime/limits%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/realtime/limits%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Consuming Supabase Queue Messages with Edge Functions | Supabase Docs Queues Consuming Supabase Queue Messages with Edge Functions ========================================================= Learn how to consume Supabase Queue messages server-side with a Supabase Edge Function ------------------------------------------------------------------------------------------ * * * This guide helps you read & process queue messages server-side with a Supabase Edge Function. Read [Queues API Reference](https://supabase.com/docs/guides/queues/api) for more details on our API. Concepts[#](https://supabase.com/docs/guides/queues/consuming-messages-with-edge-functions#concepts) ----------------------------------------------------------------------------------------------------- Supabase Queues is a pull-based Message Queue consisting of three main components: Queues, Messages, and Queue Types. You should already be familiar with the [Queues Quickstart](https://supabase.com/docs/guides/queues/quickstart) . ### Consuming messages in an Edge Function[#](https://supabase.com/docs/guides/queues/consuming-messages-with-edge-functions#consuming-messages-in-an-edge-function) This is a Supabase Edge Function that reads 5 messages off the queue, processes each of them, and deletes each message when it is done. 1import 'jsr:@supabase/functions-js/edge-runtime.d.ts'2import { createClient } from 'npm:@supabase/supabase-js@2'34const supabaseUrl = 'supabaseURL'5const supabaseKey = 'supabaseKey'67const supabase = createClient(supabaseUrl, supabaseKey)8const queueName = 'your_queue_name'910// Type definition for queue messages11interface QueueMessage {12 msg_id: bigint13 read_ct: number14 vt: string15 enqueued_at: string16 message: any17}1819async function processMessage(message: QueueMessage) {20 //21 // Do whatever logic you need to with the message content22 //23 // Delete the message from the queue24 const { error: deleteError } = await supabase.schema('pgmq_public').rpc('delete', {25 queue_name: queueName,26 msg_id: message.msg_id,27 })2829 if (deleteError) {30 console.error(`Failed to delete message ${message.msg_id}:`, deleteError)31 } else {32 console.log(`Message ${message.msg_id} deleted from queue`)33 }34}3536Deno.serve(async (req) => {37 const { data: messages, error } = await supabase.schema('pgmq_public').rpc('read', {38 queue_name: queueName,39 sleep_seconds: 0, // Don't wait if queue is empty40 n: 5, // Read 5 messages off the queue41 })4243 if (error) {44 console.error(`Error reading from ${queueName} queue:`, error)45 return new Response(JSON.stringify({ error: error.message }), {46 status: 500,47 headers: { 'Content-Type': 'application/json' },48 })49 }5051 if (!messages || messages.length === 0) {52 console.log('No messages in workflow_messages queue')53 return new Response(JSON.stringify({ message: 'No messages in queue' }), {54 status: 200,55 headers: { 'Content-Type': 'application/json' },56 })57 }5859 console.log(`Found ${messages.length} messages to process`)6061 // Process each message that was read off the queue62 for (const message of messages) {63 try {64 await processMessage(message as QueueMessage)65 } catch (error) {66 console.error(`Error processing message ${message.msg_id}:`, error)67 }68 }6970 // Return immediately while background processing continues71 return new Response(72 JSON.stringify({73 message: `Processing ${messages.length} messages in background`,74 count: messages.length,75 }),76 {77 status: 200,78 headers: { 'Content-Type': 'application/json' },79 }80 )81}) Every time this Edge Function is run it: 1. Read 5 messages off the queue 2. Call the `processMessage` function 3. At the end of `processMessage`, the message is deleted from the queue 4. If `processMessage` throws an error, the error is logged. In this case, the message is still in the queue, so the next time this Edge Function runs it reads the message again. You might find this kind of setup handy to run with [Supabase Cron](https://supabase.com/docs/guides/cron) . You can set up Cron so that every N number of minutes or seconds, the Edge Function will run and process a number of messages off the queue. Similarly, you can invoke the Edge Function on command at any given time with [`supabase.functions.invoke`](https://supabase.com/docs/guides/functions/quickstart-dashboard#usage) . ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/queues/consuming-messages-with-edge-functions%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/queues/consuming-messages-with-edge-functions%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Using Realtime with Next.js | Supabase Docs Realtime Using Realtime with Next.js =============================== * * * In this guide, we explore the best ways to receive real-time Postgres changes with your Next.js application. We'll show both client and server side updates, and explore which option is best. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/realtime/realtime-with-nextjs%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/realtime/realtime-with-nextjs%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Secure configuration of Supabase products | Supabase Docs Security Secure configuration of Supabase products ============================================= * * * The Supabase [production checklist](https://supabase.com/docs/guides/deployment/going-into-prod) provides detailed advice on preparing an app for production. While our [SOC 2](https://supabase.com/docs/guides/security/soc-2-compliance) and [HIPAA](https://supabase.com/docs/guides/security/hipaa-compliance) compliance documents outline the roles and responsibilities for building a secure and compliant app. Various products at Supabase have their own hardening and configuration guides, below is a definitive list of these to help guide your way. Auth[#](https://supabase.com/docs/guides/security/product-security#auth) ------------------------------------------------------------------------- * [Password security](https://supabase.com/docs/guides/auth/password-security) * [Rate limits](https://supabase.com/docs/guides/auth/rate-limits) * [Bot detection / Prevention](https://supabase.com/docs/guides/auth/auth-captcha) * [JWTs](https://supabase.com/docs/guides/auth/jwts) Database[#](https://supabase.com/docs/guides/security/product-security#database) --------------------------------------------------------------------------------- * [Row Level Security](https://supabase.com/docs/guides/database/postgres/row-level-security) * [Column Level Security](https://supabase.com/docs/guides/database/postgres/column-level-security) * [Hardening the Data API](https://supabase.com/docs/guides/api/hardening-data-api) * [Additional security controls for the Data API](https://supabase.com/docs/guides/api/securing-your-api) * [Custom claims and role based access control](https://supabase.com/docs/guides/api/custom-claims-and-role-based-access-control-rbac) * [Managing Postgres roles](https://supabase.com/docs/guides/database/postgres/roles) * [Managing secrets with Vault](https://supabase.com/docs/guides/database/vault) * [Superuser access and unsupported operations](https://supabase.com/docs/guides/security/docs/guides/database/postgres/roles-superuser) Storage[#](https://supabase.com/docs/guides/security/product-security#storage) ------------------------------------------------------------------------------- * [Object ownership](https://supabase.com/docs/guides/storage/security/ownership) * [Access control](https://supabase.com/docs/guides/storage/security/access-control) * The Storage API docs contain hints about required [RLS policy permissions](https://supabase.com/docs/reference/javascript/storage-createbucket) * [Custom roles with the storage schema](https://supabase.com/docs/guides/storage/schema/custom-roles) Realtime[#](https://supabase.com/docs/guides/security/product-security#realtime) --------------------------------------------------------------------------------- * [Authorization](https://supabase.com/docs/guides/security/docs/guides/realtime/authorization) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/security/product-security%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/security/product-security%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Permissions | Supabase Docs Platform Permissions =============== * * * The Supabase platform offers additional services (e.g. Storage) on top of the Postgres database that comes with each project. These services default to storing their operational data within your database, to ensure that you retain complete control over it. However, these services assume a base level of access to their data, in order to e.g. be able to run migrations over it. Breaking these assumptions runs the risk of rendering these services inoperational for your project: * all entities under the `storage` schema are owned by `supabase_storage_admin` * all entities under the `auth` schema are owned by `supabase_auth_admin` It is possible for violations of these assumptions to not cause an immediate outage, but take effect at a later time when a newer migration becomes available. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/platform/permissions%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/platform/permissions%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Your monthly invoice | Supabase Docs Platform Your monthly invoice ======================== * * * Billing cycle[#](https://supabase.com/docs/guides/platform/your-monthly-invoice#billing-cycle) ----------------------------------------------------------------------------------------------- When you sign up for a paid plan you get charged once a month at the beginning of the billing cycle. A billing cycle starts with the creation of a Supabase organization. If you create an organization on the sixth of January your billing cycle resets on the sixth of each month. If the anchored day is not present in the current month, then the last day of the month is used. Your invoice explained[#](https://supabase.com/docs/guides/platform/your-monthly-invoice#your-invoice-explained) ----------------------------------------------------------------------------------------------------------------- When your billing cycle resets an invoice gets issued. That invoice contains line items from both the current and the previous billing cycle. Fixed fees for the current billing cycle, usage based fees for the previous billing cycle. ### Fixed fees[#](https://supabase.com/docs/guides/platform/your-monthly-invoice#fixed-fees) Fixed fees are independent of usage and paid in-advance. Whether you have one or several projects, hundreds or millions of active users, the fee is always the same, and doesn't vary. Examples are the subscription fee, the fee for HIPAA and for priority support. ### Usage based fees[#](https://supabase.com/docs/guides/platform/your-monthly-invoice#usage-based-fees) Fees vary depending on usage and are paid in arrears. The more usage you have, the higher the fee. Examples are fees for monthly active users and storage size. ### Discounted line items[#](https://supabase.com/docs/guides/platform/your-monthly-invoice#discounted-line-items) Paid plans come with a usage quota for certain line items. You only pay for usage that goes beyond the quota. The quota for Storage for example is 100 GB. If you use 105 GB, you pay for 5 GB. If you use 95 GB, you pay nothing. This quota is declared as a discount on your invoice. #### Compute Credits[#](https://supabase.com/docs/guides/platform/your-monthly-invoice#compute-credits) Paid plans come with $10 in Compute Credits per month. This suffices for a single project using a Nano or Micro compute instance. Every additional project adds compute fees to your monthly invoice though. ### Example invoice[#](https://supabase.com/docs/guides/platform/your-monthly-invoice#example-invoice) The following invoice was issued on January 6, 2025 with the previous billing cycle from December 6, 2024 - January 5, 2025, and the current billing cycle from January 6 - February 5, 2025. ![Example Invoice](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fguides%2Fplatform%2Fexample-invoice.png&w=3840&q=75) 1. The final amount due 2. Fixed subscription fee for the current billing cycle 3. Usage based fee for Compute for the previous billing cycle. There were two projects (`wsmmedyqtlrvbcesxdew`, `wwxdpovgtfcmcnxwsaad`) running 744 hours (24 hours \* 31 days). These projects incurred $10 in Compute fees each. With $10 in Compute Credits deducted, the final Compute fees are $10. 4. Usage based fee for Custom Domain for the previous billing cycle. There is no free usage quota for Custom Domain. You get charged for the 744 hours (24 hours \* 31 days) a Custom Domain was active. The final Custom Domain fees are $10.19. 5. Usage based fee for Egress for the previous billing cycle. There is a free usage quota of 250 GB for Egress. You get charged for usage beyond 250 GB only, meaning for 2,119.47 GB. The final Egress fees are $190.75. 6. Usage based fee for Monthly Active Users for the previous billing cycle. There is a free usage quota of 100,000 users. With 141 users there is no charge for this line item. ### Why is my invoice more than $25?[#](https://supabase.com/docs/guides/platform/your-monthly-invoice#why-is-my-invoice-more-than-$,25-) The amount due of your invoice being higher than the $25 subscription fee for the Pro Plan can have several reasons. * **Running several projects:** You had more than one project running in the previous billing cycle. Supabase provides a dedicated server and database for every project. That means that every project you launch incurs compute costs. While the $10 Compute Credits cover a single project using a Nano or Micro compute instance, every additional project adds at least $10 compute costs to your invoice. * **Usage beyond quota:** You exceeded the included usage quota for one or more line items in the previous billing cycle while having the Spend Cap disabled. * **Usage that is not covered by the Spend Cap:** You had usage in the previous billing cycle that is not covered by the [Spend Cap](https://supabase.com/docs/guides/platform/cost-control#spend-cap) . For example using an IPv4 address or a custom domain. How to settle your invoices[#](https://supabase.com/docs/guides/platform/your-monthly-invoice#how-to-settle-your-invoices) --------------------------------------------------------------------------------------------------------------------------- Monthly invoices are auto-collected by charging the payment method marked as "active" for an organization. ### Payment failure[#](https://supabase.com/docs/guides/platform/your-monthly-invoice#payment-failure) If your payment fails, Supabase retries the charge several times. We send you a Payment Failure email with the reason for the failure. Follow the steps outlined in this email. You can manually trigger a charge at any time via * the link in the Payment Failure email * the "Pay now" button on the [organization's invoices page](https://supabase.com/dashboard/org/_/billing#invoices) Where to find your invoices[#](https://supabase.com/docs/guides/platform/your-monthly-invoice#where-to-find-your-invoices) --------------------------------------------------------------------------------------------------------------------------- Your invoice is sent to you via email. You can also find your invoices on the [organization's invoices page](https://supabase.com/dashboard/org/_/billing#invoices) . ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/platform/your-monthly-invoice%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/platform/your-monthly-invoice%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Secure configuration of Supabase platform | Supabase Docs Security Secure configuration of Supabase platform ============================================= * * * The Supabase hosted platform provides a secure by default configuration. Some organizations may however require further security controls to meet their own security policies or compliance requirements. Access to additional security controls can be found under the [security tab](https://supabase.com/dashboard/org/_/security) for organizations. Available controls[#](https://supabase.com/docs/guides/security/platform-security#available-controls) ------------------------------------------------------------------------------------------------------ Additional security controls are under active development. Any changes will be published here and in our [changelog](https://supabase.com/changelog) . ### Enforce multi-factor authentication (MFA)[#](https://supabase.com/docs/guides/security/platform-security#enforce-multi-factor-authentication-mfa) Organization owners can choose to enforce MFA for all team members. For configuration information, see [Enforce MFA on Organization](https://supabase.com/docs/guides/platform/mfa/org-mfa-enforcement) ### SSO for organizations[#](https://supabase.com/docs/guides/security/platform-security#sso-for-organizations) Supabase offers single sign-on (SSO) as a login option to provide additional account security for your team. This allows company administrators to enforce the use of an identity provider when logging into Supabase. For configuration information, see [Enable SSO for Your Organization](https://supabase.com/docs/guides/platform/sso) . ### Postgres SSL enforcement[#](https://supabase.com/docs/guides/security/platform-security#postgres-ssl-enforcement) Supabase projects support connecting to the Postgres DB without SSL enforced to maximize client compatibility. For increased security, you can prevent clients from connecting if they're not using SSL. For configuration information, see [Postgres SSL Enforcement](https://supabase.com/docs/guides/platform/ssl-enforcement) Controlling this at the organization level is on our roadmap. ### Network restrictions[#](https://supabase.com/docs/guides/security/platform-security#network-restrictions) Each Supabase project comes with configurable restrictions on the IP ranges that are allowed to connect to Postgres and its pooler ("your database"). These restrictions are enforced before traffic reaches the database. If a connection is not restricted by IP, it still needs to authenticate successfully with valid database credentials. For configuration information, see [Network Restrictions](https://supabase.com/docs/guides/platform/network-restrictions) Controlling this at the organization level is on our roadmap. ### PrivateLink[#](https://supabase.com/docs/guides/security/platform-security#privatelink) PrivateLink provides enterprise-grade private network connectivity between your AWS VPC and your Supabase database using AWS VPC Lattice. This eliminates exposure to the public internet by creating a secure, private connection that keeps your database traffic within the AWS network backbone. For configuration information, see [PrivateLink](https://supabase.com/docs/guides/platform/privatelink) PrivateLink is currently in beta. To establish PrivateLink with a Read Replica, reach out to your account rep. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/security/platform-security%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/security/platform-security%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Realtime | Supabase Docs Realtime Realtime ============ Send and receive messages to connected clients. --------------------------------------------------- * * * Supabase provides a globally distributed [Realtime](https://github.com/supabase/realtime) service with the following features: * [Broadcast](https://supabase.com/docs/guides/realtime/broadcast) : Send low-latency messages between clients. Perfect for real-time messaging, database changes, cursor tracking, game events, and custom notifications. * [Presence](https://supabase.com/docs/guides/realtime/presence) : Track and synchronize user state across clients. Ideal for showing who's online, or active participants. * [Postgres Changes](https://supabase.com/docs/guides/realtime/postgres-changes) : Listen to database changes in real-time. What can you build?[#](https://supabase.com/docs/guides/realtime#what-can-you-build) ------------------------------------------------------------------------------------- * **Chat applications** - Real-time messaging with typing indicators and online presence * **Collaborative tools** - Document editing, whiteboards, and shared workspaces * **Live dashboards** - Real-time data visualization and monitoring * **Multiplayer games** - Synchronized game state and player interactions * **Social features** - Live notifications, reactions, and user activity feeds Check the [Getting Started](https://supabase.com/docs/guides/realtime/getting_started) guide to get started. Examples[#](https://supabase.com/docs/guides/realtime#examples) ---------------------------------------------------------------- [Multiplayer.dev\ \ Showcase application displaying cursor movements and chat messages using Broadcast.](https://multiplayer.dev/) [Chat\ \ Supabase UI chat component using Broadcast to send message between users.](https://supabase.com/ui/docs/nextjs/realtime-chat) [Avatar Stack\ \ Supabase UI avatar stack component using Presence to track connected users.](https://supabase.com/ui/docs/nextjs/realtime-avatar-stack) [Realtime Cursor\ \ Supabase UI realtime cursor component using Broadcast to share users' cursors to build collaborative applications.](https://supabase.com/ui/docs/nextjs/realtime-cursor) Resources[#](https://supabase.com/docs/guides/realtime#resources) ------------------------------------------------------------------ Find the source code and documentation in the Supabase GitHub repository. [Supabase Realtime\ \ View the source code.](https://github.com/supabase/realtime) [Realtime: Multiplayer Edition\ \ Read more about Supabase Realtime.](https://supabase.com/blog/supabase-realtime-multiplayer-general-availability) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/realtime%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/realtime%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Using Custom Schemas | Supabase Docs REST API Using Custom Schemas ======================== * * * By default, your database has a `public` schema which is automatically exposed on data APIs. Creating custom schemas[#](https://supabase.com/docs/guides/api/using-custom-schemas#creating-custom-schemas) -------------------------------------------------------------------------------------------------------------- You can create your own custom schema/s by running the following SQL, substituting `myschema` with the name you want to use for your schema: 1CREATE SCHEMA myschema; Exposing custom schemas[#](https://supabase.com/docs/guides/api/using-custom-schemas#exposing-custom-schemas) -------------------------------------------------------------------------------------------------------------- You can expose custom database schemas - to do so you need to follow these steps: 1. Go to [API settings](https://supabase.com/dashboard/project/_/settings/api) and add your custom schema to "Exposed schemas". 2. Run the following SQL, substituting `myschema` with your schema name: 1GRANT USAGE ON SCHEMA myschema TO anon, authenticated, service_role;2GRANT ALL ON ALL TABLES IN SCHEMA myschema TO anon, authenticated, service_role;3GRANT ALL ON ALL ROUTINES IN SCHEMA myschema TO anon, authenticated, service_role;4GRANT ALL ON ALL SEQUENCES IN SCHEMA myschema TO anon, authenticated, service_role;5ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA myschema GRANT ALL ON TABLES TO anon, authenticated, service_role;6ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA myschema GRANT ALL ON ROUTINES TO anon, authenticated, service_role;7ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA myschema GRANT ALL ON SEQUENCES TO anon, authenticated, service_role; Now you can access these schemas from data APIs: JavaScriptDartcURL 1// Initialize the JS client2import { createClient } from '@supabase/supabase-js'3const supabase = createClient(SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY, {4 db: { schema: 'myschema' },5})67// Make a request8const { data: todos, error } = await supabase.from('todos').select('*')910// You can also change the target schema on a per-query basis11const { data: todos, error } = await supabase.schema('myschema').from('todos').select('*') ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/api/using-custom-schemas%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/api/using-custom-schemas%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Realtime Architecture | Supabase Docs Realtime Realtime Architecture ========================= * * * Realtime is a globally distributed Elixir cluster. Clients can connect to any node in the cluster via WebSockets and send messages to any other client connected to the cluster. Realtime is written in [Elixir](https://elixir-lang.org/) , which compiles to [Erlang](https://www.erlang.org/) , and utilizes many tools the [Phoenix Framework](https://www.phoenixframework.org/) provides out of the box. ![Architecture](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fguides%2Fplatform%2Frealtime%2Farchitecture--light.png&w=3840&q=75) Elixir & Phoenix[#](https://supabase.com/docs/guides/realtime/architecture#elixir--phoenix) -------------------------------------------------------------------------------------------- Phoenix is fast and able to handle millions of concurrent connections. Phoenix can handle many concurrent connections because Elixir provides lightweight processes (not OS processes) to work with. Client-facing WebSocket servers need to handle many concurrent connections. Elixir & Phoenix let the Supabase Realtime cluster do this easily. Channels[#](https://supabase.com/docs/guides/realtime/architecture#channels) ----------------------------------------------------------------------------- Channels are implemented using [Phoenix Channels](https://hexdocs.pm/phoenix/channels.html) which uses [Phoenix.PubSub](https://hexdocs.pm/phoenix_pubsub/Phoenix.PubSub.html) with the default `Phoenix.PubSub.PG2` adapter. The PG2 adapter utilizes Erlang [process groups](https://www.erlang.org/docs/18/man/pg2.html) to implement the PubSub model where a publisher can send messages to many subscribers. Global cluster[#](https://supabase.com/docs/guides/realtime/architecture#global-cluster) ----------------------------------------------------------------------------------------- Presence is an in-memory key-value store backed by a CRDT. When a user is connected to the cluster the state of that user is sent to all connected Realtime nodes. Broadcast lets you send a message from any connected client to a Channel. Any other client connected to that same Channel will receive that message. This works globally. A client connected to a Realtime node in the United States can send a message to another client connected to a node in Singapore. Connect two clients to the same Realtime Channel and they'll all receive the same messages. Broadcast is useful for getting messages to users in the same location very quickly. If a group of clients are connected to a node in Singapore, the message only needs to go to that Realtime node in Singapore and back down. If users are close to a Realtime node they'll get Broadcast messages in the time it takes to ping the cluster. Thanks to the Realtime cluster, you (an amazing Supabase user) don't have to think about which regions your clients are connected to. If you're using Broadcast, Presence, or streaming database changes, messages will always get to your users via the shortest path possible. Connecting to a database[#](https://supabase.com/docs/guides/realtime/architecture#connecting-to-a-database) ------------------------------------------------------------------------------------------------------------- Realtime allows you to listen to changes from your Postgres database. When a new client connects to Realtime and initializes the `postgres_changes` Realtime Extension the cluster will connect to your Postgres database and start streaming changes from a replication slot. Realtime knows the region your database is in, and connects to it from the closest region possible. Every Realtime region has at least two nodes so if one node goes offline the other node should reconnect and start streaming changes again. Broadcast from Postgres[#](https://supabase.com/docs/guides/realtime/architecture#broadcast-from-postgres) ----------------------------------------------------------------------------------------------------------- Realtime Broadcast sends messages when changes happen in your database. Behind the scenes, Realtime creates a publication on the `realtime.messages` table. It then reads the Write-Ahead Log (WAL) file for this table, and sends a message whenever an insert happens. Messages are sent as JSON packages over WebSockets. The `realtime.messages` table is partitioned by day. This allows old messages to be deleted performantly, by dropping old partitions. Partitions are retained for 3 days before being deleted. Broadcast uses [Realtime Authorization](https://supabase.com/docs/guides/realtime/authorization) by default to protect your data. Streaming the Write-Ahead Log[#](https://supabase.com/docs/guides/realtime/architecture#streaming-the-write-ahead-log) ----------------------------------------------------------------------------------------------------------------------- A Postgres logical replication slot is acquired when connecting to your database. Realtime delivers changes by polling the replication slot and appending channel subscription IDs to each wal record. Subscription IDs are Erlang processes representing underlying sockets on the cluster. These IDs are globally unique and messages to processes are routed automatically by the Erlang virtual machine. After receiving results from the polling query, with subscription IDs appended, Realtime delivers records to those clients. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/realtime/architecture%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/realtime/architecture%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Quickstart | Supabase Docs Queues Quickstart ============== Learn how to use Supabase Queues to add and read messages ------------------------------------------------------------- * * * This guide is an introduction to interacting with Supabase Queues via the Dashboard and official client library. Check out [Queues API Reference](https://supabase.com/docs/guides/queues/api) for more details on our API. Concepts[#](https://supabase.com/docs/guides/queues/quickstart#concepts) ------------------------------------------------------------------------- Supabase Queues is a pull-based Message Queue consisting of three main components: Queues, Messages, and Queue Types. ### Pull-Based Queue[#](https://supabase.com/docs/guides/queues/quickstart#pull-based-queue) A pull-based Queue is a Message storage and delivery system where consumers actively fetch Messages when they're ready to process them - similar to constantly refreshing a webpage to display the latest updates. Our pull-based Queues process Messages in a First-In-First-Out (FIFO) manner without priority levels. ### Message[#](https://supabase.com/docs/guides/queues/quickstart#message) A Message in a Queue is a JSON object that is stored until a consumer explicitly processes and removes it, like a task waiting in a to-do list until someone checks and completes it. ### Queue types[#](https://supabase.com/docs/guides/queues/quickstart#queue-types) Supabase Queues offers three types of Queues: * **Basic Queue**: A durable Queue that stores Messages in a logged table. * **Unlogged Queue**: A transient Queue that stores Messages in an unlogged table for better performance but may result in loss of Queue Messages. * **Partitioned Queue** (_Coming Soon_): A durable and scalable Queue that stores Messages in multiple table partitions for better performance. Create Queues[#](https://supabase.com/docs/guides/queues/quickstart#create-queues) ----------------------------------------------------------------------------------- To get started, navigate to the [Supabase Queues](https://supabase.com/dashboard/project/_/integrations/queues/overview) Postgres Module under Integrations in the Dashboard and enable the `pgmq` extension. `pgmq` extension is available in Postgres version 15.6.1.143 or later. ![Supabase Dashboard Integrations page, showing the Queues Postgres Module](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fqueues-quickstart-install.png&w=3840&q=75) On the [Queues page](https://supabase.com/dashboard/project/_/integrations/queues/queues) : * Click **Add a new queue** button If you've already created a Queue click the **Create a queue** button instead. * Name your queue Queue names can only be lowercase and hyphens and underscores are permitted. * Select your [Queue Type](https://supabase.com/docs/guides/queues/quickstart#queue-types) ![Create a Queue from the Supabase Dashboard](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fqueues-quickstart-create.png&w=3840&q=75) ### What happens when you create a queue?[#](https://supabase.com/docs/guides/queues/quickstart#what-happens-when-you-create-a-queue) Every new Queue creates two tables in the `pgmq` schema. These tables are `pgmq.q_` to store and process active messages and `pgmq.a_` to store any archived messages. A "Basic Queue" will create `pgmq.q_` and `pgmq.a_` tables as logged tables. However, an "Unlogged Queue" will create `pgmq.q_` as an unlogged table for better performance while sacrificing durability. The `pgmq.a_` table will still be created as a logged table so your archived messages remain safe and secure. Expose Queues to client-side consumers[#](https://supabase.com/docs/guides/queues/quickstart#expose-queues-to-client-side-consumers) ------------------------------------------------------------------------------------------------------------------------------------- Queues, by default, are not exposed over Supabase Data API and are only accessible via Postgres clients. However, you may grant client-side consumers access to your Queues by enabling the Supabase Data API and granting permissions to the Queues API, which is a collection of database functions in the `pgmq_public` schema that wraps the database functions in the `pgmq` schema. This is to prevent direct access to the `pgmq` schema and its tables (RLS is not enabled by default on any tables) and database functions. To get started, navigate to the Queues [Settings page](https://supabase.com/dashboard/project/_/integrations/queues/settings) and toggle on “Expose Queues via PostgREST”. Once enabled, Supabase creates and exposes a `pgmq_public` schema containing database function wrappers to a subset of `pgmq`'s database functions. ![Screenshot of Queues settings with toggle to expose to PostgREST](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fqueues-quickstart-settings.png&w=3840&q=75) ### Enable RLS on your tables in `pgmq` schema[#](https://supabase.com/docs/guides/queues/quickstart#enable-rls-on-your-tables-in-pgmq-schema) For security purposes, you must enable Row Level Security (RLS) on all Queue tables (all tables in `pgmq` schema that begin with `q_`) if the Data API is enabled. You’ll want to create RLS policies for any Queues you want your client-side consumers to interact with. ![Screenshot of creating an RLS policy from the Queues settings](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fqueues-quickstart-rls.png&w=3840&q=75) ### Grant permissions to `pgmq_public` database functions[#](https://supabase.com/docs/guides/queues/quickstart#grant-permissions-to-pgmqpublic-database-functions) On top of enabling RLS and writing RLS policies on the underlying Queue tables, you must grant the correct permissions to the `pgmq_public` database functions for each Data API role. The permissions required for each Queue API database function: | **Operations** | **Permissions Required** | | --- | --- | | `send` `send_batch` | `Select` `Insert` | | `read` `pop` | `Select` `Update` | | `archive` `delete` | `Select` `Delete` | To manage your queue permissions, click on the Queue Settings button. ![Screenshot of accessing queue settings](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fqueues-quickstart-queue-settings.png&w=3840&q=75) Then enable the required roles permissions. ![Screenshot of configuring API access for roles from the Queues settings](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fqueues-quickstart-roles-light.png&w=3840&q=75) `postgres` and `service_role` roles should never be exposed client-side. ### Enqueueing and dequeueing messages[#](https://supabase.com/docs/guides/queues/quickstart#enqueueing-and-dequeueing-messages) Once your Queue has been created, you can begin enqueueing and dequeueing Messages. JavaScriptDartSwiftPython 1import { createClient } from '@supabase/supabase-js'23const supabaseUrl = 'supabaseURL'4const supabaseKey = 'supabaseKey'56const supabase = createClient(supabaseUrl, supabaseKey)78const QueuesTest: React.FC = () => {9 //Add a Message10 const sendToQueue = async () => {11 const result = await supabase.schema('pgmq_public').rpc('send', {12 queue_name: 'foo',13 message: { hello: 'world' },14 sleep_seconds: 30,15 })16 console.log(result)17 }1819 //Dequeue Message20 const popFromQueue = async () => {21 const result = await supabase.schema('pgmq_public').rpc('pop', { queue_name: 'foo' })22 console.log(result)23 }2425 return (26
27

Queue Test Component

28 32 Add Message33 34 38 Pop Message39 40
41 )42}4344export default QueuesTest ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/queues/quickstart%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/queues/quickstart%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Credits | Supabase Docs Platform Credits =========== * * * Credit balance[#](https://supabase.com/docs/guides/platform/credits#credit-balance) ------------------------------------------------------------------------------------ Each organization has a credit balance. Credits are applied to future invoices to reduce the amount due. As long as the credit balance is greater than $0, credits will be used before charging your payment method on file. ![Subscription upgrade modal](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fguides%2Fplatform%2Fcredit-balance--light.png&w=3840&q=75) You can find the credit balance on the [organization's billing page](https://supabase.com/dashboard/org/_/billing) . ### What causes the credit balance to change?[#](https://supabase.com/docs/guides/platform/credits#what-causes-the-credit-balance-to-change) **Subscription plan downgrades:** Upon subscription downgrade, any prepaid subscription fee will be credited back to your organization for unused time in the billing cycle. As an example, if you start a Pro Plan subscription on January 1 and downgrade to the Free Plan on January 15, your organization will receive about 50% of the subscription fee as credits for the unused time between January 15 and January 31. **Credit top-ups:** You self-served a credit top-up or have signed an upfront credits deal with our growth team. Credit top-ups[#](https://supabase.com/docs/guides/platform/credits#credit-top-ups) ------------------------------------------------------------------------------------ You can top up credits at any time, with a maximum of $2000 per top-up. These credits do not expire and are non-refundable. You may want to consider this option to avoid issues with recurring payments, gain more control over how often your credit card is charged, and potentially make things easier for your accounting department. If you are interested in larger (> $2000) credit packages, [reach out](https://supabase.com/dashboard/support/new?subject=I%20would%20like%20to%20inquire%20about%20larger%20credit%20packages&category=Sales) . ### How to top up credits[#](https://supabase.com/docs/guides/platform/credits#how-to-top-up-credits) 1. On the [organization's billing page](https://supabase.com/dashboard/org/_/billing) , go to section **Credit Balance** 2. Click **Top Up** 3. Choose the amount 4. Choose a payment method or add a new payment method 5. Click **Top Up** ![Subscription upgrade modal](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fguides%2Fplatform%2Fcredit-top-up--light.png&w=2048&q=75) Credit FAQ[#](https://supabase.com/docs/guides/platform/credits#credit-faq) ---------------------------------------------------------------------------- ### Will I get an invoice for the credits purchase?[#](https://supabase.com/docs/guides/platform/credits#will-i-get-an-invoice-for-the-credits-purchase) Yes, once the payment is confirmed, you will get a matching invoice that can be accessed through your [organization's invoices page](https://supabase.com/dashboard/org/_/billing#invoices) . ### Can I transfer credits to another organization?[#](https://supabase.com/docs/guides/platform/credits#can-i-transfer-credits-to-another-organization) Yes, you can transfer credits to another organization. Submit a [support ticket](https://supabase.help/) . ### Can I get a refund of my unused credits?[#](https://supabase.com/docs/guides/platform/credits#can-i-get-a-refund-of-my-unused-credits) No, we do not provide refunds. Please refer to our [Terms of Service](https://supabase.com/terms#1-fees) . ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/platform/credits%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/platform/credits%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Manage your subscription | Supabase Docs Platform Manage your subscription ============================ * * * Manage your subscription plan[#](https://supabase.com/docs/guides/platform/manage-your-subscription#manage-your-subscription-plan) ----------------------------------------------------------------------------------------------------------------------------------- To change your subscription plan 1. On the [organization's billing page](https://supabase.com/dashboard/org/_/billing) , go to section **Subscription Plan** 2. Click **Change subscription plan** 3. On the side panel, choose a subscription plan 4. Follow the prompts ### Upgrade[#](https://supabase.com/docs/guides/platform/manage-your-subscription#upgrade) Upgrades take effect immediately. During the process, you are informed of the associated costs. ![Subscription upgrade modal](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fguides%2Fplatform%2Fupgrade-to-pro-plan-modal--light.png&w=3840&q=75) If you still have credits in your account, we will use the credits first before charging your card. ### Downgrade[#](https://supabase.com/docs/guides/platform/manage-your-subscription#downgrade) Downgrades take effect immediately. During the process, you are informed of the implications. ![Subscription downgrade modal](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fguides%2Fplatform%2Fdowngrade-to-free-plan-modal--light.png&w=3840&q=75) #### Credits upon downgrade[#](https://supabase.com/docs/guides/platform/manage-your-subscription#credits-upon-downgrade) Upon subscription downgrade, any prepaid subscription fee will be credited back to your organization for unused time in the billing cycle. These credits do not expire and will be applied to future invoices. **Example:** If you start a Pro Plan subscription on January 1 and downgrade to the Free Plan on January 15, your organization will receive about 50% of the subscription fee as credits for the unused time between January 15 and January 31. As stated in our [Terms of Service](https://supabase.com/terms#1-fees) , we do not offer refunds to the payment method on file. #### Charges on downgrade[#](https://supabase.com/docs/guides/platform/manage-your-subscription#charges-on-downgrade) When you downgrade from a paid plan to the Free Plan, you will get credits for the unused time on the paid plan. However, you will also be charged for any excessive usage in the billing cycle. The plan line item (e.g. Pro Plan) gets charged upfront, whereas all usage charges get charged in arrears, as we only know your usage by the end of the billing cycle. Excessive usage is charged whenever a billing cycle resets, so either when your monthly cycle resets, or whenever you do a plan change. If you got charged after downgrading to the Free Plan, you had excessive usage in the previous billing cycle. You can check your invoices to see what exactly you were charged for. ### Cancel subscription[#](https://supabase.com/docs/guides/platform/manage-your-subscription#cancel-subscription) To cancel your subscription, go to your [organization's billing settings](https://supabase.com/dashboard/org/_/billing) , click "Change subscription plan" and select the Free Plan. The cancellation is immediate, refer to [downgrade docs](https://supabase.com/docs/guides/platform/manage-your-subscription#downgrade) for full details. Cancellations are fully self-serve. Your Free Plan subscription will run indefinitely unless you delete the organization through your [organization's settings](https://supabase.com/dashboard/org/_/general) . Manage your payment methods[#](https://supabase.com/docs/guides/platform/manage-your-subscription#manage-your-payment-methods) ------------------------------------------------------------------------------------------------------------------------------- You can add multiple payment methods, but only one can be active at a time. ### Add a payment method[#](https://supabase.com/docs/guides/platform/manage-your-subscription#add-a-payment-method) 1. On the [organization's billing page](https://supabase.com/dashboard/org/_/billing) , go to section **Payment Methods** 2. Click **Add new card** 3. Provide your credit card details 4. Click **Add payment method** ### Delete a payment method[#](https://supabase.com/docs/guides/platform/manage-your-subscription#delete-a-payment-method) 1. On the [organization's billing page](https://supabase.com/dashboard/org/_/billing) , go to section **Payment Methods** 2. In the context menu of the payment method you want to delete, click **Delete card** 3. Click **Confirm** ### Set a payment method as active[#](https://supabase.com/docs/guides/platform/manage-your-subscription#set-a-payment-method-as-active) 1. On the [organization's billing page](https://supabase.com/dashboard/org/_/billing) , go to section **Payment Methods** 2. In the context menu of the payment method you want to delete, click **Use this card** 3. Click **Confirm** Manage your billing details[#](https://supabase.com/docs/guides/platform/manage-your-subscription#manage-your-billing-details) ------------------------------------------------------------------------------------------------------------------------------- You can update your billing email address, billing address and tax ID on the [organization's billing page](https://supabase.com/dashboard/org/_/billing) . Any changes made to your billing details will only be reflected in your upcoming invoices. Our payment provider cannot regenerate previous invoices. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/platform/manage-your-subscription%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/platform/manage-your-subscription%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Restore to a new project | Supabase Docs Platform Restore to a new project ============================ How to clone your existing Supabase project ----------------------------------------------- * * * ##### Beta Version You can clone your Supabase project by restoring your data from an existing project into a completely new one. This process creates a database-only copy and requires manual reconfiguration to fully replicate your original project. **What will be transferred?** * Database schema (tables, views, procedures) * All data and indexes * Database roles, permissions and users * Auth user data (user accounts, hashed passwords, and authentication records from the auth schema) **What needs manual reconfiguration?** * Storage objects & settings (Your S3/storage files and bucket configurations are **NOT** copied) * Edge Functions * Auth settings & API keys * Realtime settings * Database extensions and settings * Read replicas Whether you're using physical backups or Point-in-Time recovery (PITR), this feature allows you to duplicate project data with ease, perform testing safely, or recover data for analysis. Access to this feature is exclusive to users on paid plans and requires that physical backups are enabled for the source project. PITR is an additional add-on available for organizations on a paid plan with physical backups enabled. To begin, switch to the source project—the project containing the data you wish to restore—and go to the [database backups](https://supabase.com/dashboard/project/_/database/backups/restore-to-new-project) page. Select the **Restore to a New Project** tab. A list of available backups is displayed. Select the backup you want to use and click the "Restore" button. For projects with PITR enabled, use the date and time selector to specify the exact point in time from which you wish to restore data. Once you’ve made your choice, Supabase takes care of the rest. A new project is automatically created, replicating key configurations from the original, including the compute instance size, disk attributes, SSL enforcement settings, and network restrictions. The data will remain in the same region as the source project to ensure compliance with data residency requirements. The entire process is fully automated. The time required to complete the restoration can vary depending largely on the volume of data involved. If you have a large amount of data you can opt for higher performing disk attributes on the source project _before_ starting a clone operation. These disk attributes will be replicated to the new project. This incurs additional costs which will be displayed before starting. There are a few important restrictions to be aware of with the "Restore to a New Project" process: * Projects that are created through the restoration process cannot themselves be used as a source for further clones at this time. * The feature is only accessible to paid plan users with physical backups enabled, ensuring that the necessary resources and infrastructure are available for the restore process. Before starting the restoration, you’ll be presented with an overview of the costs associated with creating the new project. The new project will incur additional monthly expenses based on the mirrored resources from the source project. It’s important to review these costs carefully before proceeding. Once the restoration is complete, the new project will be available in your dashboard and will include all data, tables, schemas, and selected settings from the chosen backup source. It is recommended to thoroughly review the new project and perform any necessary tests to ensure everything has been restored as expected. New projects are completely independent of their source, and as such can be modified and used as desired. As the entire database is copied to the new project, this will include all extensions that were enabled at the source. If the source project included extensions that are configured to carry out external operations—for example pg\_net, pg\_cron, wrappers—these should be disabled once the copy process has completed to avoid any unwanted actions from taking place. Restoring to a new project is an excellent way to manage environments more effectively. You can use this feature to create staging environments for testing, experiment with changes without risk to production data, or swiftly recover from unexpected data loss scenarios. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/platform/clone-project%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/platform/clone-project%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Hardening the Data API | Supabase Docs REST API Hardening the Data API ========================== * * * Your database's auto-generated Data API exposes the `public` schema by default. You can change this to any schema in your database, or even disable the Data API completely. Any tables that are accessible through the Data API _must_ have [Row Level Security](https://supabase.com/docs/guides/database/postgres/row-level-security) enabled. Row Level Security (RLS) is enabled by default when you create tables from the Supabase Dashboard. If you create a table using the SQL editor or your own SQL client or migration runner, you_must_ enable RLS yourself. Shared responsibility[#](https://supabase.com/docs/guides/api/hardening-data-api#shared-responsibility) -------------------------------------------------------------------------------------------------------- Your application's security is your responsibility as a developer. This includes RLS, falling under the [Shared Responsibility](https://supabase.com/docs/guides/deployment/shared-responsibility-model) model. To help you: * Supabase sends daily emails warning of any tables that are exposed to the Data API which do not have RLS enabled. * Supabase provides a Security Advisor and other tools in the Supabase Dashboard to fix any issues. Private schemas[#](https://supabase.com/docs/guides/api/hardening-data-api#private-schemas) -------------------------------------------------------------------------------------------- We highly recommend creating a `private` schema for storing tables that you do not want to expose via the Data API. These tables can be accessed via Supabase Edge Functions or any other serverside tool. In this model, you should implement your security model in your serverside code. Although it's not required, we _still_ recommend enabling RLS for private tables and then connecting to your database using a Postgres role with `bypassrls` privileges. Managing the public schema[#](https://supabase.com/docs/guides/api/hardening-data-api#managing-the-public-schema) ------------------------------------------------------------------------------------------------------------------ If your `public` schema is used by other tools as a default space, you might want to lock down this schema. This helps prevent accidental exposure of data that's automatically added to `public`. There are several levels of security hardening for the Data API: * [Disabling the Data API entirely](https://supabase.com/docs/guides/api/hardening-data-api#disabling-the-data-api) . This is recommended if you _never_ need to access your database via Supabase client libraries or the REST and GraphQL endpoints. * [Exposing a custom schema](https://supabase.com/docs/guides/api/hardening-data-api#exposing-a-custom-schema-instead-of-public) instead of `public`, giving you explicit control over what is accessible. * [Automatically enabling RLS on new tables](https://supabase.com/docs/guides/api/hardening-data-api#automatically-enabling-rls-on-new-tables) using an event trigger. * [Adjusting table-level grants](https://supabase.com/docs/guides/api/hardening-data-api#table-level-grants) to control which roles can access specific tables. Disabling the Data API[#](https://supabase.com/docs/guides/api/hardening-data-api#disabling-the-data-api) ---------------------------------------------------------------------------------------------------------- You can disable the Data API entirely if you never intend to use the Supabase client libraries or the REST and GraphQL data endpoints. For example, if you only access your database via a direct connection on the server, disabling the Data API gives you the greatest layer of protection. 1. Go to [API Settings](https://supabase.com/dashboard/project/_/settings/api) in the Supabase Dashboard. 2. Under **Data API Settings**, toggle **Enable Data API** off. Exposing a custom schema instead of `public`[#](https://supabase.com/docs/guides/api/hardening-data-api#exposing-a-custom-schema-instead-of-public) ---------------------------------------------------------------------------------------------------------------------------------------------------- If you want to use the Data API but with increased security, you can expose a custom schema instead of `public`. By not using `public`, which is often used as a default space and has laxer default permissions, you get more conscious control over your exposed data. Any data, views, or functions that should be exposed need to be deliberately put within your custom schema (which we will call `api`), rather than ending up there by default. ### Step 1: Remove `public` from exposed schemas[#](https://supabase.com/docs/guides/api/hardening-data-api#step-1-remove-public-from-exposed-schemas) 1. Go to [**API Settings**](https://supabase.com/dashboard/project/_/settings/api) in the Supabase Dashboard. 2. Under **Data API Settings**, remove `public` from **Exposed schemas**. Also remove `public` from **Extra search path**. 3. Click **Save**. 4. Go to [**Database Extensions**](https://supabase.com/dashboard/project/_/database/extensions) and disable the `pg_graphql` extension. ### Step 2: Create an `api` schema and expose it[#](https://supabase.com/docs/guides/api/hardening-data-api#step-2-create-an-api-schema-and-expose-it) 1. Connect to your database. You can use `psql`, the [Supabase SQL Editor](https://supabase.com/dashboard/project/_/sql) , or the Postgres client of your choice. 2. Create a new schema named `api`: 1create schema if not exists api; 3. Grant the `anon` and `authenticated` roles usage on this schema. 1grant usage on schema api to anon, authenticated; 4. Go to [API Settings](https://supabase.com/dashboard/project/_/settings/api) in the Supabase Dashboard. 5. Under **Data API Settings**, add `api` to **Exposed schemas**. Make sure it is the first schema in the list, so that it will be searched first by default. 6. Under these new settings, `anon` and `authenticated` can execute functions defined in the `api` schema, but they have no automatic permissions on any tables. On a table-by-table basis, you can grant them permissions. For example: 1grant select on table api. to anon;2grant select, insert, update, delete on table api. to authenticated; Automatically enabling RLS on new tables[#](https://supabase.com/docs/guides/api/hardening-data-api#automatically-enabling-rls-on-new-tables) ---------------------------------------------------------------------------------------------------------------------------------------------- Tables created via the Supabase Dashboard have RLS enabled by default. However, if you or your team create tables using the SQL editor, migrations, or an external tool, RLS will not be enabled automatically. You can use an [event trigger](https://supabase.com/docs/guides/database/postgres/event-triggers#example-trigger-function---auto-enable-row-level-security) to automatically enable RLS whenever a new table is created in the `public` schema. This ensures that no table is accidentally left exposed without RLS protection. Table-level grants[#](https://supabase.com/docs/guides/api/hardening-data-api#table-level-grants) -------------------------------------------------------------------------------------------------- By default, tables in the `public` schema are granted full access (`SELECT`, `INSERT`, `UPDATE`, `DELETE`) to the `anon` and `authenticated` roles. This allows the Data API to query those tables on behalf of users. You can adjust these privileges on a per-table basis to restrict which operations each role can perform. For example, you might want to: * Allow `anon` users to only `SELECT` from a table, preventing anonymous writes. * Prevent `anon` users from accessing a table entirely, making it available only to authenticated users. * Restrict `authenticated` users to `SELECT` and `INSERT` only, preventing updates and deletes. Table-level privileges work alongside [Row Level Security](https://supabase.com/docs/guides/database/postgres/row-level-security) . Privileges control _which operations_ are possible, while RLS policies control _which rows_ are accessible. For full protection, use both: restrict privileges to limit operation types, and use RLS policies to control row-level access. ### Adjusting table-level grants via the Dashboard[#](https://supabase.com/docs/guides/api/hardening-data-api#adjusting-table-level-grants-via-the-dashboard) Adjusting table-level privileges via the Dashboard is currently in beta and will be available via gradual roll-out. 1. Go to [**Table Editor**](https://supabase.com/dashboard/project/_/editor) in the Supabase Dashboard. 2. Select the table you want to configure. 3. Click the vertical dots icon to open the table menu and select "Edit table". 4. Under **Data API Access**, click the settings icon to open **Adjust API privileges per role**. 5. For each role (`anon` and `authenticated`), select or deselect the privileges you want to grant. 6. Click **Save**. ### Adjusting table-level grants via SQL[#](https://supabase.com/docs/guides/api/hardening-data-api#adjusting-table-level-grants-via-sql) You can also adjust privileges using SQL. For example, to allow only `SELECT` access for `anon` on a table: 1-- Revoke all existing privileges2revoke all on table public.your_table from anon;34-- Grant only SELECT5grant select on table public.your_table to anon; To remove all access for `anon` from a table: 1revoke all on table public.your_table from anon; To restore full access: 1grant select, insert, update, delete on table public.your_table to anon; ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/api/hardening-data-api%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/api/hardening-data-api%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # HIPAA Projects | Supabase Docs Platform HIPAA Projects ================== * * * You can use Supabase to store and process Protected Health Information (PHI). If you want to start developing healthcare apps on Supabase, reach out to the Supabase team [here](https://forms.supabase.com/hipaa2) to sign the Business Associate Agreement (BAA). Organizations must have a signed BAA with Supabase and have the Health Insurance Portability and Accountability Act (HIPAA) add-on enabled when dealing with PHI. Configuring a HIPAA project[#](https://supabase.com/docs/guides/platform/hipaa-projects#configuring-a-hipaa-project) --------------------------------------------------------------------------------------------------------------------- When the HIPAA add-on is enabled on an organization, projects within the organization can be configured as _High Compliance_. This configuration can be found in the [General Project Settings page](https://supabase.com/dashboard/project/_/settings) of the dashboard. Once enabled, additional security checks will be run against the project to ensure the deployed configuration is compliant. These checks are performed on a continual basis and security warnings will appear in the [Security Advisor](https://supabase.com/dashboard/project/_/advisors/security) if a non-compliant setting is detected. The required project configuration is outlined in the [shared responsibility model](https://supabase.com/docs/guides/deployment/shared-responsibility-model#managing-healthcare-data) for managing healthcare data. These include: * Enabling [Point in Time Recovery](https://supabase.com/docs/guides/platform/backups#point-in-time-recovery) which requires at least a [small compute add-on](https://supabase.com/docs/guides/platform/compute-add-ons) . * Turning on [SSL Enforcement](https://supabase.com/docs/guides/platform/ssl-enforcement) . * Enabling [Network Restrictions](https://supabase.com/docs/guides/platform/network-restrictions) . Additional security checks and controls will be added as the security advisor is extended and additional security controls are made available. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/platform/hipaa-projects%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/platform/hipaa-projects%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Understanding API keys | Supabase Docs REST API Understanding API keys ========================== * * * Supabase gives you fine-grained control over which application components are allowed to access your project through API keys. API keys provide the first layer of authentication for data access. Auth then builds upon that. This chart covers the differences: | Responsibility | Question | Answer | | --- | --- | --- | | API keys | **What** is accessing the project? | Web page, mobile app, server, Edge Function... | | [Supabase Auth](https://supabase.com/docs/guides/auth) | **Who** is accessing the project? | Monica, Jian Yang, Gavin, Dinesh, Laurie, Fiona... | Overview[#](https://supabase.com/docs/guides/api/api-keys#overview) -------------------------------------------------------------------- An API key authenticates an application component to give it access to Supabase services. An application component might be a web page, a mobile app, or a server. The API key _does not_ distinguish between users, only between applications. There are 4 types of API keys that can be used with Supabase: | Type | Format | Privileges | Availability | Use | | --- | --- | --- | --- | --- | | Publishable key | `sb_publishable_...` | Low | Platform | Safe to expose online: web page, mobile or desktop app, GitHub actions, CLIs, source code. | | Secret keys | `sb_secret_...` | Elevated | Platform | **Only use in backend components of your app:** servers, already secured APIs (admin panels), [Edge Functions](https://supabase.com/docs/guides/functions)
, microservices, etc. They provide _full access_ to your project's data, bypassing [Row Level Security](https://supabase.com/docs/guides/database/postgres/row-level-security)
. | | `anon` | JWT (long lived) | Low | Platform, CLI | Exactly like the publishable key. | | `service_role` | JWT (long lived) | Elevated | Platform, CLI | Exactly like secret keys. | `anon` and `service_role` keys are based on the project's JWT secret. They are generated when your project is created and can only be changed when you rotate the JWT secret. This can cause significant issues in production applications. Use the publishable and secret keys instead. ##### Changes to API keys Supabase is changing the way keys work to improve project security and developer experience. You can [read the full announcement](https://github.com/orgs/supabase/discussions/29260) , but in the transition period, you can use both the current `anon` and `service_role` keys and the new publishable key with the form `sb_publishable_xxx` which will replace the older keys. Where to find keys[#](https://supabase.com/docs/guides/api/api-keys#where-to-find-keys) ---------------------------------------------------------------------------------------- You can find API keys in a couple of different places. In most cases, you can get the correct key from [the Project's **Connect** dialog](https://supabase.com/dashboard/project/_?showConnect=true) , but if you want a specific key, you can find all keys in [the API Keys section of a Project's Settings page](https://supabase.com/dashboard/project/_/settings/api-keys/) : * **For legacy keys**, copy the `anon` key for client-side operations and the `service_role` key for server-side operations from the **Legacy API Keys** tab. * **For new keys**, open the **API Keys** tab, if you don't have a publishable key already, click **Create new API Keys**, and copy the value from the **Publishable key** section. `anon` and publishable keys[#](https://supabase.com/docs/guides/api/api-keys#anon-and-publishable-keys) -------------------------------------------------------------------------------------------------------- The `anon` and publishable keys secure the public components of your application. Public components run in environments where it is impossible to secure any secrets. These include: * Web pages, where the key is bundled in source code. * Mobile or desktop applications, where the key is bundled inside the compiled packages or executables. * CLI, scripts, tools, or other pre-built executables. * Other publicly available APIs that return the key without prior additional authorization. These environments are always considered public because anyone can retrieve the key from the source code or build artifacts. Obfuscation can increase the difficulty, but never eliminate the possibility. (In general, obfuscation, Turing test challenges, and specialized knowledge do not count as authorization for the purpose of securing secrets.) ### Interaction with Supabase Auth[#](https://supabase.com/docs/guides/api/api-keys#interaction-with-supabase-auth) Using the `anon` or publishable key does not mean that your user is anonymous. (Thinking of both these keys as publishable rather than `anon` makes the mental model clearer.) Your application can be authenticated with the publishable key, while your user is authenticated (via Supabase Auth) with their personal JWT: | Key | User logged in via Supabase Auth | Postgres role used for RLS, etc. | | --- | --- | --- | | Publishable key | No | `anon` | | `anon` | No | `anon` | | Publishable key | Yes | `authenticated` | | `anon` | Yes | `authenticated` | ### Protection[#](https://supabase.com/docs/guides/api/api-keys#protection) These keys provide first-layer protection to your project's data, performance and bill, such as: * Providing basic Denial-of-Service protection, by requiring a minimal threshold of knowledge. * Protecting your bill by ignoring bots, scrapers, automated vulnerability scanners and other well meaning or random Internet activity. ### Security considerations[#](https://supabase.com/docs/guides/api/api-keys#security-considerations) The publishable and `anon` keys are not intended to protect from the following, since key retrieval is always possible from a public component: * Static or dynamic code analysis and reverse engineering attempts. * Use of the Network inspector in the browser. * Cross-site request forgery, cross-site scripting, phishing attacks. * Man-in-the-middle attacks. When using the publishable or `anon` key, access to your project's data is guarded by Postgres via the built-in `anon` and `authenticated` roles. For full protection make sure: * You have enabled Row Level Security on all tables. * You regularly review your Row Level Security policies for permissions granted to the `anon` and `authenticated` roles. * You do not modify the role's attributes without understanding the changes you are making. Your project's [Security Advisor](https://supabase.com/dashboard/project/_/advisors/security) constantly checks for common security problems with the built-in Postgres roles. Make sure you carefully review each finding before dismissing it. `service_role` and secret keys[#](https://supabase.com/docs/guides/api/api-keys#servicerole-and-secret-keys) ------------------------------------------------------------------------------------------------------------- Unlike the `anon` and publishable key, the `service_role` and secret keys allow elevated access to your project's data. It is meant to be used only in secure, developer-controlled components of your application, such as: * Servers that implement prior authorization themselves, such as Edge Functions, microservices, traditional or specialized web servers. * Periodic jobs, queue processors, topic subscribers. * Admin and back-office tools, with prior authorization checks only. * Data processing pipelines, such as for analytics, reports, backups, or database synchronization. Never expose your `service_role` and secret keys publicly. Your data is at risk. **Do not:** * Add in web pages, public documents, source code, bundle in executables or packages for mobile, desktop or CLI apps. * Send over chat applications, email or SMS to your peers. * Never use in a browser, even on `localhost`! * Do not pass in URLs or query params, as these are often logged. * Be careful passing them in request headers without prior log sanitization. * Take extra care logging even potentially **invalid API keys**. Simple typos might reveal the real key in the future. * Reveal, copy, use or manipulate on hardware devices without full disk encryption and which you do not directly own or control (such as public computers, friend's laptop, etc.) Ensure you handle them with care and using [secure coding practices](https://owasp.org/www-project-secure-coding-practices-quick-reference-guide/stable-en/) . Secret keys and the `service_role` JWT-based API key authorize access to your project's data via the built-in `service_role` Postgres role. By design, this role has full access to your project's data. It also uses the [`BYPASSRLS` attribute](https://www.postgresql.org/docs/current/ddl-rowsecurity.html#:~:text=BYPASSRLS) , skipping any and all Row Level Security policies you attach. The secret key is an improvement over the old JWT-based `service_role` key, and we recommend using it where possible. It adds more checks to prevent misuse, specifically: * You cannot use a secret key in the browser (matches on the `User-Agent` header) and it will always reply with HTTP 401 Unauthorized. * You don't need to have any secret keys if you are not using them. ### Best practices for handling secret keys[#](https://supabase.com/docs/guides/api/api-keys#best-practices-for-handling-secret-keys) Below are some starting guidelines on how to securely work with secret keys: * Always work with secret keys on computers you fully own or control. * Use secure & encrypted send tools to share API keys with others (often provided by good password managers), but prefer the [API Keys](https://supabase.com/dashboard/project/_/settings/api-keys) dashboard instead. * Prefer encrypting them when stored in files or environment variables. * Do not add in source control, especially for CI scripts and tools. Prefer using the tool's native secrets capability instead. * Prefer using a separate secret key for each separate backend component of your application, so that if one is found to be vulnerable or to have leaked the key you will only need to change it and not all. * Even though a secret key will always return HTTP 401 Unauthorized error when used in a browser, it does not mean that attackers will not use it with other tools. Delete immediately! * If you must include them in logs, log the first few random characters (but never more than 6). * If you wish to log or store which valid API key was used, store it as a SHA256 hash. ### What to do if a secret key or `service_role` has been leaked or compromised?[#](https://supabase.com/docs/guides/api/api-keys#what-to-do-if-a-secret-key-or-servicerole-has-been-leaked-or-compromised) Don't rush if this has happened, or you are suspecting it has. Make sure you have fully considered the situation and have remediated the root cause of the suspicion or vulnerability **first**. Consider using the [OWASP Risk Rating Methodology](https://owasp.org/www-community/OWASP_Risk_Rating_Methodology) as an easy way to identify the severity of the incident and to plan your next steps. Rotating a secret key (`sb_secret_...`) is easy and painless. Use the [API Keys](https://supabase.com/dashboard/project/_/settings/api-keys) dashboard to create a new secret API key, then replace it with the compromised key. Once all components are using the new key, delete the compromised one. **Deleting a secret key is irreversible and once done it will be gone forever.** If you are still using the JWT-based `service_role` key, replace the `service_role` key with a new secret key instead. Follow the guide from above as if you are rotating an existing secret key. If you believe this is not possible for your implementation, [contact Support](https://supabase.com/dashboard/support/new) . Known limitations and compatibility differences[#](https://supabase.com/docs/guides/api/api-keys#known-limitations-and-compatibility-differences) -------------------------------------------------------------------------------------------------------------------------------------------------- As the publishable and secret keys are no longer JWT-based, there are some known limitations and compatibility differences that you may need to plan for: * You cannot send a publishable or secret key in the `Authorization: Bearer ...` header, except if the value exactly equals the `apikey` header. In this case, your request will be forwarded down to your project's database, but will be rejected as the value is not a JWT. * Edge Functions **only support JWT verification** via the `anon` and `service_role` JWT-based API keys. You will need to use the `--no-verify-jwt` option when using publishable and secret keys. The Supabase platform does not verify the `apikey` header when using Edge Functions in this way. Implement your own `apikey`\-header authorization logic inside the Edge Function code itself. * Public Realtime connections are limited to 24 hours in duration, unless the connection is upgraded and further maintained with user-level authentication via Supabase Auth or a supported Third-Party Auth provider. Frequently asked questions[#](https://supabase.com/docs/guides/api/api-keys#frequently-asked-questions) -------------------------------------------------------------------------------------------------------- ### I am using JWT-based `anon` key in a mobile, desktop, or CLI application and need to rotate my `service_role` JWT secret?[#](https://supabase.com/docs/guides/api/api-keys#i-am-using-jwt-based-anon-key-in-a-mobile-desktop-or-cli-application-and-need-to-rotate-my-servicerole-jwt-secret) If the JWT secret is secure, substitute the `service_role` JWT-based key with a new secret key which you can create in the [API Keys](https://supabase.com/dashboard/project/_/settings/api-keys) dashboard. This will prevent downtime for your application. ### Can I still use my old `anon` and `service-role` API keys after enabling the publishable and secret keys?[#](https://supabase.com/docs/guides/api/api-keys#can-i-still-use-my-old-anon-and-service-role-api-keys-after-enabling-the-publishable-and-secret-keys) Yes. This allows you to transition between the API keys with zero downtime by gradually swapping your clients while both sets of keys are active. See the next question for how to deactivate your keys once all your clients are switched over. ### How do I deactivate the `anon` and `service_role` JWT-based API keys after moving to publishable and secret keys?[#](https://supabase.com/docs/guides/api/api-keys#how-do-i-deactivate-the-anon-and-servicerole-jwt-based-api-keys-after-moving-to-publishable-and-secret-keys) You can do this in the [API Keys](https://supabase.com/dashboard/project/_/settings/api-keys) dashboard. To prevent downtime in your application's components, use the last used indicators on the page to confirm that these are no longer used before deactivating. You can re-activate them should you need to. ### Why are `anon` and `service_role` JWT-based keys no longer recommended?[#](https://supabase.com/docs/guides/api/api-keys#why-are-anon-and-servicerole-jwt-based-keys-no-longer-recommended) Since the start of Supabase, the JWT-based `anon` and `service_role` keys were the right trade-off against simplicity and relative security for your project. Unfortunately they pose some real challenges in live applications, especially around rotation and security best practices. The main reasons for preferring the publishable and secret keys (`sb_publishable_...` and `sb_secret_...`) are: * Tight coupling between the JWT secret (which itself can be compromised, if you mint your own JWTs), the `anon` (low privilege) and `service_role` (high privilege) and `authenticated` (issued by Supabase Auth) Postgres roles. * Inability to independently rotate each aspect of the keys, without downtime. * Inability to roll-back an unnecessary or problematic JWT secret rotation. * Publishing new versions of mobile applications can take days and often weeks in the app review phase with Apple's App Store and Google's Play Store. A forced rotation can cause weeks of downtime for mobile app users. * Users may continue using desktop, CLI and mobile apps with very old versions, making rotation impossible without a forced version upgrade. * JWTs had 10-year expiry duration, giving malicious actors more to work with. * JWTs were self-referential and full of redundant information not necessary for achieving their primary purpose. * JWTs are large, hard to parse, verify, and manipulate -- leading to insecure logging or bad security practices. * They were signed with a symmetric JWT secret. ### Why is there no publishable or secret keys in the CLI / self-hosting?[#](https://supabase.com/docs/guides/api/api-keys#why-is-there-no-publishable-or-secret-keys-in-the-cli--self-hosting) Publishable and secret keys are only available on the Supabase hosted platform. They are managed by our API Gateway component, which does not currently have a CLI equivalent. We are looking into providing similar but limited in scope support for publishable or secret keys in the future. For now you can only use the `anon` and `service_role` JWT-based keys there. For advanced users, see the following question on how these keys are implemented on the hosted platform for an idea on how to provide similar functionality for yourself. ### How are publishable and secret keys implemented on the hosted platform?[#](https://supabase.com/docs/guides/api/api-keys#how-are-publishable-and-secret-keys-implemented-on-the-hosted-platform) When your applications use the Supabase APIs they go through a component called the API Gateway on the Supabase hosted platform. This provides us (and therefore you) with the following features: * Observability and logging. * Performance and request routing (such as to read-replicas). * Security, for blocking malicious patterns or behavior on a global scale. This API Gateway component is able to verify the API key (sent in the `apikey` request header, or for WebSocket in a query param) against your project's publishable and secret key list. If the match is found, it mints a temporary, short-lived JWT that is then forwarded down to your project's servers. It may be possible to replicate similar behavior if you self-host by using programmable proxies such as [Kong](https://konghq.com/) , [Envoy](https://www.envoyproxy.io/) , [NGINX](https://nginx.org/) or similar. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/api/api-keys%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/api/api-keys%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Multi-factor Authentication | Supabase Docs Platform Multi-factor Authentication =============================== Enable multi-factor authentication (MFA) to keep your account secure. ------------------------------------------------------------------------- * * * This guide is for adding MFA to your Supabase user account. If you want to enable MFA for users in your Supabase project, refer to [**this guide**](https://supabase.com/docs/guides/auth/auth-mfa) instead. Multi-factor authentication (MFA) adds an additional layer of security to your user account, by requiring a second factor to verify your user identity. Supabase allows users to enable MFA on their account and set it as a requirement for subsequent logins. Supported authentication factors[#](https://supabase.com/docs/guides/platform/multi-factor-authentication#supported-authentication-factors) -------------------------------------------------------------------------------------------------------------------------------------------- Currently, Supabase supports adding a unique time-based one-time password (TOTP) to your user account as an additional security factor. You can manage your TOTP factor using apps such as 1Password, Authy, Google Authenticator or Apple's Keychain. Enable MFA[#](https://supabase.com/docs/guides/platform/multi-factor-authentication#enable-mfa) ------------------------------------------------------------------------------------------------ You can enable MFA for your user account under your [Supabase account settings](https://supabase.com/dashboard/account/security) . Enabling MFA will result in all other user sessions to be automatically logged out and forced to sign-in again with MFA. Supabase does not return recovery codes. Instead, we recommend that you register a backup TOTP factor to use in an event that you lose access to your primary TOTP factor. Make sure you use a different device and app, or store the secret in a secure location different than your primary one. For security reasons, we will not be able to restore access to your account if you lose all your two-factor authentication credentials. Do register a backup factor if necessary. Login with MFA[#](https://supabase.com/docs/guides/platform/multi-factor-authentication#login-with-mfa) -------------------------------------------------------------------------------------------------------- Once you've enabled MFA for your Supabase user account, you will be prompted to enter your second factor challenge code as seen in your preferred TOTP app. If you are an organization owner and on the Pro, Team or Enterprise plan, you can enforce that all organization members [must have MFA enabled](https://supabase.com/docs/guides/platform/mfa/org-mfa-enforcement) . Disable MFA[#](https://supabase.com/docs/guides/platform/multi-factor-authentication#disable-mfa) -------------------------------------------------------------------------------------------------- You can disable MFA for your user account under your [Supabase account settings](https://supabase.com/dashboard/account/security) . On subsequent login attempts, you will not be prompted to enter an MFA code. We strongly recommend that you do not disable MFA to avoid unauthorized access to your user account. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/platform/multi-factor-authentication%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/platform/multi-factor-authentication%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Get set up for billing | Supabase Docs Platform Get set up for billing ========================== * * * Correct billing settings are essential for ensuring successful payment processing and uninterrupted services. Additionally, it's important to configure all invoicing-related data early, as this information cannot be changed once an invoice is issued. Review these key points to ensure everything is set up correctly from the start. Payments[#](https://supabase.com/docs/guides/platform/get-set-up-for-billing#payments) --------------------------------------------------------------------------------------- ### Ensuring valid credit card details[#](https://supabase.com/docs/guides/platform/get-set-up-for-billing#ensuring-valid-credit-card-details) Paid plans require a credit card to be on file. Ensure the correct credit card is set as active and * has not expired * has sufficient funds * has a sufficient transaction limit For more information on managing payment methods, see [Manage your payment methods](https://supabase.com/docs/guides/platform/manage-your-subscription#manage-your-payment-methods) . ### Alternatives to monthly charges[#](https://supabase.com/docs/guides/platform/get-set-up-for-billing#alternatives-to-monthly-charges) Instead of having your credit card charged every month, you can make an upfront payment by topping up your credit balance. You may want to consider this option to avoid issues with recurring payments, gain more control over how often your credit card is charged, and potentially make things easier for your accounting department. For more information on credits and credit top-ups, see the [Credits page](https://supabase.com/docs/guides/platform/credits) . Billing details[#](https://supabase.com/docs/guides/platform/get-set-up-for-billing#billing-details) ----------------------------------------------------------------------------------------------------- Billing details cannot be changed once an invoice is issued, so it's crucial to configure them correctly from the start. You can update your billing email address, billing address and tax ID on the [organization's billing page](https://supabase.com/dashboard/org/_/billing) . ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/platform/get-set-up-for-billing%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/platform/get-set-up-for-billing%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Self-Hosting | Supabase Docs Self-Hosting Self-Hosting ================ Install and run your own Supabase on your computer, server, or cloud infrastructure. ---------------------------------------------------------------------------------------- * * * Get started[#](https://supabase.com/docs/guides/self-hosting#get-started) -------------------------------------------------------------------------- The fastest and recommended way to self-host Supabase is using Docker. [![[object Object]](https://supabase.com/docs/img/icons/docker-light.svg)\ \ Docker\ \ Official\ \ Deploy Supabase within your own infrastructure using Docker Compose.](https://supabase.com/docs/guides/self-hosting/docker) Community-driven projects[#](https://supabase.com/docs/guides/self-hosting#community-driven-projects) ------------------------------------------------------------------------------------------------------ There are several other options to deploy Supabase. If you're interested in helping these projects, visit our [Community](https://supabase.com/contribute) page. [Kubernetes\ \ Helm charts to deploy a Supabase on Kubernetes.](https://github.com/supabase-community/supabase-kubernetes) [Traefik\ \ A self-hosted Supabase setup with Traefik as a reverse proxy.](https://github.com/supabase-community/supabase-traefik) About self-hosting[#](https://supabase.com/docs/guides/self-hosting#about-self-hosting) ---------------------------------------------------------------------------------------- Self-hosting is a good fit if you need full control over your data, have compliance requirements that prevent using managed services, or want to run Supabase in an isolated environment. ### How self-hosted Supabase differs[#](https://supabase.com/docs/guides/self-hosting#how-self-hosted-supabase-differs) Self-hosted Supabase is different from: * **Supabase CLI** (local development), which is intended for development and testing only. * **Managed Supabase** platform, which is fully hosted and operated by Supabase. ### Telemetry[#](https://supabase.com/docs/guides/self-hosting#telemetry) Self-hosted Supabase (Docker) does not phone home or collect any telemetry. The **Supabase CLI** is a [separate tool](https://supabase.com/docs/guides/local-development/cli/getting-started) from self-hosted Supabase and collects usage telemetry to help improve the developer experience. You can opt out by running `supabase telemetry disable` or setting `SUPABASE_TELEMETRY_DISABLED=1`. See [CLI telemetry](https://supabase.com/docs/guides/local-development/cli/getting-started#telemetry) for other opt-out methods. ### Your responsibilities when self-hosting[#](https://supabase.com/docs/guides/self-hosting#your-responsibilities-when-self-hosting) When you self-host, **you are responsible for**: * Server provisioning and maintenance * Security hardening and keeping OS and services updated * Maintaining the Postgres database * Backups and disaster recovery * Monitoring and uptime Support and community[#](https://supabase.com/docs/guides/self-hosting#support-and-community) ---------------------------------------------------------------------------------------------- Self-hosted Supabase is community-supported. For resolving common issues: * [GitHub Discussions](https://github.com/orgs/supabase/discussions?discussions_q=is%3Aopen+label%3Aself-hosted) - Questions, feature requests, and workarounds * [GitHub Issues](https://github.com/supabase/supabase/issues?q=is%3Aissue%20state%3Aopen%20label%3Aself-hosted) - Known issues Get help and connect with other users: * [Discord](https://discord.supabase.com/) - Real-time chat and community support * [Reddit](https://www.reddit.com/r/Supabase/) - Official Supabase subreddit Share your self-hosting experience: * [GitHub Discussions](https://github.com/orgs/supabase/discussions/39820) - "Self-hosting: What's working (and what's not)?" ### Enterprise self-hosting[#](https://supabase.com/docs/guides/self-hosting#enterprise-self-hosting) If you're an enterprise using self-hosted Supabase, we'd love to hear from you. Reach out to our [Growth Team](https://forms.supabase.com/enterprise) to discuss your use case, share feedback, or explore design partnership opportunities. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/self-hosting%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/self-hosting%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Sentry integration | Supabase Docs Telemetry Sentry integration ====================== Integrate Sentry to monitor errors from a Supabase client ------------------------------------------------------------- * * * You can use [Sentry](https://sentry.io/welcome/) to monitor errors thrown from a Supabase JavaScript client. Install the [Supabase Sentry integration](https://github.com/supabase-community/sentry-integration-js) to get started. The Sentry integration supports browser, Node, and edge environments. Installation[#](https://supabase.com/docs/guides/telemetry/sentry-monitoring#installation) ------------------------------------------------------------------------------------------- Install the Sentry integration using your package manager: npmyarnpnpm 1npm install @supabase/sentry-js-integration Use[#](https://supabase.com/docs/guides/telemetry/sentry-monitoring#use) ------------------------------------------------------------------------- If you are using Sentry JavaScript SDK v7, reference [`supabase-community/sentry-integration-js` repository](https://github.com/supabase-community/sentry-integration-js/blob/master/README-v7.md) instead. To use the Supabase Sentry integration, add it to your `integrations` list when initializing your Sentry client. You can supply either the Supabase Client constructor or an already-initiated instance of a Supabase Client. With constructorWith instance 1import * as Sentry from '@sentry/browser'2import { SupabaseClient } from '@supabase/supabase-js'3import { supabaseIntegration } from '@supabase/sentry-js-integration'45Sentry.init({6 dsn: SENTRY_DSN,7 integrations: [8 supabaseIntegration(SupabaseClient, Sentry, {9 tracing: true,10 breadcrumbs: true,11 errors: true,12 }),13 ],14}) All available configuration options are available in our [`supabase-community/sentry-integration-js` repository](https://github.com/supabase-community/sentry-integration-js/blob/master/README.md#options) . Deduplicating spans[#](https://supabase.com/docs/guides/telemetry/sentry-monitoring#deduplicating-spans) --------------------------------------------------------------------------------------------------------- If you're already monitoring HTTP errors in Sentry, for example with the HTTP, Fetch, or Undici integrations, you will get duplicate spans for Supabase calls. You can deduplicate the spans by skipping them in your other integration: 1import * as Sentry from '@sentry/browser'2import { SupabaseClient } from '@supabase/supabase-js'3import { supabaseIntegration } from '@supabase/sentry-js-integration'45Sentry.init({6 dsn: SENTRY_DSN,7 integrations: [8 supabaseIntegration(SupabaseClient, Sentry, {9 tracing: true,10 breadcrumbs: true,11 errors: true,12 }),1314 // @sentry/browser15 Sentry.browserTracingIntegration({16 shouldCreateSpanForRequest: (url) => {17 return !url.startsWith(`${SUPABASE_URL}/rest`)18 },19 }),2021 // or @sentry/node22 Sentry.httpIntegration({23 tracing: {24 ignoreOutgoingRequests: (url) => {25 return url.startsWith(`${SUPABASE_URL}/rest`)26 },27 },28 }),2930 // or @sentry/node with Fetch support31 Sentry.nativeNodeFetchIntegration({32 ignoreOutgoingRequests: (url) => {33 return url.startsWith(`${SUPABASE_URL}/rest`)34 },35 }),3637 // or @sentry/WinterCGFetch for Next.js Proxy & Edge Functions38 Sentry.winterCGFetchIntegration({39 breadcrumbs: true,40 shouldCreateSpanForRequest: (url) => {41 return !url.startsWith(`${SUPABASE_URL}/rest`)42 },43 }),44 ],45}) Example Next.js configuration[#](https://supabase.com/docs/guides/telemetry/sentry-monitoring#example-nextjs-configuration) ---------------------------------------------------------------------------------------------------------------------------- See this example for a setup with Next.js to cover browser, server, and edge environments. First, run through the [Sentry Next.js wizard](https://docs.sentry.io/platforms/javascript/guides/nextjs/#install) to generate the base Next.js configuration. Then add the Supabase Sentry Integration to all your `Sentry.init` calls with the appropriate filters. BrowserServerProxy & EdgeInstrumentation 1import * as Sentry from '@sentry/nextjs'2import { SupabaseClient } from '@supabase/supabase-js'3import { supabaseIntegration } from '@supabase/sentry-js-integration'45Sentry.init({6 dsn: SENTRY_DSN,7 integrations: [8 supabaseIntegration(SupabaseClient, Sentry, {9 tracing: true,10 breadcrumbs: true,11 errors: true,12 }),13 Sentry.browserTracingIntegration({14 shouldCreateSpanForRequest: (url) => {15 return !url.startsWith(`${process.env.NEXT_PUBLIC_SUPABASE_URL}/rest`)16 },17 }),18 ],1920 // Adjust this value in production, or use tracesSampler for greater control21 tracesSampleRate: 1,2223 // Setting this option to true will print useful information to the console while you're setting up Sentry.24 debug: true,25}) Afterwards, build your application (`npm run build`) and start it locally (`npm run start`). You will now see the transactions being logged in the terminal when making supabase-js requests. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/telemetry/sentry-monitoring%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/telemetry/sentry-monitoring%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Maturity Model | Supabase Docs Home Maturity Model ================== * * * Supabase is great for building something very fast _and_ for scaling up. However, it's important to note that as your application matures and your team expands, the practices you use for managing an application in production should not be the same as the practices you used for prototyping. Prototyping[#](https://supabase.com/docs/guides/deployment/maturity-model#prototyping) --------------------------------------------------------------------------------------- The Dashboard is a quick and easy tool for building applications while you are prototyping. That said, we strongly recommend using [Migrations](https://supabase.com/docs/guides/deployment/database-migrations) to manage your database changes. You can use our CLI to [capture any changes](https://supabase.com/docs/reference/cli/supabase-db-diff) you have made on the Dashboard so that you can commit them a version control system, like git. Collaborating[#](https://supabase.com/docs/guides/deployment/maturity-model#collaborating) ------------------------------------------------------------------------------------------- As soon as you start collaborating with team members, all project changes should be in version control. At this point we strongly recommend moving away from using the Dashboard for schema changes. Use migrations to manage your database, and check them into your version control system to track every change. Resources: * [Database migrations](https://supabase.com/docs/guides/deployment/database-migrations) * [Managing access on the Dashboard](https://supabase.com/docs/guides/platform/access-control) * [PGAudit for Postgres](https://supabase.com/docs/guides/database/extensions/pgaudit) In production[#](https://supabase.com/docs/guides/deployment/maturity-model#in-production) ------------------------------------------------------------------------------------------- Once your application is live, you should never change your database using the Dashboard - everything should be done with [Migrations](https://supabase.com/docs/guides/cli/managing-environments#create-a-new-migration) . Some other important things to consider at this point include: * The Dashboard has various [access levels](https://supabase.com/docs/guides/platform/access-control) that can prevent changes being made via the UI. * Design a [safe workflow](https://supabase.com/docs/guides/platform/shared-responsibility-model#you-decide-your-own-workflow) for managing your database. We strongly recommend running [multiple environments](https://supabase.com/docs/guides/cli/managing-environments) as part of your development workflow (`local` -> `staging` -> `prod`). * Do not share any production passwords with your team, _especially_ your `postgres` password. All changes should be made via version-controlled migrations which run via a bastion host or a CI platform (like [GitHub Actions](https://supabase.com/docs/guides/cli/managing-environments#configure-github-actions) . If you use GitHub Actions, use [approval workflows](https://docs.github.com/en/actions/managing-workflow-runs/reviewing-deployments) to prevent any migrations being run accidentally. * Restrict production access to your database using [Network Restrictions](https://supabase.com/docs/guides/platform/network-restrictions) . * As your database to grows, we strongly recommend moving to [Point-in-Time Recovery](https://supabase.com/docs/guides/platform/backups#point-in-time-recovery) . This is safer and has less impact on your database performance during maintenance windows. * Read the [Production Checklist](https://supabase.com/docs/guides/platform/going-into-prod) and familiarize your team with the [Shared Responsibilities](https://supabase.com/docs/guides/platform/shared-responsibility-model) between your organization and Supabase. Resources: * [Database migrations](https://supabase.com/docs/guides/deployment/database-migrations) * [Managing access on the Dashboard](https://supabase.com/docs/guides/platform/access-control) * [PGAudit for Postgres](https://supabase.com/docs/guides/database/extensions/pgaudit) * [Managing environments](https://supabase.com/docs/guides/cli/managing-environments) Enterprise[#](https://supabase.com/docs/guides/deployment/maturity-model#enterprise) ------------------------------------------------------------------------------------- For a more secure setup, consider running your workload across several organizations. It's a common pattern to have a Production organization which is restricted to only those team members who are qualified to have direct access to production databases. Reach out to [growth](https://forms.supabase.com/enterprise) if you need help designing a secure development workflow for your organization. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/deployment/maturity-model%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/deployment/maturity-model%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Project Transfers | Supabase Docs Platform Project Transfers ===================== * * * You can freely transfer projects between different organizations. Head to your [projects' general settings](https://supabase.com/dashboard/project/_/settings/general) to initiate a project transfer. ![Project Transfer: General Settings](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fguides%2Fplatform%2Fproject-transfer-overview--light.png&w=1920&q=75) ![Project Transfer: Confirmation Modal](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fguides%2Fplatform%2Fproject-transfer-modal--light.png&w=1920&q=75) Source organization - the organization the project currently belongs to Target organization - the organization you want to move the project to Pre-Requirements[#](https://supabase.com/docs/guides/platform/project-transfer#pre-requirements) ------------------------------------------------------------------------------------------------- * You need to be the owner of the source organization. * You need to be at least a member of the target organization you want to move the project to. * No active GitHub integration connection * No project-scoped roles pointing to the project (Team/Enterprise plan) * No log drains configured Usage-billing and project add-ons[#](https://supabase.com/docs/guides/platform/project-transfer#usage-billing-and-project-add-ons) ----------------------------------------------------------------------------------------------------------------------------------- For usage metrics such as disk size, egress or image transformations and project add-ons such as [Compute Add-On](https://supabase.com/docs/guides/platform/compute-add-ons) , [Point-In-Time-Recovery](https://supabase.com/docs/guides/platform/backups#point-in-time-recovery) , [IPv4](https://supabase.com/docs/guides/platform/ipv4-address) , [Log Drains](https://supabase.com/docs/guides/platform/log-drains) , [Advanced MFA](https://supabase.com/docs/guides/auth/auth-mfa/phone) or a [Custom Domain](https://supabase.com/docs/guides/platform/custom-domains) , the source organization will still be charged for the usage up until the transfer. The charges will be added to the invoice when the billing cycle resets. The target organization will be charged at the end of the billing cycle for usage after the project transfer. Things to watch out for[#](https://supabase.com/docs/guides/platform/project-transfer#things-to-watch-out-for) --------------------------------------------------------------------------------------------------------------- * Transferring a project might come with a short 1-2 minute downtime if you're moving a project from a paid to a Free Plan. * You could lose access to certain project features depending on the plan of the target organization, i.e. moving a project from a Pro Plan to a Free Plan. * When moving your project to a Free Plan, we also ensure you’re not exceeding your two free project limit. In these cases, it is best to upgrade your target organization to Pro Plan first. * You could have less rights on the project depending on your role in the target organization, i.e. you were an Owner in the previous organization and only have a Read-Only role in the target organization. Transfer to a different region[#](https://supabase.com/docs/guides/platform/project-transfer#transfer-to-a-different-region) ----------------------------------------------------------------------------------------------------------------------------- Note that project transfers are only transferring your projects across an organization and cannot be used to transfer between different regions. To move your project to a different region, see [migrating your project](https://supabase.com/docs/guides/platform/migrating-within-supabase) . ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/platform/project-transfer%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/platform/project-transfer%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Converting SQL to JavaScript API | Supabase Docs REST API Converting SQL to JavaScript API ==================================== * * * Many common SQL queries can be written using the JavaScript API, provided by the SDK to wrap Data API calls. Below are a few examples of conversions between SQL and JavaScript patterns. Select statement with basic clauses[#](https://supabase.com/docs/guides/api/sql-to-api#select-statement-with-basic-clauses) ---------------------------------------------------------------------------------------------------------------------------- Select a set of columns from a single table with where, order by, and limit clauses. 1select first_name, last_name, team_id, age2from players3where age between 20 and 24 and team_id != 'STL'4order by last_name, first_name desc5limit 20; 1const { data, error } = await supabase2 .from('players')3 .select('first_name,last_name,team_id,age')4 .gte('age', 20)5 .lte('age', 24)6 .not('team_id', 'eq', 'STL')7 .order('last_name', { ascending: true }) // or just .order('last_name')8 .order('first_name', { ascending: false })9 .limit(20) Select statement with complex Boolean logic clause[#](https://supabase.com/docs/guides/api/sql-to-api#select-statement-with-complex-boolean-logic-clause) ---------------------------------------------------------------------------------------------------------------------------------------------------------- Select all columns from a single table with a complex where clause: OR AND OR 1select *2from players3where ((team_id = 'CHN' or team_id is null) and (age > 35 or age is null)); 1const { data, error } = await supabase2 .from('players')3 .select() // or .select('*')4 .or('team_id.eq.CHN,team_id.is.null')5 .or('age.gt.35,age.is.null') // additional filters imply "AND" Select all columns from a single table with a complex where clause: AND OR AND 1select *2from players3where ((team_id = 'CHN' and age > 35) or (team_id != 'CHN' and age is not null)); 1const { data, error } = await supabase2 .from('players')3 .select() // or .select('*')4 .or('and(team_id.eq.CHN,age.gt.35),and(team_id.neq.CHN,.not.age.is.null)') Resources[#](https://supabase.com/docs/guides/api/sql-to-api#resources) ------------------------------------------------------------------------ * [Supabase - Get started for free](https://supabase.com/) * [PostgREST Operators](https://postgrest.org/en/stable/api.html#operators) * [Supabase API: JavaScript select](https://supabase.com/docs/reference/javascript/select) * [Supabase API: JavaScript modifiers](https://supabase.com/docs/reference/javascript/using-modifiers) * [Supabase API: JavaScript filters](https://supabase.com/docs/reference/javascript/using-filters) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/api/sql-to-api%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/api/sql-to-api%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # PrivateLink | Supabase Docs Platform PrivateLink =============== * * * PrivateLink is currently in beta and available only to Team and Enterprise customers. Contact support if you would like to create a PrivateLink connection for a read-only replica. PrivateLink provides enterprise-grade private network connectivity between your AWS VPC and your Supabase database using AWS VPC Lattice. This eliminates exposure to the public internet by creating a secure, private connection that keeps your database traffic within the AWS network backbone. By enabling PrivateLink, database connections never traverse the public internet, enabling the disablement of public facing connectivity and providing an additional layer of security and compliance for sensitive workloads. This infrastructure-level security feature helps organizations meet strict data governance requirements and reduces potential attack vectors. How PrivateLink works[#](https://supabase.com/docs/guides/platform/privatelink#how-privatelink-works) ------------------------------------------------------------------------------------------------------ Supabase PrivateLink is an organisation level configuration. It works by sharing a [VPC Lattice Resource Configuration](https://docs.aws.amazon.com/vpc-lattice/latest/ug/resource-configuration.html) to any number of AWS Accounts for each of your Supabase projects. Connectivity can be achieved by either associating the Resource Configuration to a PrivateLink endpoint, or a [VPC Lattice Service Network](https://docs.aws.amazon.com/vpc-lattice/latest/ug/service-networks.html) . This means: * Database traffic flows through private AWS infrastructure only * Connection latency is typically reduced compared to public internet routing * Network isolation provides enhanced security posture * Attack surface is minimized by eliminating public exposure The connection architecture changes from public internet routing to a dedicated private path through AWS's secure network backbone. Supabase PrivateLink is currently just for direct database and PgBouncer connections only. It does not support other Supabase services like API, Storage, Auth, or Realtime. These services will continue to operate over public internet connections. Requirements[#](https://supabase.com/docs/guides/platform/privatelink#requirements) ------------------------------------------------------------------------------------ To use PrivateLink with your Supabase project: * Team or Enterprise Supabase subscription * AWS VPC in the same region as your Supabase project * Appropriate permissions to accept Resource Shares, and create and manage endpoints Getting started[#](https://supabase.com/docs/guides/platform/privatelink#getting-started) ------------------------------------------------------------------------------------------ #### Step 1: Add AWS account[#](https://supabase.com/docs/guides/platform/privatelink#step-1-add-aws-account) Navigate to your project's Integrations section to set up PrivateLink: 1. Go to your Supabase project dashboard 2. Navigate to [**Settings** > **Integrations**](https://supabase.com/dashboard/project/_/settings/integrations) 3. Find the **AWS PrivateLink** section 4. Click **Add Account** 5. Enter your AWS Account ID 6. Provide a description for the account (recommended) 7. Click **Add Account** to submit After submission, Supabase creates a VPC Lattice Resource Configuration for your project and sends an AWS Resource Share to the specified AWS Account ID. This process may take a few moments. Once complete, the account will show a "Ready" status, indicating that the resource share has been sent to your AWS account and is ready to be accepted. #### Step 2: Accept resource share[#](https://supabase.com/docs/guides/platform/privatelink#step-2-accept-resource-share) Supabase will send you an AWS Resource Share containing the VPC Lattice Resource Configurations for your projects. To accept this share: 1. Login to your AWS Management Console, ensure you are in the AWS region where your Supabase project is located 2. Navigate to the AWS Resource Access Manager (RAM) console 3. Go to [Shared with me > Resource shares](https://console.aws.amazon.com/ram/home#SharedResourceShares) 4. Locate the resource share from Supabase. * The resource share has the format `sspl-[project_ref]-[random alphanumeric string]` 5. Click on the resource share name to view details. Review the list of resource shares - it should only include resources of type vpc-lattice:ResourceConfiguration. 6. Click **Accept resource share** 7. Confirm the acceptance in the dialog box After accepting, you'll see the resource configurations appear in your [Shared with me > Shared resources](https://console.aws.amazon.com/ram/home#SharedResources) section of the RAM console and the [PrivateLink and Lattice > Resource configurations](https://console.aws.amazon.com/vpcconsole/home#ResourceConfigs) section of the VPC console. #### Step 3: Configure security groups[#](https://supabase.com/docs/guides/platform/privatelink#step-3-configure-security-groups) Ensure your security groups allow traffic on the appropriate ports: 1. Navigate to the [VPC console > Security Groups](https://console.aws.amazon.com/vpcconsole/home#SecurityGroups:) 2. Create a new security group for the endpoint or service network by clicking [Create security group](https://console.aws.amazon.com/vpcconsole/home#CreateSecurityGroup:) 3. Give your security group a descriptive name and select the appropriate VPC 4. Add an inbound rule for: * Type: Postgres (TCP, port 5432) * Destination that is appropriate for your network. i.e. the subnet of your VPC or security group of your application instances 5. Finish creating the security group by clicking **Create security group** #### Step 4: Create connection[#](https://supabase.com/docs/guides/platform/privatelink#step-4-create-connection) In your AWS account, you have two options to establish connectivity: ##### Option A: Create a PrivateLink endpoint 1. Navigate to the VPC console in your AWS account 2. Go to [Endpoints](https://console.aws.amazon.com/vpcconsole/home#Endpoints:) in the left sidebar 3. Click [Create endpoint](https://console.aws.amazon.com/vpcconsole/home#CreateVpcEndpoint:) 4. Give your endpoint a name (e.g. `supabase-privatelink-[project name]`) 5. Under Type, select **Resources** 6. In the **Resource configurations** section select the appropriate resource configuration * The resource configuration name will be in the format `[organisation]-[project-ref]-rc` 7. Select your VPC from the dropdown. This should match the VPC you selected for your security group in Step 3 8. Enable the **Enable DNS name** option if you want to use a DNS record instead of the endpoints IP address(es) 9. Choose the appropriate subnets for your network * AWS will provision a private ENI for you in each selected subnet * IP address type should be set to IPv4 10. Choose the security group you created in Step 3. 11. Click **Create endpoint** 12. After creation, you will see the endpoint in the [Endpoints](https://console.aws.amazon.com/vpcconsole/home#Endpoints:) section with a status of "Available" 13. For connectivity: * The IP addresses of the endpoint will be listed in the **Subnets** section of the endpoint details * The DNS record will be in the **Associations** section of the endpoint details in the **DNS Name** field if you enabled it in step 8 ##### Option B: Attach resource configuration to an existing VPC lattice service network 1. **This method is only recommended if you have an existing VPC Lattice Service Network** 2. Navigate to the VPC Lattice console in your AWS account 3. Go to [Service networks](https://console.aws.amazon.com/vpcconsole/home#ServiceNetworks) in the left sidebar and select your service network 4. In the service network details, go to the **Resource configuration associations** tab 5. Click **Create associations** 6. Select the appropriate **Resource configuration** from the dropdown 7. Click **Save changes** 8. After creation, you will see the resource configuration in the Resource configurations section of your service network with the status "Active" 9. For connectivity, click on the association details and the domain name will be listed in the **DNS entries** section #### Step 5: Test connectivity[#](https://supabase.com/docs/guides/platform/privatelink#step-5-test-connectivity) Verify the private connection is working correctly from your VPC: 1. Launch an EC2 instance or use an existing instance within your VPC 2. Install a Postgres client (e.g., `psql`) 3. Test the connection using the private endpoint: 1psql "postgresql://[username]:[password]@[private-endpoint]:5432/postgres" You should see a successful connection without any public internet traffic. #### Step 6: Update applications[#](https://supabase.com/docs/guides/platform/privatelink#step-6-update-applications) Configure your applications to use the private connection details: 1. Update your database connection strings to use the private endpoint hostname 2. Ensure your application instances are in the same VPC or connected VPCs 3. Update any database connection pooling configurations 4. Test application connectivity thoroughly Example connection string update: 1# Before (public)2postgresql://user:pass@db.[project-ref].supabase.co:5432/postgres34# After (private)5postgresql://user:pass@your-private-endpoint.vpce.amazonaws.com:5432/postgres #### Step 7: Disable public connectivity (optional)[#](https://supabase.com/docs/guides/platform/privatelink#step-7-disable-public-connectivity-optional) For maximum security, you can disable public internet access for your database: 1. Contact Supabase support to disable public connectivity 2. Ensure all applications are successfully using the private connection 3. Update any monitoring or backup tools to use the private endpoint Beta limitations[#](https://supabase.com/docs/guides/platform/privatelink#beta-limitations) -------------------------------------------------------------------------------------------- During the beta phase: * **Read Replicas**: To establish PrivateLink with a Read Replica, reach out to your account rep. * **Feature Evolution**: The setup process and capabilities may evolve as we refine the offering Compatibility[#](https://supabase.com/docs/guides/platform/privatelink#compatibility) -------------------------------------------------------------------------------------- The PrivateLink endpoint is a layer 3 solution so behaves like a standard Postgres endpoint, allowing you to connect using: * Direct Postgres connections using standard tools * Third-party database tools and ORMs (with the appropriate routing) Next steps[#](https://supabase.com/docs/guides/platform/privatelink#next-steps) -------------------------------------------------------------------------------- Ready to enhance your database security with PrivateLink? [Contact our Enterprise team](https://supabase.com/contact/enterprise) to discuss your requirements and begin the setup process. Our support team will guide you through the configuration and ensure your private database connectivity meets your security and performance requirements. Regional availability[#](https://supabase.com/docs/guides/platform/privatelink#regional-availability) ------------------------------------------------------------------------------------------------------ PrivateLink is not currently available in the following regions: * **eu-central-2 (Zurich)** - Expected availability: April 2026 ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/platform/privatelink%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/platform/privatelink%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Resources | Supabase Docs Resources Resources ============= * * * [Examples\ \ Official GitHub examples, curated content from the community, and more.](https://supabase.com/docs/guides/resources/examples) [Glossary\ \ Definitions for terminology and acronyms used in the Supabase documentation.](https://supabase.com/docs/guides/resources/glossary) ### Migrate to Supabase[#](https://supabase.com/docs/guides/resources#migrate-to-supabase) [![Auth0 Icon](https://supabase.com/docs/img/icons/auth0-icon-light.svg)\ \ ##### Auth0\ \ Move your auth users from Auth0 to a Supabase project.Learn more](https://supabase.com/docs/guides/resources/migrating-to-supabase/auth0) [![Firebase Auth Icon](https://supabase.com/docs/img/icons/firebase-icon.svg)\ \ ##### Firebase Auth\ \ Move your auth users from a Firebase project to a Supabase project.Learn more](https://supabase.com/docs/guides/resources/migrating-to-supabase/firebase-auth) [![Firestore Data Icon](https://supabase.com/docs/img/icons/firebase-icon.svg)\ \ ##### Firestore Data\ \ Migrate the contents of a Firestore collection to a single PostgreSQL table.Learn more](https://supabase.com/docs/guides/resources/migrating-to-supabase/firestore-data) [![Firebase Storage Icon](https://supabase.com/docs/img/icons/firebase-icon.svg)\ \ ##### Firebase Storage\ \ Convert your Firebase Storage files to Supabase Storage.Learn more](https://supabase.com/docs/guides/resources/migrating-to-supabase/firebase-storage) [![Heroku Icon](https://supabase.com/docs/img/icons/heroku-icon.svg)\ \ ##### Heroku\ \ Migrate your Heroku Postgres database to Supabase.Learn more](https://supabase.com/docs/guides/resources/migrating-to-supabase/heroku) [![Render Icon](https://supabase.com/docs/img/icons/render-icon.svg)\ \ ##### Render\ \ Migrate your Render Postgres database to Supabase.Learn more](https://supabase.com/docs/guides/resources/migrating-to-supabase/render) [![Amazon RDS Icon](https://supabase.com/docs/img/icons/aws-rds-icon.svg)\ \ ##### Amazon RDS\ \ Migrate your Amazon RDS database to Supabase.Learn more](https://supabase.com/docs/guides/resources/migrating-to-supabase/amazon-rds) [![Postgres Icon](https://supabase.com/docs/img/icons/postgres-icon.svg)\ \ ##### Postgres\ \ Migrate your Postgres database to Supabase.Learn more](https://supabase.com/docs/guides/resources/migrating-to-supabase/postgres) [![MySQL Icon](https://supabase.com/docs/img/icons/mysql-icon.svg)\ \ ##### MySQL\ \ Migrate your MySQL database to Supabase.Learn more](https://supabase.com/docs/guides/resources/migrating-to-supabase/mysql) [![Microsoft SQL Server Icon](https://supabase.com/docs/img/icons/mssql-icon.svg)\ \ ##### Microsoft SQL Server\ \ Migrate your Microsoft SQL Server database to Supabase.Learn more](https://supabase.com/docs/guides/resources/migrating-to-supabase/mssql) ### Postgres resources[#](https://supabase.com/docs/guides/resources#postgres-resources) [Managing Indexes\ \ Improve query performance using various index types in Postgres.](https://supabase.com/docs/guides/database/postgres/indexes) [Cascade Deletes\ \ Understand the types of foreign key constraint deletes.](https://supabase.com/docs/guides/database/postgres/cascade-deletes) [Drop all tables in schema\ \ Delete all tables in a given schema.](https://supabase.com/docs/guides/database/postgres/dropping-all-tables-in-schema) [Select first row per group\ \ Retrieve the first row in each distinct group.](https://supabase.com/docs/guides/database/postgres/first-row-in-group) [Print PostgreSQL version\ \ Find out which version of Postgres you are running.](https://supabase.com/docs/guides/database/postgres/which-version-of-postgres) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/resources%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/resources%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Migrating within Supabase | Supabase Docs Platform Migrating within Supabase ============================= Learn how to migrate from one Supabase project to another ------------------------------------------------------------- * * * If you are on a Paid Plan and have physical backups enabled, you should instead use the [Restore to another project feature](https://supabase.com/docs/guides/platform/clone-project) . Database migration guides[#](https://supabase.com/docs/guides/platform/migrating-within-supabase#database-migration-guides) ---------------------------------------------------------------------------------------------------------------------------- If you need to migrate from one Supabase project to another, choose the appropriate guide below: ### Backup file from the dashboard (\*.backup)[#](https://supabase.com/docs/guides/platform/migrating-within-supabase#backup-file-from-the-dashboard-backup) Follow the [Restore dashboard backup guide](https://supabase.com/docs/guides/platform/migrating-within-supabase/dashboard-restore) ### SQL backup files (\*.sql)[#](https://supabase.com/docs/guides/platform/migrating-within-supabase#sql-backup-files-sql) Follow the [Backup and Restore using the CLI guide](https://supabase.com/docs/guides/platform/migrating-within-supabase/backup-restore) Transfer project to a different organization[#](https://supabase.com/docs/guides/platform/migrating-within-supabase#transfer-project-to-a-different-organization) ------------------------------------------------------------------------------------------------------------------------------------------------------------------ Project migration is primarily for changing regions or upgrading to new major versions of the platform in some scenarios. If you need to move your project to a different organization without touching the infrastructure, see [project transfers](https://supabase.com/docs/guides/platform/project-transfer) . ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/platform/migrating-within-supabase%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/platform/migrating-within-supabase%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Enabling MCP Server Access | Supabase Docs Self-Hosting Enabling MCP Server Access ============================== Configure secure access to the MCP server in your self-hosted Supabase instance. ------------------------------------------------------------------------------------ * * * The MCP (Model Context Protocol) server in [self-hosted Supabase](https://supabase.com/docs/guides/self-hosting/docker) runs behind the internal API. Currently, it does not offer OAuth 2.1 authentication, and is not intended to be exposed to the Internet. The corresponding API route has to be protected by restricting network connections from the outside. By default, all connections to the MCP server are denied. This guide explains how to securely enable access to your self-hosted MCP server. Security considerations[#](https://supabase.com/docs/guides/self-hosting/enable-mcp#security-considerations) ------------------------------------------------------------------------------------------------------------- Do not allow connections to the self-hosted MCP server from the Internet. Only access it via: * A VPN connection to the server running the Studio container * An SSH tunnel from your local machine Accessing via SSH tunnel[#](https://supabase.com/docs/guides/self-hosting/enable-mcp#accessing-via-ssh-tunnel) --------------------------------------------------------------------------------------------------------------- ### Step 1: Determine the local IP address that will be used to access the MCP server[#](https://supabase.com/docs/guides/self-hosting/enable-mcp#step-1-determine-the-local-ip-address-that-will-be-used-to-access-the-mcp-server) When connecting via an SSH tunnel to the Studio Docker container, the source IP will be that of the Docker bridge gateway. You need to allow connections from this IP address. Determine the Docker bridge gateway IP on the host running your Supabase containers: 1docker inspect supabase-kong \2 --format '{{range .NetworkSettings.Networks}}{{println .Gateway}}{{end}}' This command will output an IP address, e.g., `172.18.0.1`. ### Step 2: Allow connections from the gateway IP[#](https://supabase.com/docs/guides/self-hosting/enable-mcp#step-2-allow-connections-from-the-gateway-ip) Add the IP address you discovered to the Kong configuration by editing the following section in `./volumes/api/kong.yml`: 1. Comment out the request-termination section 2. Remove the # symbols from the entire section starting with `- name: cors`, including `deny: []` 3. Add your local IP to the 'allow' list. 4. Your edited configuration should look like the example below. 1## MCP endpoint - local access2- name: mcp3 _comment: 'MCP: /mcp -> http://studio:3000/api/mcp (local access)'4 url: http://studio:3000/api/mcp5 routes:6 - name: mcp7 strip_path: true8 paths:9 - /mcp10 plugins:11 # Block access to /mcp by default12 #- name: request-termination13 # config:14 # status_code: 40315 # message: "Access is forbidden."16 # Enable local access (danger zone!)17 # 1. Comment out the 'request-termination' section above18 # 2. Uncomment the entire section below, including 'deny'19 # 3. Add your local IPs to the 'allow' list20 - name: cors21 - name: ip-restriction22 config:23 allow:24 - 127.0.0.125 - ::126 # Add your Docker bridge gateway IP below27 - 172.18.0.128 # Do not remove deny!29 deny: [] ### Step 3: Restart API gateway[#](https://supabase.com/docs/guides/self-hosting/enable-mcp#step-3-restart-api-gateway) After you've added the local IP address as above, restart the Kong container: 1docker compose restart kong ### Step 4: Create the SSH tunnel[#](https://supabase.com/docs/guides/self-hosting/enable-mcp#step-4-create-the-ssh-tunnel) From your local machine, create an SSH tunnel to your Supabase host: 1ssh -L localhost:8080:localhost:8000 you@your-supabase-host This command forwards local port `8080` to port `8000` on your Supabase host. ### Step 5: Configure your MCP client[#](https://supabase.com/docs/guides/self-hosting/enable-mcp#step-5-configure-your-mcp-client) Edit the settings for your MCP client and add the following to `"mcpServers": {}` or `"servers": {}`: 1{2 "mcpServers": {3 "supabase-self-hosted": {4 "url": "http://localhost:8080/mcp"5 }6 }7} ### Step 6: Start using the self-hosted MCP server[#](https://supabase.com/docs/guides/self-hosting/enable-mcp#step-6-start-using-the-self-hosted-mcp-server) From your local machine, check that the MCP server is reachable: 1curl http://localhost:8080/mcp \2 -X POST \3 -H "Content-Type: application/json" \4 -H "Accept: application/json, text/event-stream" \5 -H "MCP-Protocol-Version: 2025-06-18" \6 -d '{7 "jsonrpc": "2.0",8 "id": 1,9 "method": "initialize",10 "params": {11 "protocolVersion": "2025-06-18",12 "capabilities": {13 "elicitation": {}14 },15 "clientInfo": {16 "name": "test-client",17 "title": "Test Client",18 "version": "1.0.0"19 }20 }21 }' Start your MCP client (Claude Code, Cursor, etc.) and verify access to the MCP tools. For example, you can ask: "What is Supabase anon key? Use the Supabase MCP server tools." Troubleshooting[#](https://supabase.com/docs/guides/self-hosting/enable-mcp#troubleshooting) --------------------------------------------------------------------------------------------- If you are unable to connect to the MCP server: 1. Update Kong configuration file to the [latest version](https://github.com/supabase/supabase/blob/master/docker/volumes/api/kong.yml) and edit carefully 2. Confirm the Docker bridge gateway IP is correctly added in `./volumes/api/kong.yml` 3. Check Kong's logs for errors: `docker compose logs kong` 4. Make sure your SSH tunnel is active ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/self-hosting/enable-mcp%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/self-hosting/enable-mcp%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Supabase Platform | Supabase Docs Platform Supabase Platform ===================== * * * Supabase is a hosted platform which makes it very simple to get started without needing to manage any infrastructure. Visit [supabase.com/dashboard](https://supabase.com/dashboard) and sign in to start creating projects. Projects[#](https://supabase.com/docs/guides/platform#projects) ---------------------------------------------------------------- Each project on Supabase comes with: * A dedicated [Postgres database](https://supabase.com/docs/guides/database) * [Auto-generated APIs](https://supabase.com/docs/guides/database/api) * [Auth and user management](https://supabase.com/docs/guides/auth) * [Edge Functions](https://supabase.com/docs/guides/functions) * [Realtime API](https://supabase.com/docs/guides/realtime) * [Storage](https://supabase.com/docs/guides/storage) Organizations[#](https://supabase.com/docs/guides/platform#organizations) -------------------------------------------------------------------------- Organizations are a way to group your projects. Each organization can be configured with different team members and billing settings. Refer to [access control](https://supabase.com/docs/guides/platform/access-control) for more information on how to manage team members within an organization. Platform status[#](https://supabase.com/docs/guides/platform#platform-status) ------------------------------------------------------------------------------ If Supabase experiences outages, we keep you as informed as possible, as early as possible. We provide the following feedback channels: * Status page: [status.supabase.com](https://status.supabase.com/) * RSS Feed: [status.supabase.com/history.rss](https://status.supabase.com/history.rss) * Atom Feed: [status.supabase.com/history.atom](https://status.supabase.com/history.atom) * Slack Alerts: You can receive updates via the RSS feed, using Slack's [built-in RSS functionality](https://slack.com/help/articles/218688467-Add-RSS-feeds-to-Slack) `/feed subscribe https://status.supabase.com/history.atom` Make sure to review our [SLA](https://supabase.com/docs/company/sla) for details on our commitment to Platform Stability. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/platform%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/platform%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Available regions | Supabase Docs Platform Available regions ===================== * * * Each Supabase project is deployed to one primary region. Choose the location closest to your users for the best performance. General regions[#](https://supabase.com/docs/guides/platform/regions#general-regions) -------------------------------------------------------------------------------------- For most projects, we recommend choosing a general region. Supabase will deploy your project to an available AWS region within that area based on current infrastructure capacity. * Americas`East US (North Virginia)` * Europe`Central EU (Frankfurt)` * APAC`Southeast Asia (Singapore)` Note: General regions aren’t yet supported for read replicas or management via the API. Specific regions[#](https://supabase.com/docs/guides/platform/regions#specific-regions) ---------------------------------------------------------------------------------------- If you prefer, you can choose an exact AWS region for your project. * West US (North California)`us-west-1` * West US (Oregon)`us-west-2` * East US (North Virginia)`us-east-1` * East US (Ohio)`us-east-2` * Canada (Central)`ca-central-1` * West EU (Ireland)`eu-west-1` * West Europe (London)`eu-west-2` * West EU (Paris)`eu-west-3` * Central EU (Frankfurt)`eu-central-1` * Central Europe (Zurich)`eu-central-2` * North EU (Stockholm)`eu-north-1` * South Asia (Mumbai)`ap-south-1` * Southeast Asia (Singapore)`ap-southeast-1` * Northeast Asia (Tokyo)`ap-northeast-1` * Northeast Asia (Seoul)`ap-northeast-2` * Oceania (Sydney)`ap-southeast-2` * South America (São Paulo)`sa-east-1` ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/platform/regions%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/platform/regions%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # AWS Marketplace | Supabase Docs Platform AWS Marketplace =================== * * * You can purchase Supabase through the AWS Marketplace. Buying through AWS Marketplace can mean simpler billing, faster progress toward your AWS spend commitments, and centralized purchasing across all your AWS accounts. Start the purchase process from our marketplace [product page](https://aws.amazon.com/marketplace/pp/prodview-zjciuce2qsb3q) . When you make a purchase on AWS Marketplace, AWS will calculate sales taxes, VAT, GST, service tax, etc. (“Indirect Taxes”), if applicable, based on the location of your AWS account. You can find more details in the [AWS tax help guide](https://aws.amazon.com/tax-help/marketplace-buyers/) . ### Plans available through the AWS Marketplace[#](https://supabase.com/docs/guides/platform/aws-marketplace#plans-available-through-the-aws-marketplace) * Free Plan: not available * Pro Plan: available, self-serve * Team Plan: available, self-serve * Enterprise Plan: available, via AWS Marketplace Private Offer. [Contact us](https://forms.supabase.com/enterprise) for more information. More information[#](https://supabase.com/docs/guides/platform/aws-marketplace#more-information) ------------------------------------------------------------------------------------------------ * Implications of managing your Supabase organization through the AWS Marketplace. Refer to the [Account Setup guide](https://supabase.com/docs/guides/platform/aws-marketplace/account-setup#implications-of-linking-a-supabase-organization-to-a-marketplace-subscription) . * [AWS Marketplace FAQ](https://supabase.com/docs/guides/platform/aws-marketplace/faq) * General guidance on using the AWS Marketplace as a buyer. Refer to the [AWS documentation](https://docs.aws.amazon.com/marketplace/latest/buyerguide/using-aws-marketplace-as-a-subscriber.html) . Next steps[#](https://supabase.com/docs/guides/platform/aws-marketplace#next-steps) ------------------------------------------------------------------------------------ * Purchase Supabase through the AWS Marketplace. Refer to the [Getting Started guide](https://supabase.com/docs/guides/platform/aws-marketplace/getting-started) . ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/platform/aws-marketplace%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/platform/aws-marketplace%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Performance Tuning | Supabase Docs Platform Performance Tuning ====================== * * * The Supabase platform automatically optimizes your Postgres database to take advantage of the compute resources of the plan your project is on. However, these optimizations are based on assumptions about the type of workflow the project is being utilized for, and it is likely that better results can be obtained by tuning the database for your particular workflow. Examining query performance[#](https://supabase.com/docs/guides/platform/performance#examining-query-performance) ------------------------------------------------------------------------------------------------------------------ Unoptimized queries are a major cause of poor database performance. To analyze the performance of your queries, see the [Debugging and monitoring guide](https://supabase.com/docs/guides/database/inspect) . Optimizing the number of connections[#](https://supabase.com/docs/guides/platform/performance#optimizing-the-number-of-connections) ------------------------------------------------------------------------------------------------------------------------------------ The default connection limits for Postgres and Supavisor is based on your compute size. See the default connection numbers in the [Compute Add-ons](https://supabase.com/docs/guides/platform/compute-add-ons) section. If the number of connections is insufficient, you will receive the following error upon connecting to the DB: 1$ psql -U postgres -h ...2FATAL: remaining connection slots are reserved for non-replication superuser connections In such a scenario, you can consider: * [upgrading to a larger compute add-on](https://supabase.com/dashboard/project/_/settings/compute-and-disk) * configuring your clients to use fewer connections * manually configuring the database for a higher number of connections ### Configuring clients to use fewer connections[#](https://supabase.com/docs/guides/platform/performance#configuring-clients-to-use-fewer-connections) You can use the [pg\_stat\_activity](https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-ACTIVITY-VIEW) view to debug which clients are holding open connections on your DB. `pg_stat_activity` only exposes information on direct connections to the database. Information on the number of connections to Supavisor is available [via the metrics endpoint](https://supabase.com/docs/guides/platform/metrics) . Depending on the clients involved, you might be able to configure them to work with fewer connections (e.g. by imposing a limit on the maximum number of connections they're allowed to use), or shift specific workloads to connect via [Supavisor](https://supabase.com/docs/guides/database/connecting-to-postgres#connection-pooler) instead. Transient workflows, which can quickly scale up and down in response to traffic (e.g. serverless functions), can especially benefit from using a connection pooler rather than connecting to the DB directly. ### Allowing higher number of connections[#](https://supabase.com/docs/guides/platform/performance#allowing-higher-number-of-connections) You can configure Postgres connection limit among other parameters by using [Custom Postgres Config](https://supabase.com/docs/guides/platform/custom-postgres-config#custom-postgres-config) . ### Enterprise[#](https://supabase.com/docs/guides/platform/performance#enterprise) [Contact us](https://forms.supabase.com/enterprise) if you need help tuning your database for your specific workflow. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/platform/performance%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/platform/performance%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Understanding Database and Disk Size | Supabase Docs Platform Understanding Database and Disk Size ======================================== * * * Disk metrics refer to the storage usage reported by Postgres. These metrics are updated daily. As you read through this document, we will refer to "database size" and "disk size": * _Database size_: Displays the actual size of the data within your Postgres database. This can be found on the [Database Reports page](https://supabase.com/dashboard/project/_/observability/database) . * _Disk size_: Shows the overall disk space usage, which includes both the database size and additional files required for Postgres to function like the Write Ahead Log (WAL) and other system log files. You can view this on the [Database Settings page](https://supabase.com/dashboard/project/_/database/settings) . Database size[#](https://supabase.com/docs/guides/platform/database-size#database-size) ---------------------------------------------------------------------------------------- This SQL query will show the size of all databases in your Postgres cluster: 1select2 pg_size_pretty(sum(pg_database_size(pg_database.datname)))3from pg_database; This value is reported in the [database report page](https://supabase.com/dashboard/project/_/observability/database) . Database size is consumed primarily by your data, indexes, and materialized views. You can reduce your database size by removing any of these and running a Vacuum operation. Depending on your billing plan, your database can go into read-only mode which can prevent you inserting and deleting data. There are instructions for managing read-only mode in the [Disk Management](https://supabase.com/docs/guides/platform/database-size#disk-management) section. ### Disk space usage[#](https://supabase.com/docs/guides/platform/database-size#disk-space-usage) Your database size is part of the disk usage for your Supabase project, there are many components to Postgres that consume additional disk space. One of the primary components, is the [Write Ahead Log (WAL)](https://www.postgresql.org/docs/current/wal-intro.html) . Postgres will store database changes in log files that are cleared away after they are applied to the database. These same files are also used by [Read Replicas](https://supabase.com/docs/guides/platform/read-replicas) or other replication methods. If you would like to determine the size of the WAL files stored on disk, Postgres provides `pg_ls_waldir` as a helper function; the following query can be run: 1select pg_size_pretty(sum(size)) as wal_size from pg_ls_waldir(); ### Vacuum operations[#](https://supabase.com/docs/guides/platform/database-size#vacuum-operations) Postgres does not immediately reclaim the physical space used by dead tuples (i.e., deleted rows) in the DB. They are marked as "removed" until a [vacuum operation](https://www.postgresql.org/docs/current/routine-vacuuming.html) is executed. As a result, deleting data from your database may not immediately reduce the reported disk usage. You can use the [Supabase CLI](https://supabase.com/docs/guides/cli/getting-started) `inspect db bloat` command to view all dead tuples in your database. Alternatively, you can run the [query](https://github.com/supabase/cli/blob/c9cce58025fded16b4c332747f819a44f45c3b83/internal/inspect/bloat/bloat.go#L17) found in the CLI's GitHub repo in the [SQL Editor](https://supabase.com/dashboard/project/_/sql/) 1# Login to the CLI2npx supabase login34# Initialize a local supabase directory5npx supabase init67# Link a project8npx supabase link910# Detect bloat11npx supabase inspect db bloat --linked If you find a table you would like to immediately clean, you can run the following in the [SQL Editor](https://supabase.com/dashboard/project/_/sql/new) : 1vacuum full ; Vacuum operations can temporarily increase resource utilization, which may adversely impact the observed performance of your project until the maintenance is completed. The [vacuum full](https://www.postgresql.org/docs/current/sql-vacuum.html) command will lock the table until the operation concludes. Supabase projects have automatic vacuuming enabled, which ensures that these operations are performed regularly to keep the database healthy and performant. It is possible to [fine-tune](https://www.percona.com/blog/2018/08/10/tuning-autovacuum-in-postgresql-and-autovacuum-internals/) the [autovacuum parameters](https://www.enterprisedb.com/blog/postgresql-vacuum-and-analyze-best-practice-tips) , or [manually initiate](https://www.postgresql.org/docs/current/sql-vacuum.html) vacuum operations. Running a manual vacuum after deleting large amounts of data from your DB could help reduce the database size reported by Postgres. ### Preoccupied space[#](https://supabase.com/docs/guides/platform/database-size#preoccupied-space) New Supabase projects have a database size of ~40-60mb. This space includes pre-installed extensions, schemas, and default Postgres data. Additional database size is used when installing extensions, even if those extensions are inactive. Disk size[#](https://supabase.com/docs/guides/platform/database-size#disk-size) -------------------------------------------------------------------------------- Supabase uses network-attached storage to balance performance with scalability. The disk scaling behavior depends on your billing plan. ### Paid plan behavior[#](https://supabase.com/docs/guides/platform/database-size#paid-plan-behavior) Projects on the Pro Plan and higher have auto-scaling disks. Disk size expands automatically when the database reaches 90% of the allocated disk size. The disk is expanded to be 50% larger (for example, 8 GB -> 12 GB). Auto-scaling is limited to four modifications within a rolling 24-hour window. While a new modification can be initiated immediately after the previous one completes, reaching the quota of four resizes within the current rolling 24-hour window will prevent further scaling until the window allows it. If you reach 95% disk utilization and have exhausted your modification quota, your project will enter read-only mode. The automatic resize operation will add an additional 50% capped to a maximum of 200 GB. If 50% of your current usage is more than 200 GB then only 200 GB will be added to your disk (for example a size of 1500 GB will resize to 1700 GB). Disk size can also be manually expanded on the [Database Settings page](https://supabase.com/dashboard/project/_/database/settings) . The maximum disk size for the Pro/Team Plan is 60 TB. If you need more than this, [contact us](https://forms.supabase.com/enterprise) to learn more about the Enterprise Plan. You may want to import a lot of data into your database which requires multiple disk expansions. for example, uploading more than 1.5x the current size of your database storage will put your database into [read-only mode](https://supabase.com/docs/guides/platform/database-size#read-only-mode) . If so, it is highly recommended you increase the disk size manually on the [Database Settings page](https://supabase.com/dashboard/project/_/database/settings) . Due to restrictions on the underlying cloud provider, disk modifications are limited to four operations within a rolling 24-hour window. While a new modification can be initiated as soon as the previous one completes, you will be unable to make further adjustments if you reach this rolling 24-hour limit until the rolling 24-hour window permits it. ### Free Plan behavior[#](https://supabase.com/docs/guides/platform/database-size#free-plan-behavior) Free Plan projects enter [read-only](https://supabase.com/docs/guides/platform/database-size#read-only-mode) mode when your **database size** exceeds 500 MB. Note that this is the _database size_ limit (the size of your actual Postgres data), not the _disk size_. Free Plan projects include 1 GB of disk space, but read-only mode is triggered by the 500 MB database size quota. Once in read-only mode, you have these options: * [Upgrade to the Pro Plan](https://supabase.com/dashboard/org/_/billing) to increase the database size quota. [Disable the Spend Cap](https://app.supabase.com/org/_/billing?panel=costControl) if you want your Pro instance to auto-scale beyond the 8 GB disk size limit. * [Disable read-only mode](https://supabase.com/docs/guides/platform/database-size#disabling-read-only-mode) and reduce your database size. ### Read-only mode[#](https://supabase.com/docs/guides/platform/database-size#read-only-mode) In some cases Supabase may put your database into read-only mode to prevent your database from exceeding the billing or disk limitations. In read-only mode, clients will encounter errors such as `cannot execute INSERT in a read-only transaction`. Regular operation (read-write mode) is automatically re-enabled once usage is below 95% of the disk size, ### Disabling read-only mode[#](https://supabase.com/docs/guides/platform/database-size#disabling-read-only-mode) You manually override read-only mode to reduce disk size. To do this, run the following in the [SQL Editor](https://supabase.com/dashboard/project/_/sql) : First, change the [transaction access mode](https://www.postgresql.org/docs/current/sql-set-transaction.html) : 1set session characteristics as transaction read write; This allows you to delete data from within the session. After deleting data, consider running a vacuum to reclaim as much space as possible: 1vacuum; Once you have reclaimed space, you can run the following to disable [read-only](https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-DEFAULT-TRANSACTION-READ-ONLY) mode: 1set default_transaction_read_only = 'off'; ### Disk size distribution[#](https://supabase.com/docs/guides/platform/database-size#disk-size-distribution) You can check the distribution of your disk size on your [project's compute and disk page](https://supabase.com/dashboard/project/_/settings/compute-and-disk) . ![Disk Size Distribution](https://supabase.com/docs/img/guides/platform/database-size/disk-size-distribution.png) Your disk size usage falls in three categories: * **Database** - Disk usage by the database. This includes the actual data, indexes, materialized views, ... * **WAL** - Disk usage by the write-ahead log. The usage depends on your WAL settings and the amount of data being written to the database. * **System** - Disk usage reserved by the system to ensure the database can operate smoothly. Users cannot modify this and it should only take very little space. ### Reducing disk size[#](https://supabase.com/docs/guides/platform/database-size#reducing-disk-size) Disks don't automatically downsize during normal operation. Once you have [reduced your database size](https://supabase.com/docs/guides/platform/database-size#database-size) , they _will_ automatically "right-size" during a [project upgrade](https://supabase.com/docs/guides/platform/upgrading) . The final disk size after the upgrade is 1.2x the size of the database with a minimum of 8 GB. For example, if your database size is 100GB, and you have a 200GB disk, the size after a project upgrade will be 120 GB. In case you have a large WAL directory, you may [modify WAL settings](https://supabase.com/docs/guides/database/custom-postgres-config) such as `max_wal_size`. Use at your own risk as changing these settings can have side effects. To query your current WAL size, use `SELECT SUM(size) FROM pg_ls_waldir()`. In the event that your project is already on the latest version of Postgres and cannot be upgraded, a new version of Postgres will be released approximately every week which you can then upgrade to once it becomes available. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/platform/database-size%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/platform/database-size%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Upgrading | Supabase Docs Platform Upgrading ============= * * * Supabase ships fast and we endeavor to add all new features to existing projects wherever possible. In some cases, access to new features require upgrading or migrating your Supabase project. This guide refers to upgrading the Postgres version of your Supabase Project. For scaling your compute size, refer to the [Compute and Disk page](https://supabase.com/docs/guides/platform/compute-and-disk) . You can upgrade your project using in-place upgrades or by pausing and restoring your project. In-place upgrades[#](https://supabase.com/docs/guides/platform/upgrading#in-place-upgrades) -------------------------------------------------------------------------------------------- For security purposes, passwords for custom roles are not backed up and, following a restore, they would need to be reset. See [here](https://supabase.com/docs/guides/platform/backups#daily-backups) for more details In-place upgrades uses `pg_upgrade`. For projects larger than 1GB, this method is generally faster than a pause and restore cycle, and the speed advantage grows with the size of the database. 1. Plan for an appropriate downtime window, and ensure you have reviewed the [caveats](https://supabase.com/docs/guides/platform/upgrading#caveats) section of this document before executing the upgrade. 2. Use the "Upgrade project" button on the [Infrastructure](https://supabase.com/dashboard/project/_/settings/infrastructure) section of your dashboard. Additionally, if the upgrade should fail, your original database would be brought back up online and be able to service requests. As a rough rule of thumb, pg\_upgrade operates at ~100MBps (when executing an upgrade on your data). Using the size of your database, you can use this metric to derive an approximate sense of the downtime window necessary for the upgrade. During this window, you should plan for your database and associated services to be unavailable. Pause and restore[#](https://supabase.com/docs/guides/platform/upgrading#pause-and-restore) -------------------------------------------------------------------------------------------- We recommend using the In-place upgrade method, as it is faster, and more reliable. Additionally, only Free-tier projects are eligible to use the Pause and Restore method. When you pause and restore a project, the restored database includes the latest features. **This method includes downtime**, so be aware that your project will be inaccessible for a short period of time. 1. On the [General Settings](https://supabase.com/dashboard/project/_/settings/general) page in the Dashboard, click **Pause project**. You will be redirected to the home screen in the meantime. 2. After this, click **Restore project**. Your project will be restored from the [physical backup](https://supabase.com/guides/platform/backups) . You should receive an email once the restoration is complete. Pausing and restoring project will take some time depending on how much data your database has. If the restore process fails, [contact Supabase support](https://supabase.com/dashboard/support/new?projectRef=) to bring your project back online. Caveats[#](https://supabase.com/docs/guides/platform/upgrading#caveats) ------------------------------------------------------------------------ Regardless of the upgrade method, a few caveats apply: ### Logical replication[#](https://supabase.com/docs/guides/platform/upgrading#logical-replication) If you are using logical replication, the replication slots will not be preserved by the upgrade process. You will need to manually recreate them after the upgrade with the method `pg_create_logical_replication_slot`. Refer to the Postgres docs on [Replication Management Functions](https://www.postgresql.org/docs/current/functions-admin.html#FUNCTIONS-REPLICATION) for more details about the method. ### Breaking changes[#](https://supabase.com/docs/guides/platform/upgrading#breaking-changes) Newer versions of services can break functionality or change the performance characteristics you rely on. If your project is eligible for an upgrade, you will be able to find your current service versions from within [the Supabase dashboard](https://supabase.com/dashboard/project/_/settings/infrastructure) . Breaking changes are generally only present in major version upgrades of Postgres and PostgREST. You can find their respective release notes at: * [Postgres](https://www.postgresql.org/docs/release/) * [PostgREST](https://github.com/PostgREST/postgrest/releases) If you are upgrading from a significantly older version, you will need to consider the release notes for any intermediary releases as well. ### Time limits[#](https://supabase.com/docs/guides/platform/upgrading#time-limits) Starting from 2024-06-24, when a project is paused, users then have a 90-day window to restore the project on the platform from within Supabase Studio. The 90-day window allows Supabase to introduce platform changes that may not be backwards compatible with older backups. Unlike active projects, static backups can't be updated to accommodate such changes. During the 90-day restore window a paused project can be restored to the platform with a single button click from [Studio's dashboard page](https://supabase.com/dashboard/projects) . ![Project Paused: 90 Days Remaining](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fguides%2Fplatform%2Fpaused-90-day.png&w=2048&q=75) After the 90-day restore window, you can download your project's backup file, and Storage objects from the project dashboard. You can restore the data in the following ways: * [Restore a backup to a new Supabase project](https://supabase.com/docs/guides/platform/migrating-within-supabase/dashboard-restore) * [Restore a backup locally](https://supabase.com/docs/guides/local-development/restoring-downloaded-backup) ![Project Paused: 90 Days Remaining](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fguides%2Fplatform%2Fpaused-dl-backup.png&w=1080&q=75) If you upgrade to a paid plan while your project is paused within the 90-day restore window, any expired one-click restore options are reenabled. Since the backup was taken outside the backwards compatibility window, it may fail to restore. If you have a problem restoring your backup after upgrading, contact [Support](https://supabase.com/support) . ![Project Paused: 90 Days Remaining](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fguides%2Fplatform%2Fpaused-paid-tier.png&w=2048&q=75) ### Disk sizing[#](https://supabase.com/docs/guides/platform/upgrading#disk-sizing) When upgrading, the Supabase platform will "right-size" your disk based on the current size of the database. For example, if your database is 100GB in size, and you have a 200GB disk, the upgrade will reduce the disk size to 120GB (1.2x the size of your database). ### Objects dependent on Postgres extensions[#](https://supabase.com/docs/guides/platform/upgrading#objects-dependent-on-postgres-extensions) In-place upgrades do not support upgrading of databases containing reg\* data types referencing system OIDs. If you have created any objects that depend on the following extensions, you will need to recreate them after the upgrade. ### `pg_cron` records[#](https://supabase.com/docs/guides/platform/upgrading#pgcron-records) [pg\_cron](https://github.com/citusdata/pg_cron#viewing-job-run-details) does not automatically clean up historical records. This can lead to extremely large `cron.job_run_details` tables if the records are not regularly pruned; you should clean unnecessary records from this table prior to an upgrade. During an in-place upgrade, the `pg_cron` extension gets dropped and recreated. Prior to this process, the `cron.job_run_details` table is duplicated to avoid losing historical logs. The instantaneous disk pressure created by duplicating an extremely large details table can cause at best unnecessary performance degradation, or at worst, upgrade process failures. ### Extensions[#](https://supabase.com/docs/guides/platform/upgrading#extensions) In-place upgrades do not currently support upgrading of databases using extensions older than the following versions: * TimescaleDB 2.16.1 * plv8 3.1.10 To upgrade to a newer version of Postgres, you will need to drop the extensions before the upgrade, and recreate them after the upgrade. #### Authentication method changes - deprecating md5 in favor of scram-sha-256[#](https://supabase.com/docs/guides/platform/upgrading#authentication-method-changes---deprecating-md5-in-favor-of-scram-sha-256) The md5 hashing method has [known weaknesses](https://en.wikipedia.org/wiki/MD5#Security) that make it unsuitable for cryptography. As such, we are deprecating md5 in favor of [scram-sha-256](https://www.postgresql.org/docs/current/auth-password.html) , which is the default and most secure authentication method used in the latest Postgres versions. We automatically migrate Supabase-managed roles' passwords to scram-sha-256 during the upgrade process, but you will need to manually migrate the passwords of any custom roles you have created, else you won't be able to connect using them after the upgrade. To identify roles using the md5 hashing method and migrate their passwords, you can use the following SQL statements after the upgrade: 1-- List roles using md5 hashing method2SELECT3 rolname4FROM pg_authid5WHERE rolcanlogin = true6 AND rolpassword LIKE 'md5%';78-- Migrate a role's password to scram-sha-2569ALTER ROLE WITH PASSWORD ''; ### Database size reduction[#](https://supabase.com/docs/guides/platform/upgrading#database-size-reduction) As part of the upgrade process, maintenance operations such as [vacuuming](https://www.postgresql.org/docs/current/routine-vacuuming.html#ROUTINE-VACUUMING) are also executed. This can result in a reduction in the reported database size. ### Post-upgrade validation[#](https://supabase.com/docs/guides/platform/upgrading#post-upgrade-validation) Supabase performs extensive pre- and post-upgrade validations to ensure that the database has been correctly upgraded. However, you should plan for your own application-level validations, as there might be changes you might not have anticipated, and this should be budgeted for when planning your downtime window. Specific upgrade notes[#](https://supabase.com/docs/guides/platform/upgrading#specific-upgrade-notes) ------------------------------------------------------------------------------------------------------ ### Upgrading to Postgres 17[#](https://supabase.com/docs/guides/platform/upgrading#upgrading-to-postgres-17) In projects using Postgres 17, the following extensions are deprecated: * `plcoffee` * `plls` * `plv8` * `timescaledb` * `pgjwt` Projects planning to upgrade from Postgres 15 to Postgres 17 need to first disable these extensions in the [Supabase Dashboard](https://supabase.com/dashboard/project/_/database/extensions) . `pgjwt` was enabled by default on every Supabase project up until Postgres 17. If you weren’t explicitly using `pgjwt` in your project, it’s most likely safe to disable. Existing projects on lower versions of Postgres are not impacted, and the extensions will continue to be supported on projects using Postgres 15, until the end of life of Postgres 15 on the Supabase platform. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/platform/upgrading%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/platform/upgrading%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Dedicated IPv4 Address for Ingress | Supabase Docs Platform Dedicated IPv4 Address for Ingress ====================================== Attach an IPv4 address to your database ------------------------------------------- * * * The Supabase IPv4 add-on provides a dedicated IPv4 address for your Postgres database connection. It can be configured in the [Add-ons Settings](https://supabase.com/dashboard/project/_/settings/addons) . Understanding IP addresses[#](https://supabase.com/docs/guides/platform/ipv4-address#understanding-ip-addresses) ----------------------------------------------------------------------------------------------------------------- The Internet Protocol (IP) addresses devices on the internet. There are two main versions: * **IPv4**: The older version, with a limited address space. * **IPv6**: The newer version, offering a much larger address space and the future-proof option. When you need the IPv4 add-on:[#](https://supabase.com/docs/guides/platform/ipv4-address#when-you-need-the-ipv4-add-on) ------------------------------------------------------------------------------------------------------------------------ IPv4 addresses are guaranteed to be static for ingress traffic. If your database is making outbound connections, the outbound IP address is not static and cannot be guaranteed. * When using the direct connection string in an IPv6-incompatible network instead of Supavisor or client libraries. * When you need a dedicated IP address for your direct connection string Enabling the IPv4 add-on[#](https://supabase.com/docs/guides/platform/ipv4-address#enabling-the-ipv4-add-on) ------------------------------------------------------------------------------------------------------------- You can enable the IPv4 add-on in your project's [add-ons settings](https://supabase.com/dashboard/project/_/settings/addons) . You can also manage the IPv4 add-on using the Management API: 1# Get your access token from https://supabase.com/dashboard/account/tokens2export SUPABASE_ACCESS_TOKEN="your-access-token"3export PROJECT_REF="your-project-ref"45# Get current IPv4 add-on status6curl -X GET "https://api.supabase.com/v1/projects/$PROJECT_REF/billing/addons" \7 -H "Authorization: Bearer $SUPABASE_ACCESS_TOKEN"89# Enable IPv4 add-on10curl -X PATCH "https://api.supabase.com/v1/projects/$PROJECT_REF/billing/addons" \11 -H "Authorization: Bearer $SUPABASE_ACCESS_TOKEN" \12 -H "Content-Type: application/json" \13 -d '{14 "addon_variant": "ipv4_default",15 "addon_type": "ipv4"16 }'1718# Disable IPv4 add-on19curl -X DELETE "https://api.supabase.com/v1/projects/$PROJECT_REF/billing/addons/ipv4_default" \20 -H "Authorization: Bearer $SUPABASE_ACCESS_TOKEN" Note that direct database connections can experience a short amount of downtime when toggling the add-on due to DNS reconfiguration and propagation. Generally, this should be less than a minute. Read replicas and IPv4 add-on[#](https://supabase.com/docs/guides/platform/ipv4-address#read-replicas-and-ipv4-add-on) ----------------------------------------------------------------------------------------------------------------------- When using the add-on, each database (including read replicas) receives an IPv4 address. Each replica adds to the total IPv4 cost. Changes and updates[#](https://supabase.com/docs/guides/platform/ipv4-address#changes-and-updates) --------------------------------------------------------------------------------------------------- * While the IPv4 address generally remains the same, actions like pausing/unpausing the project or enabling/disabling the add-on can lead to a new IPv4 address. Supabase and IPv6 compatibility[#](https://supabase.com/docs/guides/platform/ipv4-address#supabase-and-ipv6-compatibility) --------------------------------------------------------------------------------------------------------------------------- By default, Supabase Postgres use IPv6 addresses. If your system doesn't support IPv6, you have the following options: 1. **Supavisor Connection Strings**: The Supavisor connection strings are IPv4-compatible alternatives to direct connections 2. **Supabase Client Libraries**: These libraries are compatible with IPv4 3. **Dedicated IPv4 Add-On (Pro Plans+)**: For a guaranteed IPv4 and static database address for the direct connection, enable this paid add-on. ### Checking your network IPv6 support[#](https://supabase.com/docs/guides/platform/ipv4-address#checking-your-network-ipv6-support) You can check if your personal network is IPv6 compatible at [https://test-ipv6.com](https://test-ipv6.com/) . ### Checking platforms for IPv6 support:[#](https://supabase.com/docs/guides/platform/ipv4-address#checking-platforms-for-ipv6-support) The majority of services are IPv6 compatible. However, there are a few prominent ones that only accept IPv4 connections: * [Retool](https://retool.com/) * [Vercel](https://vercel.com/) * [GitHub Actions](https://docs.github.com/en/actions) * [Render](https://render.com/) Finding your database's IP address[#](https://supabase.com/docs/guides/platform/ipv4-address#finding-your-databases-ip-address) -------------------------------------------------------------------------------------------------------------------------------- Use an IP lookup website or this command (replace ``): 1nslookup db..supabase.co Identifying your connections[#](https://supabase.com/docs/guides/platform/ipv4-address#identifying-your-connections) --------------------------------------------------------------------------------------------------------------------- The pooler and direct connection strings can be found in the [project connect page](https://supabase.com/dashboard/project/_?showConnect=true) : #### Direct connection[#](https://supabase.com/docs/guides/platform/ipv4-address#direct-connection) IPv6 unless IPv4 Add-On is enabled 1# Example direct connection string2postgresql://postgres:[YOUR-PASSWORD]@db.ajrbwkcuthywfihaarmflo.supabase.co:5432/postgres #### Supavisor in transaction mode (port 6543)[#](https://supabase.com/docs/guides/platform/ipv4-address#supavisor-in-transaction-mode-port-6543) Always uses an IPv4 address 1# Example transaction string2postgresql://postgres.ajrbwkcuthywddfihrmflo:[YOUR-PASSWORD]@aws-0-us-east-1.pooler.supabase.com:6543/postgres #### Supavisor in session mode (port 5432)[#](https://supabase.com/docs/guides/platform/ipv4-address#supavisor-in-session-mode-port-5432) Always uses an IPv4 address 1# Example session string2postgresql://postgres.ajrbwkcuthywfddihrmflo:[YOUR-PASSWORD]@aws-0-us-east-1.pooler.supabase.com:5432/postgres Pricing[#](https://supabase.com/docs/guides/platform/ipv4-address#pricing) --------------------------------------------------------------------------- For a detailed breakdown of how charges are calculated, refer to [Manage IPv4 usage](https://supabase.com/docs/guides/platform/manage-your-usage/ipv4) . ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/platform/ipv4-address%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/platform/ipv4-address%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Pricing | Supabase Docs Storage Pricing =========== * * * You are charged for the total size of all assets in your buckets. $0.00002919 per GB-Hr ($0.021 per GB per month). You are only charged for usage exceeding your subscription plan's quota. | Plan | Quota in GB | Over-Usage per GB | Quota in GB-Hrs | Over-Usage per GB-Hr | | --- | --- | --- | --- | --- | | Free | 1 | \- | 744 | \- | | Pro | 100 | $0.021 | 74,400 | $0.00002919 | | Team | 100 | $0.021 | 74,400 | $0.00002919 | | Enterprise | Custom | Custom | Custom | Custom | For a detailed explanation of how charges are calculated, refer to [Manage Storage size usage](https://supabase.com/docs/guides/platform/manage-your-usage/storage-size) . If you use [Storage Image Transformations](https://supabase.com/docs/guides/storage/serving/image-transformations) , additional charges apply. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/storage/pricing%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/storage/pricing%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Storage | Supabase Docs Storage Storage =========== Use Supabase to store and serve files. ------------------------------------------ * * * Supabase Storage is a robust, scalable solution for managing files of any size with fine-grained access controls and optimized delivery. Whether you're storing user-generated content, analytics data, or vector embeddings, Supabase Storage provides specialized bucket types to meet your specific needs. Key features[#](https://supabase.com/docs/guides/storage#key-features) ----------------------------------------------------------------------- * **Multi Protocol** - S3 compatible Storage, RESTful API, TUS resumable uploads * **Global CDN** - Serve your assets with lightning-fast performance from over 285 cities worldwide * **Image Optimization** - Resize, compress, and transform media files on the fly with built-in image processing * **Fine-grained Access Control** - Manage file permissions with row-level security and custom policies * **Multiple Bucket Types** - Specialized storage solutions for different use cases Storage bucket types[#](https://supabase.com/docs/guides/storage#storage-bucket-types) --------------------------------------------------------------------------------------- Supabase Storage offers different bucket types optimized for specific use cases: ### Files buckets[#](https://supabase.com/docs/guides/storage#files-buckets) Store and serve traditional files including images, videos, documents, and general-purpose content. Ideal for user-generated content, media libraries, and asset management. **Use cases:** Images, videos, documents, PDFs, archives **Features:** * Global CDN delivery * Image optimization and transformation * Row-level security integration * Direct URL access for files [Learn more about Files Buckets](https://supabase.com/docs/guides/storage/quickstart) ### Analytics buckets[#](https://supabase.com/docs/guides/storage#analytics-buckets) Purpose-built for storing and analyzing data in open table formats like Apache Iceberg. Perfect for time-series data, logs, and large-scale analytical workloads. **Use cases:** Data lakes, analytics pipelines, ETL operations, historical data analysis **Features:** * Apache Iceberg table format support * SQL-accessible via Postgres foreign tables * Partitioned data organization * Efficient data querying and transformation [Learn more about Analytics Buckets](https://supabase.com/docs/guides/storage/analytics/introduction) ### Vector buckets[#](https://supabase.com/docs/guides/storage#vector-buckets) Specialized storage for vector embeddings and similarity search operations. Designed for AI and ML applications requiring semantic search capabilities. **Use cases:** AI-powered search, semantic similarity matching, embedding storage, RAG systems **Features:** * Optimized vector indexing (HNSW, Flat) * Multiple distance metrics (cosine, euclidean, L2) * Metadata filtering for vectors * Similarity search queries [Learn more about Vector Buckets](https://supabase.com/docs/guides/storage/vector/introduction) Examples[#](https://supabase.com/docs/guides/storage#examples) --------------------------------------------------------------- Check out all of the Storage [templates and examples](https://github.com/supabase/supabase/tree/master/examples/storage) in our GitHub repository. [![Resumable Uploads with Uppy](https://supabase.com/docs/img/icons/github-icon-light.svg)\ \ Resumable Uploads with Uppy\ \ Use Uppy to upload files to Supabase Storage using the TUS protocol (resumable uploads).](https://github.com/supabase/supabase/tree/master/examples/storage/resumable-upload-uppy) Resources[#](https://supabase.com/docs/guides/storage#resources) ----------------------------------------------------------------- Find the source code and documentation in the Supabase GitHub repository. [Supabase Storage API\ \ View the source code.](https://github.com/supabase/storage-api) [OpenAPI Spec\ \ See the Swagger Documentation for Supabase Storage.](https://supabase.github.io/storage/) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/storage%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/storage%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Copy Storage Objects from Platform | Supabase Docs Self-Hosting Copy Storage Objects from Platform ====================================== Copy storage objects from a managed Supabase project to a self-hosted instance using rclone. ------------------------------------------------------------------------------------------------ * * * This guide walks you through copying storage objects from a managed Supabase platform project to a self-hosted instance using [rclone](https://rclone.org/) with S3-to-S3 copy. Direct file copy (e.g., downloading files and placing them into `volumes/storage/`) does not work. Self-hosted Storage uses an internal file structure that differs from what you get when downloading files from the platform. Use the S3 protocol to transfer objects so that Storage creates the correct metadata records. Before you begin[#](https://supabase.com/docs/guides/self-hosting/copy-from-platform-s3#before-you-begin) ---------------------------------------------------------------------------------------------------------- You need: * A working self-hosted Supabase instance with the S3 protocol endpoint enabled - see [Configure S3 Storage](https://supabase.com/docs/guides/self-hosting/self-hosted-s3#enable-the-s3-protocol-endpoint) * Your platform project's S3 credentials - generated from the [S3 Configuration](https://supabase.com/dashboard/project/_/storage/s3) page * Matching buckets created on your self-hosted instance * [rclone](https://rclone.org/install/) installed on the machine running the copy Step 1: Get platform S3 credentials[#](https://supabase.com/docs/guides/self-hosting/copy-from-platform-s3#step-1-get-platform-s3-credentials) ----------------------------------------------------------------------------------------------------------------------------------------------- In your managed Supabase project dashboard, go to **Storage** > **S3 Configuration** > **Access keys**. Generate a new access key pair and copy: * **Endpoint**: `https://.supabase.co/storage/v1/s3` * **Region**: your project's region (e.g., `us-east-1`) * **Access Key ID** and **Secret access key** For better performance with large files, use the direct storage hostname: `https://.storage.supabase.co/storage/v1/s3` Step 2: Create buckets on self-hosted[#](https://supabase.com/docs/guides/self-hosting/copy-from-platform-s3#step-2-create-buckets-on-self-hosted) --------------------------------------------------------------------------------------------------------------------------------------------------- Buckets must exist on the destination before you can copy objects into them. You can create them through dashboard UI, or with **SQL Editor**. If you already restored your platform database to self-hosted using the [restore guide](https://supabase.com/docs/guides/self-hosting/restore-from-platform) , your bucket definitions are already present. You can skip this step. To list your platform buckets, connect to your platform database and run: 1select id, name, public from storage.buckets order by name; Then create matching buckets on your self-hosted instance. Connect to your self-hosted database and run: 1insert into storage.buckets (id, name, public)2values3 ('your-storage-bucket', 'your-storage-bucket', false)4on conflict (id) do nothing; Repeat for each bucket, setting `public` to `true` or `false` as appropriate. Step 3: Configure rclone[#](https://supabase.com/docs/guides/self-hosting/copy-from-platform-s3#step-3-configure-rclone) ------------------------------------------------------------------------------------------------------------------------- Create or edit your rclone configuration file (`~/.config/rclone/rclone.conf`): 1[platform]2type = s33provider = Other4access_key_id = your-platform-access-key-id5secret_access_key = your-platform-secret-access-key6endpoint = https://your-project-ref.supabase.co/storage/v1/s37region = your-project-region89[self-hosted]10type = s311provider = Other12access_key_id = your-self-hosted-access-key-id13secret_access_key = your-self-hosted-secret-access-key14endpoint = http://your-domain:8000/storage/v1/s315region = your-self-hosted-region Replace the credentials with your actual values. For self-hosted, use the `REGION`, `S3_PROTOCOL_ACCESS_KEY_ID` and `S3_PROTOCOL_ACCESS_KEY_SECRET` you configured in [Configure S3 Storage](https://supabase.com/docs/guides/self-hosting/self-hosted-s3#enable-the-s3-protocol-endpoint) . Verify both remotes connect: 1rclone lsd platform:2rclone lsd self-hosted: Both commands should list your buckets. Step 4: Copy objects[#](https://supabase.com/docs/guides/self-hosting/copy-from-platform-s3#step-4-copy-objects) ----------------------------------------------------------------------------------------------------------------- Copy a single bucket: 1rclone copy platform:your-storage-bucket self-hosted:your-storage-bucket --progress To copy all buckets: 1for bucket in $(rclone lsf platform: | tr -d '/'); do2 echo "Copying bucket: $bucket"3 rclone copy "platform:$bucket" "self-hosted:$bucket" --progress4done For large migrations, consider adding `--transfers 4` to increase parallelism, or `--checkers 8` to speed up the comparison phase. See the [flags documentation](https://rclone.org/flags/) for all options. Verify[#](https://supabase.com/docs/guides/self-hosting/copy-from-platform-s3#verify) -------------------------------------------------------------------------------------- Compare object counts between source and destination: 1rclone size platform:your-storage-bucket && \2rclone size self-hosted:your-storage-bucket Open Studio on your self-hosted instance and browse the storage buckets to confirm files are accessible. Troubleshooting[#](https://supabase.com/docs/guides/self-hosting/copy-from-platform-s3#troubleshooting) -------------------------------------------------------------------------------------------------------- ### Signature errors[#](https://supabase.com/docs/guides/self-hosting/copy-from-platform-s3#signature-errors) If you see `SignatureDoesNotMatch` when connecting to either remote: * **Platform**: Regenerate S3 access keys from your project's Storage Settings. Ensure the endpoint URL includes `/storage/v1/s3`. * **Self-hosted**: Verify that `REGION`, `S3_PROTOCOL_ACCESS_KEY_ID` and `S3_PROTOCOL_ACCESS_KEY_SECRET` in `.env` file match your rclone config. ### Bucket not found[#](https://supabase.com/docs/guides/self-hosting/copy-from-platform-s3#bucket-not-found) If rclone reports that a bucket doesn't exist on the self-hosted side, create it first - see [Step 2](https://supabase.com/docs/guides/self-hosting/copy-from-platform-s3#step-2-create-buckets-on-self-hosted) . The S3 protocol does not auto-create buckets on copy. ### Timeouts on large files[#](https://supabase.com/docs/guides/self-hosting/copy-from-platform-s3#timeouts-on-large-files) For very large files, increase rclone's timeout: 1rclone copy platform:your-storage-bucket self-hosted:your-storage-bucket --timeout 30m ### Empty listing on platform[#](https://supabase.com/docs/guides/self-hosting/copy-from-platform-s3#empty-listing-on-platform) If `rclone lsd platform:` returns nothing, verify the endpoint URL ends with `/storage/v1/s3` and that the S3 access keys have not expired. Regenerate them from the dashboard if needed. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/self-hosting/copy-from-platform-s3%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/self-hosting/copy-from-platform-s3%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Configure Reverse Proxy and HTTPS | Supabase Docs Self-Hosting Configure Reverse Proxy and HTTPS ===================================== Set up a reverse proxy with HTTPS for self-hosted Supabase. --------------------------------------------------------------- * * * HTTPS is required for production self-hosted Supabase deployments. This guide covers two production approaches using a reverse proxy in front of self-hosted Supabase API gateway, plus a self-signed certificate option for development environment. Before you begin[#](https://supabase.com/docs/guides/self-hosting/self-hosted-proxy-https#before-you-begin) ------------------------------------------------------------------------------------------------------------ You need: * A working self-hosted Supabase installation. See [Self-Hosting with Docker](https://supabase.com/docs/guides/self-hosting/docker) . * A domain name with DNS pointing to your server's public IP address (to obtain Let's Encrypt certificate). * Ports 80 and 443 open. Set up HTTPS[#](https://supabase.com/docs/guides/self-hosting/self-hosted-proxy-https#set-up-https) ---------------------------------------------------------------------------------------------------- Below are two options for adding a reverse proxy with automatic HTTPS in front of your self-hosted Supabase: **Caddy** (simpler, zero-config TLS) and **Nginx + Let's Encrypt** (more control over proxy settings). Both sit in front of Kong and terminate TLS, so internal traffic stays on HTTP. ##### Using a different reverse proxy? If you already run [HAProxy](https://www.haproxy.com/) , [Traefik](https://traefik.io/) , [Nginx Proxy Manager](https://nginxproxymanager.com/) , or another reverse proxy for your infrastructure, you can use it instead of Caddy or Nginx above. The key requirements are: * Proxy to Kong on port `8000` (or `:8000` if the proxy runs outside the Docker network) * Enable WebSocket support (required for Realtime) * Proxy traffic to Storage directly to the container, bypassing Kong * Add `X-Forwarded` headers to all requests * Comment out Kong's host port bindings in `docker-compose.yml` if the proxy runs in the same Docker network * Update `SUPABASE_PUBLIC_URL`, `API_EXTERNAL_URL`, and `SITE_URL` in `.env` to your HTTPS URL ### Step 1: Update environment variables[#](https://supabase.com/docs/guides/self-hosting/self-hosted-proxy-https#step-1-update-environment-variables) Update the URL configuration in your `.env` file to use your HTTPS domain: 1SUPABASE_PUBLIC_URL=https://2API_EXTERNAL_URL=https://3SITE_URL=https:// Change the following to your domain name and a **valid** email address: 1PROXY_DOMAIN=your-domain.example.com2CERTBOT_EMAIL=admin@your-domain.example.com ### Step 2: Start the reverse proxy[#](https://supabase.com/docs/guides/self-hosting/self-hosted-proxy-https#step-2-start-the-reverse-proxy) Pick one of the options below and use the corresponding Docker Compose overlay. Caddy (easiest)Nginx + Let's Encrypt [Caddy](https://caddyserver.com/) automatically provisions and renews Let's Encrypt TLS certificates with zero configuration. It also handles HTTP-to-HTTPS redirects, WebSocket upgrades, and HTTP/2 and HTTP/3 out of the box. Start Caddy by using the pre-configured `docker-compose.caddy.yml` overlay: 1docker compose -f docker-compose.yml -f docker-compose.caddy.yml up -d Caddy configuration is in `volumes/proxy/caddy/Caddyfile`. ### Step 3: Verify HTTPS connection[#](https://supabase.com/docs/guides/self-hosting/self-hosted-proxy-https#step-3-verify-https-connection) 1curl -I https:///auth/v1/ You should receive a `401` response confirming you could connect to Auth. Self-signed certificates (development only)[#](https://supabase.com/docs/guides/self-hosting/self-hosted-proxy-https#self-signed-certificates-development-only) ---------------------------------------------------------------------------------------------------------------------------------------------------------------- Self-signed certificates trigger browser warnings and are rejected by most OAuth providers. Use this approach only in development environment or internal networks. For development or internal networks where you cannot use Let's Encrypt, you can configure Kong to serve HTTPS directly using self-signed certificates. ### Step 1: Generate a self-signed certificate[#](https://supabase.com/docs/guides/self-hosting/self-hosted-proxy-https#step-1-generate-a-self-signed-certificate) Change `` in the example below, and create certificates with `openssl`: 1openssl req -x509 -nodes -days 365 -newkey rsa:2048 \2 -keyout volumes/api/server.key \3 -out volumes/api/server.crt \4 -subj "/CN=" && \5 chmod 640 volumes/api/server.key && \6 chgrp 65533 volumes/api/server.key ### Step 2: Configure Kong for SSL[#](https://supabase.com/docs/guides/self-hosting/self-hosted-proxy-https#step-2-configure-kong-for-ssl) Comment out Kong's **HTTP** port mapping in `docker-compose.yml`: 1kong:2 # ...3 ports:4 #- ${KONG_HTTP_PORT}:8000/tcp Uncomment the certificate volume mounts and SSL environment variables in `docker-compose.yml`: 1kong:2 # ... existing configuration ...3 volumes:4 - ./volumes/api/kong.yml:/home/kong/temp.yml:ro,z5 - ./volumes/api/server.crt:/home/kong/server.crt:ro6 - ./volumes/api/server.key:/home/kong/server.key:ro7 environment:8 # ... existing environment variables ...9 KONG_SSL_CERT: /home/kong/server.crt10 KONG_SSL_CERT_KEY: /home/kong/server.key ### Step 3: Update configuration variables[#](https://supabase.com/docs/guides/self-hosting/self-hosted-proxy-https#step-3-update-configuration-variables) Edit your `.env` file to use HTTPS with the Kong HTTPS port: 1SUPABASE_PUBLIC_URL=https://:84432API_EXTERNAL_URL=https://:84433SITE_URL=https://:8443 ### Step 4: Restart and verify[#](https://supabase.com/docs/guides/self-hosting/self-hosted-proxy-https#step-4-restart-and-verify) 1docker compose down && docker compose up -d 1curl -I -k https://:8443/auth/v1/ The `-k` flag tells curl to accept the self-signed certificate. Troubleshooting[#](https://supabase.com/docs/guides/self-hosting/self-hosted-proxy-https#troubleshooting) ---------------------------------------------------------------------------------------------------------- ### Certificate not issued[#](https://supabase.com/docs/guides/self-hosting/self-hosted-proxy-https#certificate-not-issued) If Caddy or Certbot fails to obtain a certificate: * Verify that ports 80 and 443 are open on your firewall * Verify that your domain's DNS A record points to your server's public IP * Check proxy logs via `docker logs supabase-caddy` or `docker logs supabase-nginx` * Let's Encrypt has [rate limits](https://letsencrypt.org/docs/rate-limits/) - if you hit them, wait before retrying ### WebSocket connection failed[#](https://supabase.com/docs/guides/self-hosting/self-hosted-proxy-https#websocket-connection-failed) If Realtime subscriptions fail to connect: * **Caddy** handles WebSocket upgrades automatically - check that Kong is healthy * **Nginx** requires explicit `Upgrade` and `Connection` headers on the `/realtime/v1/` location. Verify your `nginx.conf` includes these headers as shown above ### OAuth callback URL mismatch[#](https://supabase.com/docs/guides/self-hosting/self-hosted-proxy-https#oauth-callback-url-mismatch) If OAuth redirects fail with a callback URL error: * Verify `API_EXTERNAL_URL` in `.env` is set to your HTTPS URL * Verify the callback URL registered with your OAuth provider matches `API_EXTERNAL_URL` followed by `/auth/v1/callback` * After changing `API_EXTERNAL_URL`, restart all services with `docker compose down && docker compose up -d` ### Mixed content warnings[#](https://supabase.com/docs/guides/self-hosting/self-hosted-proxy-https#mixed-content-warnings) If the browser console shows mixed content errors: * Verify `SUPABASE_PUBLIC_URL` is set to your HTTPS URL * Verify `SITE_URL` is also set to HTTPS * Clear your browser cache after making changes ### ERR\_CERT\_AUTHORITY\_INVALID[#](https://supabase.com/docs/guides/self-hosting/self-hosted-proxy-https#errcertauthorityinvalid) This is expected when using self-signed certificates. For production, use Caddy or Nginx with Let's Encrypt. If you need to use self-signed certificates, add the certificate to your system's trust store or use a browser flag to bypass the warning. Additional resources[#](https://supabase.com/docs/guides/self-hosting/self-hosted-proxy-https#additional-resources) -------------------------------------------------------------------------------------------------------------------- * [Caddy documentation](https://caddyserver.com/docs/) * [Nginx documentation](https://nginx.org/en/docs/) (on nginx.org) * [docker-nginx-certbot on GitHub](https://github.com/JonasAlfredsson/docker-nginx-certbot) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/self-hosting/self-hosted-proxy-https%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/self-hosting/self-hosted-proxy-https%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Restore a Platform Project to Self-Hosted | Supabase Docs Self-Hosting Restore a Platform Project to Self-Hosted ============================================= Restore your database from the Supabase platform to a self-hosted instance. ------------------------------------------------------------------------------- * * * This guide walks you through restoring your database from a Supabase platform project to a [self-hosted Docker instance](https://supabase.com/docs/guides/self-hosting/docker) . Storage objects transfer or redeploying edge functions is not covered here. Before you begin[#](https://supabase.com/docs/guides/self-hosting/restore-from-platform#before-you-begin) ---------------------------------------------------------------------------------------------------------- You need: * A new self-hosted Supabase instance ([Docker setup guide](https://supabase.com/docs/guides/self-hosting/docker) ) * [Supabase CLI](https://supabase.com/docs/guides/local-development/cli/getting-started) installed (or use `npx supabase`) * [Docker Desktop](https://docs.docker.com/get-started/get-docker/) installed (required by the CLI) * `psql` installed ([official installation guide](https://www.postgresql.org/download/) ) * Your Supabase database passwords (for platform and self-hosted) Step 1: Get your platform connection string[#](https://supabase.com/docs/guides/self-hosting/restore-from-platform#step-1-get-your-platform-connection-string) --------------------------------------------------------------------------------------------------------------------------------------------------------------- On your managed Supabase project dashboard, click [**Connect**](https://supabase.com/dashboard/project/_?showConnect=true) and copy the connection string (use the session pooler or direct connection). Step 2: Back up your platform database[#](https://supabase.com/docs/guides/self-hosting/restore-from-platform#step-2-back-up-your-platform-database) ----------------------------------------------------------------------------------------------------------------------------------------------------- Export roles, schema, and data as three separate SQL files: 1supabase db dump --db-url "[CONNECTION_STRING]" -f roles.sql --role-only 1supabase db dump --db-url "[CONNECTION_STRING]" -f schema.sql 1supabase db dump --db-url "[CONNECTION_STRING]" -f data.sql --use-copy --data-only This produces SQL files that are compatible across Postgres versions. Using `supabase db dump` executes `pg_dump` under the hood but applies Supabase-specific filtering - it excludes internal schemas, strips reserved roles, and adds idempotent `IF NOT EXISTS` clauses. Using raw `pg_dump` directly will include Supabase internals and cause permission errors during restore. CLI requires Docker because it runs `pg_dump` inside a container from the Supabase Postgres image rather than requiring a local Postgres installation. Step 3: Prepare your self-hosted instance[#](https://supabase.com/docs/guides/self-hosting/restore-from-platform#step-3-prepare-your-self-hosted-instance) ----------------------------------------------------------------------------------------------------------------------------------------------------------- Before restoring, check the following on your self-hosted instance: * **Extensions**: Enable any non-default extensions your Supabase project uses. You can check which extensions are active by querying `select * from pg_extension;` on your managed database (or check Database Extensions in Dashboard). Step 4: Restore to your self-hosted database[#](https://supabase.com/docs/guides/self-hosting/restore-from-platform#step-4-restore-to-your-self-hosted-database) ----------------------------------------------------------------------------------------------------------------------------------------------------------------- Connect to your self-hosted Postgres and restore the dump files. The [default](https://supabase.com/docs/guides/self-hosting/docker#accessing-postgres) connection string for self-hosted Supabase is: 1postgres://postgres.your-tenant-id:[POSTGRES_PASSWORD]@[your-domain]:5432/postgres Where `[POSTGRES_PASSWORD]` is the value of `POSTGRES_PASSWORD` in your self-hosted `.env` file. Use your domain name, your server IP, or localhost for `[your-domain]` depending on whether you are running self-hosted Supabase on a VPS, or locally. Run `psql` to restore: 1psql \2 --single-transaction \3 --variable ON_ERROR_STOP=1 \4 --file roles.sql \5 --file schema.sql \6 --command 'SET session_replication_role = replica' \7 --file data.sql \8 --dbname "postgres://postgres.your-tenant-id:[POSTGRES_PASSWORD]@[your-domain]:5432/postgres" Setting `session_replication_role` to `replica` disables triggers during the data import, preventing issues like double-encryption of columns. Step 5: Verify the restore[#](https://supabase.com/docs/guides/self-hosting/restore-from-platform#step-5-verify-the-restore) ----------------------------------------------------------------------------------------------------------------------------- Connect to your self-hosted database and run a few checks: 1psql "postgres://postgres.your-tenant-id:[POSTGRES_PASSWORD]@[your-domain]:5432/postgres" 1-- Check your tables are present2\dt public.*34-- Verify row counts on key tables5SELECT count(*) FROM auth.users;67-- Check extensions8SELECT * FROM pg_extension; What's included in the restore and what's not[#](https://supabase.com/docs/guides/self-hosting/restore-from-platform#whats-included-in-the-restore-and-whats-not) ------------------------------------------------------------------------------------------------------------------------------------------------------------------ The database dump includes your schema, data, roles, RLS policies, database functions, triggers, and `auth.users`. However, several things require separate configuration on your self-hosted instance: | Requires manual setup | How to configure | | --- | --- | | JWT secrets and API keys | Generate new ones and update `.env` | | Auth provider settings (OAuth, Apple, etc.) | Configure `GOTRUE_EXTERNAL_*` variables in `.env` | | Edge functions | Manually copy to your self-hosted instance | | Storage objects | Transfer separately (not covered in this guide) | | SMTP / email settings | Configure `SMTP_*` variables in `.env` | | Custom domains and DNS | Point your DNS to the self-hosted server | Auth considerations[#](https://supabase.com/docs/guides/self-hosting/restore-from-platform#auth-considerations) ---------------------------------------------------------------------------------------------------------------- Your `auth.users` table and related data are included in the database dump, so user accounts are preserved. However: * **JWT secrets differ** between your platform and self-hosted instances. Existing tokens issued by the platform project will not be valid. Users will need to re-authenticate. * **Social auth providers** (Apple, Google, GitHub, etc.) need to be configured in your self-hosted `.env` file. Set the relevant `GOTRUE_EXTERNAL_*` variables. See the Auth repository [README](https://github.com/supabase/auth) for all available options. * **Redirect URLs** in your OAuth provider consoles (Apple Developer, Google Cloud Console, etc.) must be updated to point to your self-hosted hostname instead of `*.supabase.co`. Postgres version compatibility[#](https://supabase.com/docs/guides/self-hosting/restore-from-platform#postgres-version-compatibility) -------------------------------------------------------------------------------------------------------------------------------------- Managed Supabase may run a newer Postgres version (Postgres 17) than the self-hosted Docker image (currently Postgres 15). The `supabase db dump` command produces plain SQL files that work across major Postgres versions. Keep in mind: * The data dump may include Postgres 17-only settings or reference tables/columns from newer Auth and Storage versions that don't exist on self-hosted yet. See [Version mismatches](https://supabase.com/docs/guides/self-hosting/restore-from-platform#version-mismatches-between-platform-and-self-hosted) in the troubleshooting section. * Run the restore on a test self-hosted instance first to identify any incompatibilities. * Check that all extensions you use are available on the self-hosted Postgres version. Troubleshooting[#](https://supabase.com/docs/guides/self-hosting/restore-from-platform#troubleshooting) -------------------------------------------------------------------------------------------------------- ### Version mismatches between platform and self-hosted[#](https://supabase.com/docs/guides/self-hosting/restore-from-platform#version-mismatches-between-platform-and-self-hosted) The platform may run a newer Postgres version (17 vs 15) and newer Auth service versions than self-hosted. The data dump can contain settings, tables, or columns that don't exist on your new self-hosted instance. **Common issues in `data.sql`:** * `SET transaction_timeout = 0` - a Postgres 17-only setting that fails on Postgres 15 * `COPY` statements for tables that don't exist on self-hosted (e.g., `auth.oauth_clients`, `storage.buckets_vectors`, `storage.vector_indexes`) * `COPY` statements with columns added in newer Auth versions (e.g., `auth.flow_state` with `oauth_client_state_id`, `linking_target_id`) **Workaround:** Edit `data.sql` before restoring: 1# Comment out PG17-only transaction_timeout2sed -i 's/^SET transaction_timeout/-- &/' data.sql For missing tables or column mismatches, comment out the relevant `COPY ... FROM stdin;` line and its corresponding `\.` terminator. Run the restore without `--single-transaction` first to identify all failures, then fix them and run the final restore with `--single-transaction`. Keeping your self-hosted configuration [up to date](https://github.com/supabase/supabase/blob/master/docker/CHANGELOG.md) will minimize these gaps. ### Extension not available[#](https://supabase.com/docs/guides/self-hosting/restore-from-platform#extension-not-available) If the restore fails because an extension isn't available, check whether it's supported on your self-hosted Postgres version. You can list available extensions with: 1select * from pg_available_extensions; ### Connection refused[#](https://supabase.com/docs/guides/self-hosting/restore-from-platform#connection-refused) Make sure your self-hosted Postgres port is accessible. In the default [self-hosted Supabase](https://supabase.com/docs/guides/self-hosting/docker#accessing-postgres) setup, the user is `postgres.your-tenant-id` with Supavisor on port `5432`. ### Legacy Studio configuration[#](https://supabase.com/docs/guides/self-hosting/restore-from-platform#legacy-studio-configuration) Studio in self-hosted Supabase historically used `supabase_admin` role (superuser) instead of `postgres`. Objects created via Studio UI were owned by `supabase_admin`. Check your `docker-compose.yml` [configuration](https://github.com/supabase/supabase/blob/2cb5befaa377a42b6d6ca152b98105b59054f2f4/docker/docker-compose.yml#L30) to see if `POSTGRES_USER_READ_WRITE` is set to `postgres`. ### Custom roles missing passwords[#](https://supabase.com/docs/guides/self-hosting/restore-from-platform#custom-roles-missing-passwords) If you created custom database roles with the `LOGIN` attribute on your platform project, their passwords are not included in the dump. Set them manually after restore: 1ALTER ROLE your_custom_role WITH PASSWORD 'new-password'; ### Additional resources[#](https://supabase.com/docs/guides/self-hosting/restore-from-platform#additional-resources) * [Backup and Restore using the CLI](https://supabase.com/docs/guides/platform/migrating-within-supabase/backup-restore) * [Restore Dashboard backup](https://supabase.com/docs/guides/platform/migrating-within-supabase/dashboard-restore) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/self-hosting/restore-from-platform%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/self-hosting/restore-from-platform%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # About billing on Supabase | Supabase Docs Platform About billing on Supabase ============================= * * * Subscription plans[#](https://supabase.com/docs/guides/platform/billing-on-supabase#subscription-plans) -------------------------------------------------------------------------------------------------------- Supabase offers different subscription plans—Free, Pro, Team, and Enterprise. For a closer look at each plan's features and pricing, visit our [pricing page](https://supabase.com/pricing) . ### Free Plan[#](https://supabase.com/docs/guides/platform/billing-on-supabase#free-plan) The Free Plan helps you get started and explore the platform. You are granted two free projects. The project limit applies across all organizations where you are an Owner or Administrator. This means you could have two Free Plan organizations with one project each, or one Free Plan organization with two projects. Paused projects do not count towards your free project limit. ### Paid plans[#](https://supabase.com/docs/guides/platform/billing-on-supabase#paid-plans) Upgrading your organization to a paid plan provides additional features, and you receive a higher [usage quota](https://supabase.com/docs/guides/platform/billing-on-supabase#variable-usage-fees-and-quotas) . You unlock the benefits of the paid plan for all projects within your organization - for example, no projects in your Pro Plan organization will be paused. Organization-based billing[#](https://supabase.com/docs/guides/platform/billing-on-supabase#organization-based-billing) ------------------------------------------------------------------------------------------------------------------------ Supabase bills separately for each organization. Each organization has its own subscription, including a unique subscription plan (Free, Pro, Team, or Enterprise), payment method, billing cycle, and invoices. Different plans cannot be mixed within a single organization. For example, you cannot have both a Pro Plan project and a Free Plan project in the same organization. To have projects on different plans, you must create separate organizations. See [Project Transfers](https://supabase.com/docs/guides/platform/project-transfer) if you need to move a project to a different organization. ![Organization-based billing](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fguides%2Fplatform%2Fbilling-overview--light.png&w=3840&q=75) Costs[#](https://supabase.com/docs/guides/platform/billing-on-supabase#costs) ------------------------------------------------------------------------------ Monthly costs for paid plans include a fixed subscription fee based on your chosen plan and variable usage fees. To learn more about billing and cost management, refer to the following resources. * [Your monthly invoice](https://supabase.com/docs/guides/platform/your-monthly-invoice) - For a detailed breakdown of what a monthly invoice includes * [Manage your usage](https://supabase.com/docs/guides/platform/manage-your-usage) - For details on how the different usage items are billed, and how to optimize usage and reduce costs * [Control your costs](https://supabase.com/docs/guides/platform/cost-control) - For details on how you can control your costs in case unexpected high usage occurs ### Compute costs for projects[#](https://supabase.com/docs/guides/platform/billing-on-supabase#compute-costs-for-projects) An organization can have multiple projects. Each project includes a dedicated Postgres instance running on its own server. You are charged for the Compute resources of that server, independent of your database usage. Each project you launch increases your monthly Compute costs. Read more about [Compute costs](https://supabase.com/docs/guides/platform/manage-your-usage/compute) . Variable Usage Fees and Quotas[#](https://supabase.com/docs/guides/platform/billing-on-supabase#variable-usage-fees-and-quotas) -------------------------------------------------------------------------------------------------------------------------------- Each subscription plan includes a built-in quota for some selected usage items, such as [Egress](https://supabase.com/docs/guides/platform/manage-your-usage/egress) , [Storage Size](https://supabase.com/docs/guides/platform/manage-your-usage/storage-size) , or [Edge Function Invocations](https://supabase.com/docs/guides/platform/manage-your-usage/edge-function-invocations) . This quota represents your free usage allowance. If you stay within it, you incur no extra charges for these items. Only usage beyond the quota is billed as overage. For usage items without a quota, such as [Compute](https://supabase.com/docs/guides/platform/manage-your-usage/compute) or [Custom Domains](https://supabase.com/docs/guides/platform/manage-your-usage/custom-domains) , you are charged for your entire usage. The quota is applied to your entire organization, independent of how many projects you launch within that organization. For billing purposes, we sum the usage across all projects in a monthly invoice. | Usage Item | Free | Pro/Team | Enterprise | | --- | --- | --- | --- | | Egress | 5 GB | 250 GB included, then $0.09 per GB | Custom | | Database Size | 500 MB per project | 8 GB disk per project included, then $0.125 per GB | Custom | | Monthly Active Users | 50,000 MAU | 100,000 MAU included, then $0.00325 per MAU | Custom | | Monthly Active Third-Party Users | 50,000 MAU | 100,000 MAU included, then $0.00325 per MAU | Custom | | Monthly Active SSO Users | Unavailable on Free Plan | 50 MAU included, then $0.015 per MAU | Custom | | Storage Size | 1 GB | 100 GB included, then $0.021 per GB | Custom | | Storage Images Transformed | Unavailable on Free Plan | 100 included, then $5 per 1000 | Custom | | Edge Function Invocations | 500,000 | 2 million included, then $2 per million | Custom | | Realtime Message Count | 2 million | 5 million included, then $2.5 per million | Custom | | Realtime Peak Connections | 200 | 500 included, then $10 per 1000 | Custom | You can find a detailed breakdown of all usage items and how they are billed on the [Manage your usage](https://supabase.com/docs/guides/platform/manage-your-usage) page. Project add-ons[#](https://supabase.com/docs/guides/platform/billing-on-supabase#project-add-ons) -------------------------------------------------------------------------------------------------- While your subscription plan applies to your entire organization and is charged only once, you can enhance individual projects by opting into various add-ons. * [Compute](https://supabase.com/docs/guides/platform/compute-and-disk#compute) to scale your database up to 64 cores and 256 GB RAM * [Read Replicas](https://supabase.com/docs/guides/platform/read-replicas) to scale read operations and provide resiliency * [Disk](https://supabase.com/docs/guides/platform/compute-and-disk#disk) to provision extra IOPS/throughput or use a high-performance SSD * [Log Drains](https://supabase.com/docs/guides/telemetry/log-drains) to sync Supabase logs to a logging system of your choice * [Custom Domains](https://supabase.com/docs/guides/platform/custom-domains) to provide a branded experience * [PITR](https://supabase.com/docs/guides/platform/backups#point-in-time-recovery) to roll back to any specific point in time, down to the minute * [IPv4](https://supabase.com/docs/guides/platform/ipv4-address) for a dedicated IPv4 address * [Advanced MFA](https://supabase.com/docs/guides/auth/auth-mfa/phone) to provide other options than TOTP ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/platform/billing-on-supabase%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/platform/billing-on-supabase%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Enable SSO for Your Organization | Supabase Docs Platform Enable SSO for Your Organization ==================================== * * * Looking for docs on how to add Single Sign-On support in your Supabase project? Head on over to [Single Sign-On with SAML 2.0 for Projects](https://supabase.com/docs/guides/auth/enterprise-sso/auth-sso-saml) . Supabase offers single sign-on (SSO) as a login option to provide additional account security for your team. This allows company administrators to enforce the use of an identity provider when logging into Supabase. SSO improves the onboarding and offboarding experience of the company as the employee only needs a single set of credentials to access third-party applications or tools which can also be revoked by an administrator. Supabase currently provides SAML SSO for [Team and Enterprise Plan customers](https://supabase.com/pricing) . If you are an existing Team or Enterprise Plan customer, continue with the setup below. Supported providers[#](https://supabase.com/docs/guides/platform/sso#supported-providers) ------------------------------------------------------------------------------------------ Supabase supports practically all identity providers that support the SAML 2.0 SSO protocol. We've prepared these guides for commonly used identity providers to help you get started. If you use a different provider, our support stands ready to support you. * [Google Workspaces (formerly G Suite)](https://supabase.com/docs/guides/platform/sso/gsuite) * [Azure Active Directory](https://supabase.com/docs/guides/platform/sso/azure) * [Okta](https://supabase.com/docs/guides/platform/sso/okta) Once configured, you can update your settings anytime via the [SSO tab](https://supabase.com/dashboard/org/_/sso) under **Organization Settings**. ![SSO Example](https://supabase.com/docs/img/sso-dashboard-enabled.png) Key configuration options[#](https://supabase.com/docs/guides/platform/sso#key-configuration-options) ------------------------------------------------------------------------------------------------------ * **Multiple domains** - You can associate one or more email domains with your SSO provider. Users with email addresses matching these domains are eligible to sign in via SSO. * **Auto-join** - Optionally allow users with a matching domain to be added to your organization automatically when they first sign in, without an invitation. * **Default role for auto-joined users** - Choose the role (e.g., `Read-only`, `Developer`, `Administrator`, `Owner`) that automatically joined users receive. Refer to [access control](https://supabase.com/docs/guides/platform/access-control) for more information about roles. How SSO works in Supabase[#](https://supabase.com/docs/guides/platform/sso#how-sso-works-in-supabase) ------------------------------------------------------------------------------------------------------ When SSO is enabled for an organization: * Organization invites are restricted to company members belonging to the same identity provider. * Every user has an organization created by default. They can create as many projects as they want. * An SSO user will not be able to update or reset their password since the company administrator manages their access via the identity provider. * If an SSO user with the following email of `alice@foocorp.com` attempts to sign in with a GitHub account that uses the same email, a separate Supabase account is created and will not be linked to the SSO user's account. * SSO users will only see organizations/projects they've been invited to or auto-joined into. See [access control](https://supabase.com/docs/guides/platform/access-control) for more details. Enabling SSO for an organization[#](https://supabase.com/docs/guides/platform/sso#enabling-sso-for-an-organization) -------------------------------------------------------------------------------------------------------------------- * Review the steps above to configure your setup. * Invite users to the organization and ensure they join with their SSO linked account. * If a user is already a member of the organization under a non SSO account, they will need to be removed and invited again for them to join under their SSO account. **No automatic linking:** Each user account verified using a SSO identity provider will not be automatically linked to existing user accounts in the system. That is, if a user `valid.email@supabase.io` had signed up with a password, and then uses their company SSO login with your project, there will be two `valid.email@supabase.io` user accounts in the system. Users will need to ensure they are logged in with the correct account when accepting invites or accessing organizations/projects. Disabling SSO for an organization[#](https://supabase.com/docs/guides/platform/sso#disabling-sso-for-an-organization) ---------------------------------------------------------------------------------------------------------------------- If you disable the SSO provider for an organization, **all SSO users will immediately be unable to sign in**. Before disabling SSO, ensure you have at least one non-SSO owner account to prevent being locked out. Removing an individual SSO user's access[#](https://supabase.com/docs/guides/platform/sso#removing-an-individual-sso-users-access) ----------------------------------------------------------------------------------------------------------------------------------- To revoke access for a specific SSO user without disabling the provider entirely you may: * Remove or disable the user's account in your identity provider * Downgrade or remove their permissions for any organizations in Supabase. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/platform/sso%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/platform/sso%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Declarative database schemas | Supabase Docs Local Development Declarative database schemas ================================ Manage your database schemas in one place and generate versioned migrations. -------------------------------------------------------------------------------- * * * Overview[#](https://supabase.com/docs/guides/local-development/declarative-database-schemas#overview) ------------------------------------------------------------------------------------------------------ Declarative schemas provide a developer-friendly way to maintain schema migrations. [Migrations](https://supabase.com/docs/guides/deployment/database-migrations) are traditionally managed imperatively (you provide the instructions on how exactly to change the database). This can lead to related information being scattered over multiple migration files. With declarative schemas, you instead declare the state you want your database to be in, and the instructions are generated for you. Schema migrations[#](https://supabase.com/docs/guides/local-development/declarative-database-schemas#schema-migrations) ------------------------------------------------------------------------------------------------------------------------ Schema migrations are SQL statements written in Data Definition Language. They are versioned in your `supabase/migrations` directory to ensure schema consistency between local and remote environments. ### Declaring your schema[#](https://supabase.com/docs/guides/local-development/declarative-database-schemas#declaring-your-schema) 1 ### Create your first schema file Create a SQL file in `supabase/schemas` directory that defines an `employees` table. supabase/schemas/employees.sql 1create table "employees" (2 "id" integer not null,3 "name" text4); 2 ### Generate a migration file Generate a migration file by diffing against your declared schema. Terminal 1supabase db diff -f create_employees_table 3 ### Start the local database and apply migrations Start the local database first. Then, apply the migration manually to see your schema changes in the local Dashboard. Terminal 1supabase start2supabase migration up ### Updating your schema[#](https://supabase.com/docs/guides/local-development/declarative-database-schemas#updating-your-schema) 1 ### Add a new column Edit `supabase/schemas/employees.sql` file to add a new column to `employees` table. supabase/schemas/employees.sql 1create table "employees" (2 "id" integer not null,3 "name" text,4 "age" smallint not null5); Some entities like views and enums expect columns to be declared in a specific order. To avoid messy diffs, always append new columns to the end of the table. 2 ### Generate a new migration Diff existing migrations against your declared schema. Terminal 1supabase db diff -f add_age 3 ### Review the generated migration Verify that the generated migration contain a single incremental change. supabase/migrations/\_add\_age.sql 1alter table "public"."employees" add column "age" smallint not null; 4 ### Apply the pending migration Start the database locally and apply the pending migration. Terminal 1supabase migration up ### Deploying your schema changes[#](https://supabase.com/docs/guides/local-development/declarative-database-schemas#deploying-your-schema-changes) 1 ### Log in to the Supabase CLI [Log in](https://supabase.com/docs/reference/cli/supabase-login) via the Supabase CLI. Terminal 1supabase login 2 ### Link your remote project Follow the on-screen prompts to [link](https://supabase.com/docs/reference/cli/supabase-link) your remote project. Terminal 1supabase link 3 ### Deploy database changes [Push](https://supabase.com/docs/reference/cli/supabase-db-push) your changes to the remote database. Terminal 1supabase db push ### Managing dependencies[#](https://supabase.com/docs/guides/local-development/declarative-database-schemas#managing-dependencies) As your database schema evolves, you will probably start using more advanced entities like views and functions. These entities are notoriously verbose to manage using plain migrations because the entire body must be recreated whenever there is a change. Using declarative schema, you can now edit them in-place so it’s much easier to review. supabase/schemas/employees.sql 1create table "employees" (2 "id" integer not null,3 "name" text,4 "age" smallint not null5);67create view "profiles" as8 select id, name from "employees";910create function "get_age"(employee_id integer) RETURNS smallint11 LANGUAGE "sql"12AS $$13 select age14 from employees15 where id = employee_id;16$$; Your schema files are run in lexicographic order by default. The order is important when you have foreign keys between multiple tables as the parent table must be created first. For example, your `supabase` directory may end up with the following structure. 1.2└── supabase/3 ├── schemas/4 │ ├── employees.sql5 │ └── managers.sql6 └── migrations/7 ├── 20241004112233_create_employees_table.sql8 ├── 20241005112233_add_employee_age.sql9 └── 20241006112233_add_managers_table.sql For small projects with only a few tables, the default schema order may be sufficient. However, as your project grows, you might need more control over the order in which schemas are applied. To specify a custom order for applying the schemas, you can declare them explicitly in `config.toml`. Any glob patterns will evaluated, deduplicated, and sorted in lexicographic order. For example, the following pattern ensures `employees.sql` is always executed first. supabase/config.toml 1[db.migrations]2schema_paths = [3 "./schemas/employees.sql",4 "./schemas/*.sql",5] ### Pulling in your production schema[#](https://supabase.com/docs/guides/local-development/declarative-database-schemas#pulling-in-your-production-schema) To set up declarative schemas on a existing project, you can pull in your production schema by running: Terminal 1supabase db dump > supabase/schemas/prod.sql From there, you can start breaking down your schema into smaller files and generate migrations. You can do this all at once, or incrementally as you make changes to your schema. ### Rolling back a schema change[#](https://supabase.com/docs/guides/local-development/declarative-database-schemas#rolling-back-a-schema-change) During development, you may want to rollback a migration to keep your new schema changes in a single migration file. This can be done by resetting your local database to a previous version. Terminal 1supabase db reset --version 20241005112233 After a reset, you can [edit the schema](https://supabase.com/docs/guides/local-development/declarative-database-schemas#updating-your-schema) and regenerate a new migration file. Note that you should not reset a version that's already deployed to production. If you need to rollback a migration that's already deployed, you should first revert changes to the schema files. Then you can generate a new migration file containing the down migration. This ensures your production migrations are always rolling forward. SQL statements generated in a down migration are usually destructive. You must review them carefully to avoid unintentional data loss. Known caveats[#](https://supabase.com/docs/guides/local-development/declarative-database-schemas#known-caveats) ---------------------------------------------------------------------------------------------------------------- The `migra` diff tool used for generating schema diff is capable of tracking most database changes. However, there are edge cases where it can fail. If you need to use any of the entities below, remember to add them through [versioned migrations](https://supabase.com/docs/guides/deployment/database-migrations) instead. ### Data manipulation language[#](https://supabase.com/docs/guides/local-development/declarative-database-schemas#data-manipulation-language) * DML statements such as `insert`, `update`, `delete`, etc., are not captured by schema diff ### View ownership[#](https://supabase.com/docs/guides/local-development/declarative-database-schemas#view-ownership) * [view owner and grants](https://github.com/djrobstep/migra/issues/160#issuecomment-1702983833) * [security invoker on views](https://github.com/djrobstep/migra/issues/234) * [materialized views](https://github.com/djrobstep/migra/issues/194) * doesn’t recreate views when altering column type ### RLS policies[#](https://supabase.com/docs/guides/local-development/declarative-database-schemas#rls-policies) * [alter policy statements](https://github.com/djrobstep/schemainspect/blob/master/schemainspect/pg/obj.py#L228) * [column privileges](https://github.com/djrobstep/schemainspect/pull/67) ### Other entities[#](https://supabase.com/docs/guides/local-development/declarative-database-schemas#other-entities) * schema privileges are not tracked because each schema is diffed separately * [comments are not tracked](https://github.com/djrobstep/migra/issues/69) * [partitions are not tracked](https://github.com/djrobstep/migra/issues/186) * [`alter publication ... add table ...`](https://github.com/supabase/cli/issues/883) * [create domain statements are ignored](https://github.com/supabase/cli/issues/2137) * [grant statements are duplicated from default privileges](https://github.com/supabase/cli/issues/1864) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/local-development/declarative-database-schemas%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/local-development/declarative-database-schemas%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Read Replicas | Supabase Docs Platform Read Replicas ================= Deploy read-only databases across multiple regions, for lower latency and better resource management. --------------------------------------------------------------------------------------------------------- * * * Read Replicas are additional databases kept in sync with your Primary database. You can read your data from a Read Replica, which helps with: * **Load balancing:** Read Replicas reduce load on the Primary database. For example, you can use a Read Replica for complex analytical queries and reserve the Primary for user-facing create, update, and delete operations. * **Improved latency:** For projects with a global user base, additional databases can be deployed closer to users to reduce latency. * **Redundancy:** Read Replicas provide data redundancy. ![Map view of all project databases.](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fguides%2Fplatform%2Fread-replicas%2Fmap-view.png%3Fv%3D1&w=3840&q=75) About Read Replicas[#](https://supabase.com/docs/guides/platform/read-replicas#about-read-replicas) ---------------------------------------------------------------------------------------------------- The database you start with when launching a Supabase project is your Primary database. A process called "replication" keeps Read Replicas in sync with the Primary. Replication is asynchronous to ensure that transactions on the Primary aren't blocked. There is a delay between an update on the Primary and the time that a Read Replica receives the change. This delay is called "replication lag." You can only read data from a Read Replica. This is in contrast to a Primary database, where you can both read and write: | | select | insert | update | delete | | --- | --- | --- | --- | --- | | Primary | ✅ | ✅ | ✅ | ✅ | | Read Replica | ✅ | \- | \- | \- | Do you need Read Replicas? Features[#](https://supabase.com/docs/guides/platform/read-replicas#features) ------------------------------------------------------------------------------ Read Replicas offer the following features: ### Dedicated endpoints[#](https://supabase.com/docs/guides/platform/read-replicas#dedicated-endpoints) Each Read Replica has its own dedicated database and API endpoints. * Find the database endpoint on the project's [**Connect** panel](https://supabase.com/dashboard/project/_?showConnect=true) . Toggle between Primary and Read Replicas using the **Source** dropdown. * Find the API endpoint on the [API Settings page](https://supabase.com/dashboard/project/_/settings/api) under **Project URL**. Toggle between Primary and Read Replicas using the **Source** dropdown. If you use an [IPv4 add-on](https://supabase.com/docs/guides/platform/ipv4-address#read-replicas) , the database endpoints for your Read Replicas also use an IPv4 add-on. Read Replicas only support `GET` requests from the [REST API](https://supabase.com/docs/guides/api) . If you are calling a read-only Postgres function through the REST API, make sure to set the `get: true` [option](https://supabase.com/docs/reference/javascript/rpc?queryGroups=example&example=call-a-read-only-postgres-function) . Requests to other Supabase products, such as Auth, Storage, and Realtime, aren't able to use a Read Replica or its API endpoint. Support for more products will be added in the future. ### Dedicated connection pool[#](https://supabase.com/docs/guides/platform/read-replicas#dedicated-connection-pool) A connection pool through Supavisor is also available for each Read Replica. Find the connection string on the [Database Settings page](https://supabase.com/dashboard/project/_/database/settings) under **Connection String**. ### API load balancer[#](https://supabase.com/docs/guides/platform/read-replicas#api-load-balancer) A load balancer automatically balances requests between your Primary database and Read Replicas. Find its endpoint on the [**API Settings page**](https://supabase.com/dashboard/project/_/settings/api) . The load balancer enables geo-routing for Data API requests to automatically route `GET` requests to the database closest to your user ensuring the lowest latency. You can also send Non-`GET` requests through this endpoint, and they are routed to the Primary database automatically. You can also interact with other Supabase services (Auth, Edge Functions, Realtime, and Storage) through this load balancer so there's no need to worry about which endpoint to use and in which situations. Geo-routing for Auth, Realtime, and Storage aren't yet available but are coming soon. Due to the requirements of the Auth service, all Auth requests are handled by the Primary, even when sent over the load balancer endpoint. This is similar to how non-Read requests for the Data API (PostgREST) are exclusively handled by the Primary. To call a read-only Postgres function on Read Replicas through the REST API, use the `get: true` [option](https://supabase.com/docs/reference/javascript/rpc?queryGroups=example&example=call-a-read-only-postgres-function) . If you remove all Read Replicas from your project, the load balancer and its endpoint are removed as well. Make sure to redirect requests back to your Primary database before removal. From April 4th, 2025, the routing behavior for eligible Data API requests changed: * **Old behavior**: Round-Robin distribution among all databases (all read replicas + primary) of your project, regardless of location * **New behavior**: Geo-routing, that directs requests to the closest available database (all read replicas + primary) The new behavior delivers a better experience for your users by minimizing the latency to your project. You can take full advantage of this by placing Read Replicas close to your major customer bases. If you use a [custom domain](https://supabase.com/docs/guides/platform/custom-domains) , requests will not be routed through the load balancer. You should instead use the dedicated endpoints provided in the dashboard. ### Querying through the SQL editor[#](https://supabase.com/docs/guides/platform/read-replicas#querying-through-the-sql-editor) In the SQL editor, you can choose if you want to run the query on a particular Read Replica. ![SQL editor view.](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fguides%2Fplatform%2Fread-replicas%2Fsql-editor.png%3Fv%3D1&w=3840&q=75) ### Logging[#](https://supabase.com/docs/guides/platform/read-replicas#logging) When a Read Replica is deployed, it emits logs from the following services: * [API](https://supabase.com/dashboard/project/_/logs/edge-logs) * [Postgres](https://supabase.com/dashboard/project/_/logs/postgres-logs) * [PostgREST](https://supabase.com/dashboard/project/_/logs/postgrest-logs) * [Supavisor](https://supabase.com/dashboard/project/_/logs/pooler-logs) Views on [Log Explorer](https://supabase.com/docs/guides/platform/logs) are automatically filtered by databases, with the logs of the Primary database displayed by default. Viewing logs from other databases can be toggled with the `Source` button found on the upper-right part section of the Logs Explorer page. For API logs, logs can originate from the API Load Balancer as well. The upstream database or the one that eventually handles the request can be found under the `Redirect Identifier` field. This is equivalent to `metadata.load_balancer_redirect_identifier` when querying the underlying logs. ### Metrics[#](https://supabase.com/docs/guides/platform/read-replicas#metrics) Observability and metrics for Read Replicas are available on the Supabase Dashboard. Resource utilization for a specific Read Replica can be viewed on the [Database Reports page](https://supabase.com/dashboard/project/_/observability/database) by toggling for `Source`. Likewise, metrics on API requests going through either a Read Replica or Load Balancer API endpoint are also available on the dashboard through the [API Reports page](https://supabase.com/dashboard/project/_/observability/api-overview) We recommend ingesting your [project's metrics](https://supabase.com/docs/guides/platform/metrics#accessing-the-metrics-endpoint) into your own environment. If you have an existing ingestion pipeline set up for your project, you can [update it](https://github.com/supabase/supabase-grafana?tab=readme-ov-file#read-replica-support) to additionally ingest metrics from your Read Replicas. ### Centralized configuration management[#](https://supabase.com/docs/guides/platform/read-replicas#centralized-configuration-management) All settings configured through the dashboard will be propagated across all databases of a project. This ensures that no Read Replica get out of sync with the Primary database or with other Read Replicas. Pricing[#](https://supabase.com/docs/guides/platform/read-replicas#pricing) ---------------------------------------------------------------------------- For a detailed breakdown of how we calculate charges, read the [Manage Read Replica usage guide](https://supabase.com/docs/guides/platform/manage-your-usage/read-replicas) . ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/platform/read-replicas%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/platform/read-replicas%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Local development with schema migrations | Supabase Docs Local Development Local development with schema migrations ============================================ Develop locally with the Supabase CLI and schema migrations. ---------------------------------------------------------------- * * * Supabase is a flexible platform that lets you decide how you want to build your projects. You can use the Dashboard directly to get up and running quickly, or use a proper local setup. We suggest you work locally and deploy your changes to a linked project on the [Supabase Platform](https://app.supabase.io/) . Develop locally using the CLI to run a local Supabase stack. You can use the integrated Studio Dashboard to make changes, then capture your changes in schema migration files, which can be saved in version control. Alternatively, if you're comfortable with migration files and SQL, you can write your own migrations and push them to the local database for testing before sharing your changes. Database migrations[#](https://supabase.com/docs/guides/local-development/overview#database-migrations) -------------------------------------------------------------------------------------------------------- Database changes are managed through "migrations." Database migrations are a common way of tracking changes to your database over time. For this guide, we'll create a table called `employees` and see how we can make changes to it. 1 ### Create your first migration file To get started, generate a [new migration](https://supabase.com/docs/reference/cli/supabase-migration-new) to store the SQL needed to create our `employees` table ###### Terminal 1supabase migration new create_employees_table 2 ### Add the SQL to your migration file This creates a new migration: supabase/migrations/ \_create\_employees\_table.sql. To that file, add the SQL to create this `employees` table ###### 20250101000000\_create\_employees\_table.sql 1create table employees (2 id bigint primary key generated always as identity,3 name text,4 email text,5 created_at timestamptz default now()6); 3 ### Apply your migration Now that you have a migration file, you can run this migration and create the `employees` table. Use the `reset` command here to reset the database to the current migrations ###### Terminal 1supabase db reset 4 ### Modify your employees table Now you can visit your new `employees` table in the Dashboard. Next, modify your `employees` table by adding a column for department. Create a new migration file for that. ###### Terminal 1supabase migration new add_department_to_employees_table 5 ### Add a new column to your table This creates a new migration file: supabase/migrations/ \_add\_department\_to\_employees\_table.sql. To that file, add the SQL to create a new department column ###### 20250101000001\_add\_department\_to\_employees\_table.sql 1alter table if exists public.employees2add department text default 'Hooli'; ### Add sample data[#](https://supabase.com/docs/guides/local-development/overview#add-sample-data) Now that you are managing your database with migrations scripts, it would be great have some seed data to use every time you reset the database. For this, you can create a seed script in `supabase/seed.sql`. 1 ### Populate your table Insert data into your `employees` table with your `supabase/seed.sql` file. ###### supabase/seed.sql 1insert into public.employees2 (name)3values4 ('Erlich Bachman'),5 ('Richard Hendricks'),6 ('Monica Hall'); 2 ### Reset your database Reset your database (apply current migrations), and populate with seed data ###### Terminal 1supabase db reset You should now see the `employees` table, along with your seed data in the Dashboard! All of your database changes are captured in code, and you can reset to a known state at any time, complete with seed data. ### Diffing changes[#](https://supabase.com/docs/guides/local-development/overview#diffing-changes) This workflow is great if you know SQL and are comfortable creating tables and columns. If not, you can still use the Dashboard to create tables and columns, and then use the CLI to diff your changes and create migrations. Create a new table called `cities`, with columns `id`, `name` and `population`. To see the corresponding SQL for this, you can use the `supabase db diff --schema public` command. This will show you the SQL that will be run to create the table and columns. The output of `supabase db diff` will look something like this: 1Diffing schemas: public2Finished supabase db diff on branch main.34create table "public"."cities" (5 "id" bigint primary key generated always as identity,6 "name" text,7 "population" bigint8); Alternately, you can view your table definitions directly from the Table Editor: ![SQL Definition](https://supabase.com/docs/img/guides/cli/sql-definitions.png) You can then copy this SQL into a new migration file, and run `supabase db reset` to apply the changes. The last step is deploying these changes to a live Supabase project. Deploy your project[#](https://supabase.com/docs/guides/local-development/overview#deploy-your-project) -------------------------------------------------------------------------------------------------------- You've been developing your project locally, making changes to your tables via migrations. It's time to deploy your project to the Supabase Platform and start scaling up to millions of users! Head over to [Supabase](https://supabase.com/dashboard) and create a new project to deploy to. ### Log in to the Supabase CLI[#](https://supabase.com/docs/guides/local-development/overview#log-in-to-the-supabase-cli) Terminalnpx 1supabase login ### Link your project[#](https://supabase.com/docs/guides/local-development/overview#link-your-project) Associate your project with your remote project using [`supabase link`](https://supabase.com/docs/reference/cli/usage#supabase-link) . 1supabase link --project-ref 2# You can get from your project's dashboard URL: https://supabase.com/dashboard/project/34supabase db pull5# Capture any changes that you have made to your remote database before you went through the steps above6# If you have not made any changes to the remote database, skip this step `supabase/migrations` is now populated with a migration in `_remote_schema.sql`. This migration captures any changes required for your local database to match the schema of your remote Supabase project. Review the generated migration file and once happy, apply the changes to your local instance: 1# To apply the new migration to your local database:2supabase migration up34# To reset your local database completely:5supabase db reset There are a few commands required to link your project. We are in the process of consolidating these commands into a single command. Bear with us! ### Deploy database changes[#](https://supabase.com/docs/guides/local-development/overview#deploy-database-changes) Deploy any local database migrations using [`db push`](https://supabase.com/docs/reference/cli/usage#supabase-db-push) : 1supabase db push Visiting your live project on [Supabase](https://supabase.com/dashboard) , you'll see a new `employees` table, complete with the `department` column you added in the second migration above. ### Deploy Edge Functions[#](https://supabase.com/docs/guides/local-development/overview#deploy-edge-functions) If your project uses Edge Functions, you can deploy these using [`functions deploy`](https://supabase.com/docs/reference/cli/usage#supabase-functions-deploy) : 1supabase functions deploy ### Use Auth locally[#](https://supabase.com/docs/guides/local-development/overview#use-auth-locally) To use Auth locally, update your project's `supabase/config.toml` file that gets created after running `supabase init`. Add any providers you want, and set enabled to `true`. 1[auth.external.github]2enabled = true3client_id = "env(SUPABASE_AUTH_GITHUB_CLIENT_ID)"4secret = "env(SUPABASE_AUTH_GITHUB_SECRET)"5redirect_uri = "http://localhost:54321/auth/v1/callback" As a best practice, any secret values should be loaded from environment variables. You can add them to `.env` file in your project's root directory for the CLI to automatically substitute them. 1SUPABASE_AUTH_GITHUB_CLIENT_ID="redacted"2SUPABASE_AUTH_GITHUB_SECRET="redacted" For these changes to take effect, you need to run `supabase stop` and `supabase start` again. If you have additional triggers or RLS policies defined on your `auth` schema, you can pull them as a migration file locally. 1supabase db pull --schema auth ### Sync storage buckets[#](https://supabase.com/docs/guides/local-development/overview#sync-storage-buckets) Your RLS policies on storage buckets can be pulled locally by specifying `storage` schema. For example, 1supabase db pull --schema storage The buckets and objects themselves are rows in the storage tables so they won't appear in your schema. You can instead define them via `supabase/config.toml` file. For example, 1[storage.buckets.images]2public = false3file_size_limit = "50MiB"4allowed_mime_types = ["image/png", "image/jpeg"]5objects_path = "./images" This will upload files from `supabase/images` directory to a bucket named `images` in your project with one command. 1supabase seed buckets ### Sync any schema with `--schema`[#](https://supabase.com/docs/guides/local-development/overview#sync-any-schema-with---schema) You can synchronize your database with a specific schema using the `--schema` option as follows: 1supabase db pull --schema Using `--schema` If the local `supabase/migrations` directory is empty, the `db pull` command will ignore the `--schema` parameter. To fix this, you can pull twice: 1supabase db pull2supabase db pull --schema Limitations and considerations[#](https://supabase.com/docs/guides/local-development/overview#limitations-and-considerations) ------------------------------------------------------------------------------------------------------------------------------ The local development environment is not as feature-complete as the Supabase Platform. Here are some of the differences: * You cannot update your project settings in the Dashboard. This must be done using the local config file. * The CLI version determines the local version of Studio used, so make sure you keep your local [Supabase CLI up to date](https://github.com/supabase/cli#getting-started) . We're constantly adding new features and bug fixes. Watch video guide ![Video guide preview](https://supabase.com/docs/_next/image?url=https%3A%2F%2Fimg.youtube.com%2Fvi%2FvyHyYpvjaks%2F0.jpg&w=3840&q=75) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/local-development/overview%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/local-development/overview%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Operational Error Codes | Supabase Docs Realtime Operational Error Codes =========================== List of operational codes to help understand your deployment and usage. --------------------------------------------------------------------------- * * * | Error code | Description | Action | | --- | --- | --- | | `ChannelRateLimitReached` | The number of channels you can create has reached its limit. | | | `ClientJoinRateLimitReached` | The rate of joins per second from your clients has reached the channel limits. | | | `ConnectionInitializing` | Database is initializing connection. | | | `ConnectionRateLimitReached` | The number of connected clients has reached its limit. | | | `DatabaseConnectionIssue` | Database had connection issues and connection was not able to be established. | | | `DatabaseLackOfConnections` | Realtime was not able to connect to the tenant's database due to not having enough available connections.

Learn more:

* [Connection management guide](https://supabase.com/docs/guides/database/connection-management) | Verify your database connection limits. | | `ErrorAuthorizingWebsocket` | Error when trying to authorize the WebSocket connection. | Verify user information on connect. | | `ErrorConnectingToWebsocket` | Error when trying to connect to the WebSocket server. | Verify user information on connect. | | `ErrorExecutingTransaction` | Error executing a database transaction in tenant database. | | | `ErrorOnRpcCall` | Error when calling another realtime node. | | | `ErrorStartingPostgresCDC` | Error when starting the Postgres CDC extension which is used for Postgres Changes. | | | `ErrorStartingPostgresCDCStream` | Error when starting the Postgres CDC stream which is used for Postgres Changes. | | | `IncreaseConnectionPool` | The number of connections you have set for Realtime are not enough to handle your current use case. | | | `InitializingProjectConnection` | Connection against Tenant database is still starting. | | | `InvalidJWTExpiration` | JWT exp claim value it's incorrect. | | | `JanitorFailedToDeleteOldMessages` | Scheduled task for realtime.message cleanup was unable to run. | | | `JwtSignatureError` | JWT signature was not able to be validated. | | | `MalformedJWT` | Token received does not comply with the JWT format. | | | `MigrationCheckFailed` | Check to see if we require to run migrations fails. | | | `MigrationsFailedToRun` | Error when running the migrations against the Tenant database that are required by Realtime. | | | `PartitionCreationFailed` | Error when creating partitions for realtime.messages. | | | `PoolingReplicationError` | Error when pooling the replication slot. | | | `PoolingReplicationPreparationError` | Error when preparing the replication slot. | | | `RealtimeDisabledForConfiguration` | The configuration provided to Realtime on connect will not be able to provide you any Postgres Changes. | Verify your configuration on channel startup as you might not have your tables properly registered. | | `RealtimeDisabledForTenant` | Realtime has been disabled for the tenant.

Learn more:

* [Troubleshooting guide for suspended projects](https://supabase.com/docs/troubleshooting/realtime-project-suspended-for-exceeding-quotas) | Your project may have been suspended for exceeding usage quotas. Contact support with your project reference ID and a description of your Realtime use case. | | `RealtimeNodeDisconnected` | Realtime is a distributed application and this means that one the system is unable to communicate with one of the distributed nodes. | | | `RealtimeRestarting` | Realtime is currently restarting. | | | `ReconnectSubscribeToPostgres` | Postgres changes still waiting to be subscribed. | | | `ReplicationMaxWalSendersReached` | Maximum number of WAL senders reached in tenant database.

Learn more:

* [Configuring max WAL senders](https://supabase.com/docs/guides/database/custom-postgres-config#cli-configurable-settings) | | | `ReplicationSlotBeingUsed` | The replication slot is being used by another transaction. | | | `RlsPolicyError` | Error on RLS policy used for authorization. | | | `StartListenAndReplicationFailed` | Error when starting the replication and listening of errors for database broadcasting. | | | `SubscriptionDeletionFailed` | Error when trying to delete a subscription for postgres changes. | | | `SynInitializationError` | Our framework to syncronize processes has failed to properly startup a connection to the database. | | | `TableHasSpacesInName` | The table you are trying to listen to has spaces in its name which we are unable to support. | Change the table name to not have spaces in it. | | `TenantNotFound` | The tenant you are trying to connect to does not exist. | Verify the tenant name you are trying to connect to exists in the realtime.tenants table. | | `TimeoutOnRpcCall` | RPC request within the Realtime server has timed out. | | | `TopicNameRequired` | You are trying to use Realtime without a topic name set. | | | `UnableCheckoutConnection` | Error when trying to checkout a connection from the tenant pool. | | | `UnableToCheckProcessesOnRemoteNode` | Error when trying to check the processes on a remote node. | | | `UnableToConnectToProject` | Unable to connect to Project database. | | | `UnableToConnectToTenantDatabase` | Realtime was not able to connect to the tenant's database. | | | `UnableToCreateCounter` | Error when trying to create a counter to track rate limits for a tenant. | | | `UnableToDecrementCounter` | Error when trying to decrement a counter to track rate limits for a tenant. | | | `UnableToDeletePhantomSubscriptions` | Error when trying to delete subscriptions that are no longer being used. | | | `UnableToDeleteTenant` | Error when trying to delete a tenant. | | | `UnableToEncodeJson` | An error were we are not handling correctly the response to be sent to the end user. | | | `UnableToFindCounter` | Error when trying to find a counter to track rate limits for a tenant. | | | `UnableToIncrementCounter` | Error when trying to increment a counter to track rate limits for a tenant. | | | `UnableToListenToTenantDatabase` | Unable to LISTEN for notifications against the Tenant Database. | | | `UnableToProcessListenPayload` | Payload sent in NOTIFY operation was not JSON parsable. | | | `UnableToSetPolicies` | Error when setting up Authorization Policies. | | | `UnableToSubscribeToPostgres` | Error when trying to subscribe to Postgres changes. | | | `UnableToTrackPresence` | Error when handling track presence for this socket. | | | `UnableToUpdateCounter` | Error when trying to update a counter to track rate limits for a tenant. | | | `Unauthorized` | Unauthorized access to Realtime channel. | | | `UnhandledProcessMessage` | Unhandled message received by a Realtime process. | | | `UnknownDataProcessed` | An unknown data type was processed by the Realtime system. | | | `UnknownErrorOnChannel` | An error we are not handling correctly was triggered on a channel. | | | `UnknownErrorOnController` | An error we are not handling correctly was triggered on a controller. | | | `UnknownPresenceEvent` | Presence event type not recognized by service. | | | `UnprocessableEntity` | Received a HTTP request with a body that was not able to be processed by the endpoint. | | ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/realtime/error_codes%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/realtime/error_codes%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Database Backups | Supabase Docs Platform Database Backups ==================== * * * We automatically back up all Free, Pro, Team, and Enterprise Plan projects on a daily basis. You can find backups in the [**Database** > **Backups**](https://supabase.com/dashboard/project/_/database/backups/scheduled) section of the Dashboard. Pro Plan projects can access the last 7 days of daily backups. Team Plan projects can access the last 14 days of daily backups, while Enterprise Plan projects can access up to 30 days of daily backups. If you need more frequent backups, consider enabling [Point-in-Time Recovery](https://supabase.com/docs/guides/platform/backups#point-in-time-recovery) . We recommend that free tier plan projects regularly export their data using the [Supabase CLI `db dump` command](https://supabase.com/docs/reference/cli/supabase-db-dump) and maintain off-site backups. When you delete a project, we permanently remove all associated data, including any backups stored in S3. This action is irreversible, so consider it carefully before proceeding. Types of backups[#](https://supabase.com/docs/guides/platform/backups#types-of-backups) ---------------------------------------------------------------------------------------- Database backups can be categorized into two types: **logical** and **physical**. You can learn more about them [in this blog post](https://supabase.com/blog/postgresql-physical-logical-backups) . ##### Physical backups are now enabled by default All projects on Postgres `15.8.1.079` and newer use the newer physical backup process. Projects on older Postgres versions have to upgrade in order to be transitioned to physical backups. Once upgraded to an eligible version, your project is automatically transitioned over to physical backups. For security purposes, daily backups do not store passwords for custom roles, and you will not find them in downloadable files. If you restore from a daily backup and use custom roles, you will need to reset their passwords after the restoration completes. Database backups do not include objects you store via the Storage API, as the database only includes metadata about these objects. Restoring an old backup does not restore objects you deleted after that backup. Backup and restore process[#](https://supabase.com/docs/guides/platform/backups#backup-and-restore-process) ------------------------------------------------------------------------------------------------------------ You can access daily backups in the [**Database** > **Backups**](https://supabase.com/dashboard/project/_/database/backups/scheduled) section of the Dashboard and restore a project to any of the backups. You can restore your project to any of the backups. To generate a logical backup yourself, use the [Supabase CLI `db dump` command](https://supabase.com/docs/reference/cli/supabase-db-dump) . Managing backups programmatically[#](https://supabase.com/docs/guides/platform/backups#managing-backups-programmatically) -------------------------------------------------------------------------------------------------------------------------- You can also manage backups programmatically [using the Management API](https://supabase.com/docs/reference/api/v1-list-all-backups) : 1# Get your access token from https://supabase.com/dashboard/account/tokens2export SUPABASE_ACCESS_TOKEN="your-access-token"3export PROJECT_REF="your-project-ref"45# List all available backups6curl -H "Authorization: Bearer $SUPABASE_ACCESS_TOKEN" \7 "https://api.supabase.com/v1/projects/$PROJECT_REF/database/backups"89# Restore from a PITR backup (replace Unix timestamp with desired restore point)10curl -X POST "https://api.supabase.com/v1/projects/$PROJECT_REF/database/backups/restore-pitr" \11 -H "Authorization: Bearer $SUPABASE_ACCESS_TOKEN" \12 -H "Content-Type: application/json" \13 -d '{14 "recovery_time_target_unix": "1735689600"15 }' ### Restoration process[#](https://supabase.com/docs/guides/platform/backups#restoration-process) When selecting a backup to restore to, choose the closest available backup made before your desired restore point. You can always choose earlier backups, but consider how many days of data you might lose. The Dashboard prompts you for confirmation before proceeding with the restoration. The project is inaccessible during this process, so plan for downtime beforehand. Downtime depends on the size of the database—the larger it is, the longer the downtime will be. After you confirm, we trigger the process to restore the desired backup data to your project. The dashboard will display a notification once the restoration completes. If your project uses subscriptions or replication slots, you need to drop them before the restoration and re-create them afterwards. We exempt the slot used by Realtime from this requirement and handle it automatically. Point-in-Time recovery[#](https://supabase.com/docs/guides/platform/backups#point-in-time-recovery) ---------------------------------------------------------------------------------------------------- Point-in-Time Recovery (PITR) allows you to back up a project at shorter intervals, giving you the option to restore to any chosen point with up to seconds of granularity. Even with daily backups, you could still lose a day's worth of data. With PITR, you can back up to the point of disaster. Pro, Team and Enterprise Plan projects can enable PITR as an add-on. Projects that want to use PITR must also use at least a Small compute add-on to ensure smooth functioning. How PITR works If you enable PITR, we will no longer take Daily Backups. PITR provides finer granularity than Daily Backups, so running both is unnecessary. ### Backup process[#](https://supabase.com/docs/guides/platform/backups#backup-process) ![PITR dashboard](https://supabase.com/docs/img/backups-pitr-dashboard.png) You can access PITR in the [Point in Time](https://supabase.com/dashboard/project/_/database/backups/pitr) settings in the Dashboard. The recovery period of a project is shown by the earliest and latest recovery points displayed in your preferred timezone. You can change the maximum recovery period if needed. The latest restore point of the project could be significantly behind the current time. This occurs when the database has had no recent activity, and therefore we have not made any recent WAL file backups. However, the state of the database at the latest recovery point still reflects the current state of the database, given that no transactions have occurred in between. ### Restoration process[#](https://supabase.com/docs/guides/platform/backups#restoration-process) ![PITR: Calendar view](https://supabase.com/docs/img/backups-pitr-calendar-view.png) A date and time picker appears when you click the **Start a restore** button. The process only proceeds if the selected date and time fall within the earliest and latest recovery points. ![PITR: Confirmation modal](https://supabase.com/docs/img/backups-pitr-confirmation-modal.png) After selecting your desired recovery point, the Dashboard prompts you to review and confirm before proceeding with the restoration. The project is inaccessible during this process, so plan for downtime beforehand. Downtime depends on the size of the database—the larger it is, the longer the downtime will be. After you confirm, we download the latest available physical backup to the project and partially restore the database. We then download the WAL files generated after this physical backup up to your specified point in time. We replay the underlying transaction records in these files against the database to complete the restoration. The Dashboard will display a notification once the restoration completes. ### Pricing[#](https://supabase.com/docs/guides/platform/backups#pricing) Pricing depends on the recovery retention period, which determines how many days back you can restore data to any chosen point of up to seconds in granularity. | Recovery Retention Period in Days | Hourly Price USD | Monthly Price USD | | --- | --- | --- | | 7 | $0.137 | $100 | | 14 | $0.274 | $200 | | 28 | $0.55 | $400 | For a detailed breakdown of how charges are calculated, refer to [Manage Point-in-Time Recovery usage](https://supabase.com/docs/guides/platform/manage-your-usage/point-in-time-recovery) . ### Downloading backups after disabling PITR[#](https://supabase.com/docs/guides/platform/backups#downloading-backups-after-disabling-pitr) When you disable PITR, we still take all new backups as physical backups only. You can still use physical backups for restoration, but they are not available for direct download. If you need to download a backup after disabling PITR, you need to take a manual [legacy logical backup using the Supabase CLI or pg\_dump](https://supabase.com/docs/guides/platform/migrating-within-supabase/backup-restore#backup-database-using-the-cli) . Restore to a new project[#](https://supabase.com/docs/guides/platform/backups#restore-to-a-new-project) -------------------------------------------------------------------------------------------------------- See the [Duplicate Project docs](https://supabase.com/docs/guides/platform/clone-project) . ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/platform/backups%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/platform/backups%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Configure S3 Storage | Supabase Docs Self-Hosting Configure S3 Storage ======================== Enable S3-compatible client endpoint and set up an S3 backend for self-hosted Supabase Storage. --------------------------------------------------------------------------------------------------- * * * Self-hosted Supabase Storage has two independent S3-related features: * **S3 protocol endpoint** - an S3-compatible API that Storage exposes at `/storage/v1/s3`. This allows standard S3 tools like `rclone` and the AWS CLI to interact with your Storage instance. * **S3 backend** - where Storage keeps data. By default, files are stored on the local filesystem. You can switch to an S3-compatible service (AWS S3, MinIO, etc.) for durability, scalability, or to use existing infrastructure. You can configure either feature independently. For example, you can enable the S3 protocol endpoint to use `rclone` while keeping the default file-based storage, or switch to an S3 backend without enabling the S3 protocol endpoint. Enable the S3 protocol endpoint[#](https://supabase.com/docs/guides/self-hosting/self-hosted-s3#enable-the-s3-protocol-endpoint) --------------------------------------------------------------------------------------------------------------------------------- The S3 protocol endpoint at `/storage/v1/s3` allows standard S3 clients to interact with your self-hosted Storage instance. It works with any storage backend, including the default file-based storage - you do not need to configure an S3 backend first. The Supabase REST API and SDK do not use the S3 protocol. Make sure to check that `REGION`, `S3_PROTOCOL_ACCESS_KEY_ID` and `S3_PROTOCOL_ACCESS_KEY_SECRET` are properly configured in you `.env` file. Read more about the secrets and passwords in [Configuring and securing Supabase](https://supabase.com/docs/guides/self-hosting/docker#configuring-and-securing-supabase) . 1storage:2 environment:3 # ... existing variables ...4 REGION: ${REGION}5 S3_PROTOCOL_ACCESS_KEY_ID: ${S3_PROTOCOL_ACCESS_KEY_ID}6 S3_PROTOCOL_ACCESS_KEY_SECRET: ${S3_PROTOCOL_ACCESS_KEY_SECRET} ### Test with the AWS CLI[#](https://supabase.com/docs/guides/self-hosting/self-hosted-s3#test-with-the-aws-cli) 1( set -a && \2source .env > /dev/null 2>&1 && \3echo "" && \4AWS_ACCESS_KEY_ID=$S3_PROTOCOL_ACCESS_KEY_ID \5AWS_SECRET_ACCESS_KEY=$S3_PROTOCOL_ACCESS_KEY_SECRET \6aws s3 ls \7--endpoint-url http://localhost:8000/storage/v1/s3 \8--region $REGION \9s3://your-storage-bucket ) ### Test with rclone[#](https://supabase.com/docs/guides/self-hosting/self-hosted-s3#test-with-rclone) 1( set -a && \2source .env > /dev/null 2>&1 && \3echo "" && \4rclone ls \5--s3-endpoint http://localhost:8000/storage/v1/s3 \6--s3-region $REGION \7--s3-provider Other \8--s3-access-key-id "$S3_PROTOCOL_ACCESS_KEY_ID" \9--s3-secret-access-key "$S3_PROTOCOL_ACCESS_KEY_SECRET" \10:s3:your-storage-bucket ) Use `aws login` and `rclone config` for persistent configuration. How to configure an S3 backend[#](https://supabase.com/docs/guides/self-hosting/self-hosted-s3#how-to-configure-an-s3-backend) ------------------------------------------------------------------------------------------------------------------------------- In general, the following configuration variables define S3 backend configuration for Storage in `docker-compose.yml`: 1storage:2 environment:3 # ... existing variables ...4 STORAGE_BACKEND: s35 GLOBAL_S3_BUCKET: your-s3-bucket-or-dirname6 GLOBAL_S3_ENDPOINT: https://your-s3-endpoint7 GLOBAL_S3_PROTOCOL: https8 GLOBAL_S3_FORCE_PATH_STYLE: 'true'9 AWS_ACCESS_KEY_ID: your-access-key-id10 AWS_SECRET_ACCESS_KEY: your-secret-access-key11 REGION: your-region Depending on your setup, you may need to adjust these values - for example, to use a local S3-compatible service like MinIO or a cloud provider like AWS. ### Using MinIO[#](https://supabase.com/docs/guides/self-hosting/self-hosted-s3#using-minio) An overlay `docker-compose.s3.yml` configuration can be added to enable MinIO container and provide an S3-compatible API for Storage backend: 1docker compose -f docker-compose.yml -f docker-compose.s3.yml up -d Make sure to review the Storage section in your `.env` file for related configuration options. ### Using AWS S3[#](https://supabase.com/docs/guides/self-hosting/self-hosted-s3#using-aws-s3) Create an S3 bucket and an IAM user with access to it. Then configure the storage service: 1storage:2 environment:3 # ... existing variables ...4 STORAGE_BACKEND: s35 GLOBAL_S3_BUCKET: your-aws-bucket-name6 AWS_ACCESS_KEY_ID: your-aws-access-key7 AWS_SECRET_ACCESS_KEY: your-aws-secret-key8 REGION: your-aws-region For AWS S3, you do not need `GLOBAL_S3_ENDPOINT` or `GLOBAL_S3_FORCE_PATH_STYLE` - the Storage S3 client automatically resolves the endpoint from the region and uses virtual-hosted-style URLs, which is what AWS S3 expects. These variables are only needed for non-AWS S3-compatible providers. ### S3-compatible providers[#](https://supabase.com/docs/guides/self-hosting/self-hosted-s3#s3-compatible-providers) Use the same configuration as MinIO, but point to your provider's endpoint, e.g.: 1storage:2 environment:3 # ... existing variables ...4 STORAGE_BACKEND: s35 GLOBAL_S3_BUCKET: your-bucket-name6 GLOBAL_S3_ENDPOINT: https://your-account-id.r2.cloudflarestorage.com Verify[#](https://supabase.com/docs/guides/self-hosting/self-hosted-s3#verify) ------------------------------------------------------------------------------- * Open Studio and upload a file to a bucket. List the file using the AWS CLI or `rclone` to confirm the S3 endpoint works. * If using an S3 backend: confirm the file appears in your S3 provider's console. Session token[#](https://supabase.com/docs/guides/self-hosting/self-hosted-s3#session-token) --------------------------------------------------------------------------------------------- You can authenticate to Supabase's S3-compatible storage using a user’s JWT to enforce Row-Level Security (RLS) across S3 operations. This is useful when initializing the S3 client on the server for a specific user session, or when using the client directly from the frontend. All operations performed with a session token are scoped to the authenticated user, and any RLS policies defined in the storage schema will be applied. To authenticate with S3 using a session token, provide the following credentials: * **region:** value from the `REGION` environment variable in your `.env` file * **access\_key\_id:** value from the `STORAGE_TENANT_ID` environment variable in your `.env` file * **secret\_access\_key:** value from the `ANON_KEY` environment variable * **session\_token:** a valid user JWT Example using the `aws-sdk` library: 1import { S3Client } from '@aws-sdk/client-s3'23const {4 data: { session },5} = await supabase.auth.getSession()67const client = new S3Client({8 forcePathStyle: true,9 region: 'stub', // REGION in .env10 endpoint: 'http:///storage/v1/s3', // Edit 11 credentials: {12 accessKeyId: 'stub', // STORAGE_TENANT_ID in .env13 secretAccessKey: 'your-anon-key', // ANON_KEY in .env14 sessionToken: session.access_token,15 },16}) Troubleshooting[#](https://supabase.com/docs/guides/self-hosting/self-hosted-s3#troubleshooting) ------------------------------------------------------------------------------------------------- ### Signature mismatch errors[#](https://supabase.com/docs/guides/self-hosting/self-hosted-s3#signature-mismatch-errors) S3 clients sign requests using the access key ID and secret. If you see `SignatureDoesNotMatch`, verify that the `REGION`, `S3_PROTOCOL_ACCESS_KEY_ID` and `S3_PROTOCOL_ACCESS_KEY_SECRET` in your `.env` file match what your S3 client is using. ### TUS upload errors on Cloudflare R2[#](https://supabase.com/docs/guides/self-hosting/self-hosted-s3#tus-upload-errors-on-cloudflare-r2) If resumable (TUS) uploads fail with HTTP 500 and a message about `x-amz-tagging`, add `TUS_ALLOW_S3_TAGS: "false"` to the storage service environment. Cloudflare R2 does not implement this S3 feature. ### Permission denied on uploads[#](https://supabase.com/docs/guides/self-hosting/self-hosted-s3#permission-denied-on-uploads) Setting a bucket to "Public" only allows unauthenticated **downloads**. Uploads are always blocked unless you create an RLS policy on the `storage.objects` table. Go to **Storage** > **Files** > **Policies** in Studio and create a policy that allows `INSERT` for the appropriate roles. ### Upload URLs point to localhost[#](https://supabase.com/docs/guides/self-hosting/self-hosted-s3#upload-urls-point-to-localhost) If uploads from a browser fail (CORS or mixed content errors), check that `API_EXTERNAL_URL` and `SUPABASE_PUBLIC_URL` in your `.env` file match your actual domain and protocol - not `http://localhost:8000`. ### Additional resources[#](https://supabase.com/docs/guides/self-hosting/self-hosted-s3#additional-resources) * [Storage repository `.env.sample`](https://github.com/supabase/storage/blob/master/.env.sample) * [S3 Authentication](https://supabase.com/docs/guides/storage/s3/authentication) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/self-hosting/self-hosted-s3%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/self-hosting/self-hosted-s3%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Choosing a Client | Supabase Docs AI & Vectors Choosing a Client ===================== * * * As described in [Structured & Unstructured Embeddings](https://supabase.com/docs/guides/ai/structured-unstructured) , AI workloads come in many forms. For data science or ephemeral workloads, the [Supabase Vecs](https://supabase.github.io/vecs/) client gets you started quickly. All you need is a connection string and vecs handles setting up your database to store and query vectors with associated metadata. Click [**Connect**](https://supabase.com/dashboard/project/_/?showConnect=true) at the top of any project page to get your connection string. Copy the URI from the **Shared pooler** option. For production python applications with version controlled migrations, we recommend adding first class vector support to your toolchain by [registering the vector type with your ORM](https://github.com/pgvector/pgvector-python) . pgvector provides bindings for the most commonly used SQL drivers/libraries including Django, SQLAlchemy, SQLModel, psycopg, asyncpg and Peewee. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/ai/python-clients%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/ai/python-clients%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Postgres SSL Enforcement | Supabase Docs Platform Postgres SSL Enforcement ============================ * * * Your Supabase project supports connecting to the Postgres DB without SSL enabled to maximize client compatibility. For increased security, you can prevent clients from connecting if they're not using SSL. Disabling SSL enforcement only applies to connections to Postgres and Supavisor ("Connection Pooler"); all HTTP APIs offered by Supabase (e.g., PostgREST, Storage, Auth) automatically enforce SSL on all incoming connections. Applying or updating SSL enforcement triggers a fast database reboot. On small projects this usually completes in a few seconds, but larger databases may see a longer interruption. Manage SSL enforcement via the dashboard[#](https://supabase.com/docs/guides/platform/ssl-enforcement#manage-ssl-enforcement-via-the-dashboard) ------------------------------------------------------------------------------------------------------------------------------------------------ SSL enforcement can be configured via the "Enforce SSL on incoming connections" setting under the SSL Configuration section in [Database Settings page](https://supabase.com/dashboard/project/_/database/settings) of the dashboard. Updating SSL enforcement requires a brief database reboot. This restarts only the database and involves a few minutes of downtime. Manage SSL enforcement via the Management API[#](https://supabase.com/docs/guides/platform/ssl-enforcement#manage-ssl-enforcement-via-the-management-api) ---------------------------------------------------------------------------------------------------------------------------------------------------------- You can also manage SSL enforcement using the Management API: 1# Get your access token from https://supabase.com/dashboard/account/tokens2export SUPABASE_ACCESS_TOKEN="your-access-token"3export PROJECT_REF="your-project-ref"45# Get current SSL enforcement status6curl -X GET "https://api.supabase.com/v1/projects/$PROJECT_REF/ssl-enforcement" \7 -H "Authorization: Bearer $SUPABASE_ACCESS_TOKEN"89# Enable SSL enforcement10curl -X PUT "https://api.supabase.com/v1/projects/$PROJECT_REF/ssl-enforcement" \11 -H "Authorization: Bearer $SUPABASE_ACCESS_TOKEN" \12 -H "Content-Type: application/json" \13 -d '{14 "requestedConfig": {15 "database": true16 }17 }'1819# Disable SSL enforcement20curl -X PUT "https://api.supabase.com/v1/projects/$PROJECT_REF/ssl-enforcement" \21 -H "Authorization: Bearer $SUPABASE_ACCESS_TOKEN" \22 -H "Content-Type: application/json" \23 -d '{24 "requestedConfig": {25 "database": false26 }27 }' Manage SSL enforcement via the CLI[#](https://supabase.com/docs/guides/platform/ssl-enforcement#manage-ssl-enforcement-via-the-cli) ------------------------------------------------------------------------------------------------------------------------------------ To get started: 1. [Install](https://supabase.com/docs/guides/cli) the Supabase CLI 1.37.0+. 2. [Log in](https://supabase.com/docs/guides/getting-started/local-development#log-in-to-the-supabase-cli) to your Supabase account using the CLI. 3. Ensure that you have [Owner or Admin permissions](https://supabase.com/docs/guides/platform/access-control#manage-team-members) for the project that you are enabling SSL enforcement. ### Check enforcement status[#](https://supabase.com/docs/guides/platform/ssl-enforcement#check-enforcement-status) You can use the `get` subcommand of the CLI to check whether SSL is currently being enforced: 1supabase ssl-enforcement --project-ref {ref} get --experimental Response if SSL is being enforced: 1SSL is being enforced. Response if SSL is not being enforced: 1SSL is *NOT* being enforced. ### Update enforcement[#](https://supabase.com/docs/guides/platform/ssl-enforcement#update-enforcement) The `update` subcommand is used to change the SSL enforcement status for your project: 1supabase ssl-enforcement --project-ref {ref} update --enable-db-ssl-enforcement --experimental Similarly, to disable SSL enforcement: 1supabase ssl-enforcement --project-ref {ref} update --disable-db-ssl-enforcement --experimental ### A note about Postgres SSL modes[#](https://supabase.com/docs/guides/platform/ssl-enforcement#a-note-about-postgres-ssl-modes) Postgres supports [multiple SSL modes](https://www.postgresql.org/docs/current/libpq-ssl.html#LIBPQ-SSL-PROTECTION) on the client side. These modes provide different levels of protection. Depending on your needs, it is important to verify that the SSL mode in use is performing the required level of enforcement and verification of SSL connections. | SSL Mode | Encryption | Verifies CA | Verifies Hostname | Description | | --- | --- | --- | --- | --- | | `disable` | No | No | No | SSL is not used. All data is transmitted in plaintext. | | `allow` | Optional | No | No | Tries a non-SSL connection first; falls back to SSL if the server requires it. | | `prefer` | Optional | No | No | Tries an SSL connection first; falls back to non-SSL if the server doesn't support it. This is the default. | | `require` | Yes | No | No | Always uses SSL, but does not verify the server certificate or hostname. | | `verify-ca` | Yes | Yes | No | Uses SSL and verifies that the server certificate is signed by a trusted CA. | | `verify-full` | Yes | Yes | Yes | Uses SSL, verifies the CA certificate, and confirms the hostname matches the certificate. Recommended when SSL enforcement is enabled. | The strongest mode offered by Postgres is `verify-full` and this is the mode you most likely want to use when SSL enforcement is enabled. To use `verify-full` you will need to download the Supabase CA certificate for your database. The certificate is available through the dashboard under the SSL Configuration section in the [Database Settings page](https://supabase.com/dashboard/project/_/database/settings) . Once the CA certificate has been downloaded, add it to the certificate authority list used by Postgres. 1cat {location of downloaded prod-ca-2021.crt} >> ~/.postgres/root.crt With the CA certificate added to the trusted certificate authorities list, use `psql` or your client library to connect to Supabase: 1psql "postgresql://aws-0-eu-central-1.pooler.supabase.com:6543/postgres?sslmode=verify-full" -U postgres. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/platform/ssl-enforcement%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/platform/ssl-enforcement%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Build a Supabase Integration | Supabase Docs Integrations Build a Supabase Integration ================================ This guide steps through building a Supabase Integration using OAuth2 and the management API, allowing you to manage users' organizations and projects on their behalf. --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * * * Using OAuth2.0 you can retrieve an access and refresh token that grant your application full access to the [Management API](https://supabase.com/docs/reference/api/introduction) on behalf of the user. Create an OAuth app[#](https://supabase.com/docs/guides/integrations/build-a-supabase-oauth-integration#create-an-oauth-app) ----------------------------------------------------------------------------------------------------------------------------- 1. In your organization's settings, navigate to the [**OAuth Apps**](https://supabase.com/dashboard/org/_/apps) tab. 2. In the upper-right section of the page, click **Add application**. 3. Fill in the required details and click **Confirm**. Show a "Connect Supabase" button[#](https://supabase.com/docs/guides/integrations/build-a-supabase-oauth-integration#show-a-connect-supabase-button) ----------------------------------------------------------------------------------------------------------------------------------------------------- In your user interface, add a "Connect Supabase" button to kick off the OAuth flow. Follow the design guidelines outlined in our [brand assets](https://supabase.com/brand-assets) . Implementing the OAuth 2.0 flow[#](https://supabase.com/docs/guides/integrations/build-a-supabase-oauth-integration#implementing-the-oauth-20-flow) ---------------------------------------------------------------------------------------------------------------------------------------------------- Once you've published your OAuth App on Supabase, you can use the OAuth 2.0 protocol get authorization from Supabase users to manage their organizations and projects. You can use your preferred OAuth2 client or follow the steps below. You can see an example implementation in TypeScript using Supabase Edge Functions [on our GitHub](https://github.com/supabase/supabase/tree/master/examples/edge-functions/supabase/functions/connect-supabase) . ### Redirecting to the authorize URL[#](https://supabase.com/docs/guides/integrations/build-a-supabase-oauth-integration#redirecting-to-the-authorize-url) Within your app's UI, redirect the user to [`https://api.supabase.com/v1/oauth/authorize`](https://api.supabase.com/api/v1#tag/oauth/GET/v1/oauth/authorize) . Make sure to include all required query parameters such as: * `client_id`: Your client id from the app creation above. * `redirect_uri`: The URL where Supabase will redirect the user to after providing consent. * `response_type`: Set this to `code`. * `state`: Information about the state of your app. Note that `redirect_uri` and `state` together cannot exceed 4kB in size. * `organization_slug`: The slug of the organization you want to connect to. This is optional, but if provided, it will pre-select the organization for the user. * \[Recommended\] PKCE: We strongly recommend using the PKCE flow for increased security. Generate a random value before taking the user to the authorize endpoint. This value is called code verifier. Hash it with SHA256 and include it as the `code_challenge` parameter, while setting `code_challenge_method` to `S256`. In the next step, you would need to provide the code verifier to get the first access and refresh token. * \[Deprecated\] `scope`: Scopes are configured when you create your OAuth app. Read the [docs](https://supabase.com/docs/guides/platform/oauth-apps/oauth-scopes) for more details. 1router.get('/connect-supabase/login', async (ctx) => {2 // Construct the URL for the authorization redirect and get a PKCE codeVerifier.3 const { uri, codeVerifier } = await oauth2Client.code.getAuthorizationUri()4 console.log(uri.toString())5 // console.log: https://api.supabase.com/v1/oauth/authorize?response_type=code&client_id=7673bde9-be72-4d75-bd5e-b0dba2c49b38&redirect_uri=http%3A%2F%2Flocalhost%3A54321%2Ffunctions%2Fv1%2Fconnect-supabase%2Foauth2%2Fcallback&scope=all&code_challenge=jk06R69S1bH9dD4td8mS5kAEFmEbMP5P0YrmGNAUVE0&code_challenge_method=S25667 // Store the codeVerifier in the user session (cookie).8 ctx.state.session.flash('codeVerifier', codeVerifier)910 // Redirect the user to the authorization endpoint.11 ctx.response.redirect(uri)12}) Find the full example on [GitHub](https://github.com/supabase/supabase/tree/master/examples/edge-functions/supabase/functions/connect-supabase) . ### Handling the callback[#](https://supabase.com/docs/guides/integrations/build-a-supabase-oauth-integration#handling-the-callback) Once the user consents to providing API access to your OAuth App, Supabase will redirect the user to the `redirect_uri` provided in the previous step. The URL will contain these query parameters: * `code`: An authorization code you should exchange with Supabase to get the access and refresh token. * `state`: The value you provided in the previous step, to help you associate the request with the user. The `state` property returned here should be compared to the `state` you sent previously. Exchange the authorization code for an access and refresh token by calling [`POST https://api.supabase.com/v1/oauth/token`](https://api.supabase.com/api/v1#tag/oauth/POST/v1/oauth/token) with the following query parameters as content-type `application/x-www-form-urlencoded`: * `grant_type`: The value `authorization_code`. * `code`: The `code` returned in the previous step. * `redirect_uri`: This must be exactly the same URL used in the first step. * (Recommended) `code_verifier`: If you used the PKCE flow in the first step, include the code verifier as `code_verifier`. If your application need to support dynamically generated Redirect URLs, check out [Handling Dynamic Redirect URLs](https://supabase.com/docs/guides/integrations/build-a-supabase-oauth-integration#handling-dynamic-redirect-urls) section below. As per OAuth2 spec, provide the client id and client secret as basic auth header: * `client_id`: The unique client ID identifying your OAuth App. * `client_secret`: The secret that authenticates your OAuth App to Supabase. 1router.get('/connect-supabase/oauth2/callback', async (ctx) => {2 // Make sure the codeVerifier is present for the user's session.3 const codeVerifier = ctx.state.session.get('codeVerifier') as string4 if (!codeVerifier) throw new Error('No codeVerifier!')56 // Exchange the authorization code for an access token.7 const tokens = await fetch(config.tokenUri, {8 method: 'POST',9 headers: {10 'Content-Type': 'application/x-www-form-urlencoded',11 Accept: 'application/json',12 Authorization: `Basic ${btoa(`${config.clientId}:${config.clientSecret}`)}`,13 },14 body: new URLSearchParams({15 grant_type: 'authorization_code',16 code: ctx.request.url.searchParams.get('code') || '',17 redirect_uri: config.redirectUri,18 code_verifier: codeVerifier,19 }),20 }).then((res) => res.json())21 console.log('tokens', tokens)2223 // Store the tokens in your DB for future use.2425 ctx.response.body = 'Success'26}) Find the full example on [GitHub](https://github.com/supabase/supabase/tree/master/examples/edge-functions/supabase/functions/connect-supabase) . Refreshing an access token[#](https://supabase.com/docs/guides/integrations/build-a-supabase-oauth-integration#refreshing-an-access-token) ------------------------------------------------------------------------------------------------------------------------------------------- You can use the [`POST /v1/oauth/token`](https://api.supabase.com/api/v1#tag/oauth/POST/v1/oauth/token) endpoint to refresh an access token using the refresh token returned at the end of the previous section. If the user has revoked access to your application, you will not be able to refresh a token. Furthermore, access tokens will stop working. Make sure you handle HTTP Unauthorized errors when calling any Supabase API. Calling the Management API[#](https://supabase.com/docs/guides/integrations/build-a-supabase-oauth-integration#calling-the-management-api) ------------------------------------------------------------------------------------------------------------------------------------------- Refer to [the Management API reference](https://supabase.com/docs/reference/api/introduction#authentication) to learn more about authentication with the Management API. ### Use the JavaScript (TypeScript) SDK[#](https://supabase.com/docs/guides/integrations/build-a-supabase-oauth-integration#use-the-javascript-typescript-sdk) For convenience, when working with JavaScript/TypeScript, you can use the [supabase-management-js](https://github.com/supabase-community/supabase-management-js#supabase-management-js) library. 1import { SupabaseManagementAPI } from 'supabase-management-js'23const client = new SupabaseManagementAPI({ accessToken: '' }) Integration recommendations[#](https://supabase.com/docs/guides/integrations/build-a-supabase-oauth-integration#integration-recommendations) --------------------------------------------------------------------------------------------------------------------------------------------- There are a couple common patterns you can consider adding to your integration that can facilitate a great user experience. ### Store API keys in env variables[#](https://supabase.com/docs/guides/integrations/build-a-supabase-oauth-integration#store-api-keys-in-env-variables) Some integrations, e.g. like [Cloudflare Workers](https://supabase.com/partners/integrations/cloudflare-workers) provide convenient access to the API URL and API keys to allow user to speed up development. Using the management API, you can retrieve a project's API credentials using the [`/projects/{ref}/api-keys` endpoint](https://api.supabase.com/api/v1#/projects/getProjectApiKeys) . ### Pre-fill database connection details[#](https://supabase.com/docs/guides/integrations/build-a-supabase-oauth-integration#pre-fill-database-connection-details) If your integration directly connects to the project's database, you can pref-fill the Postgres connection details for the user, it follows this schema: 1postgresql://postgres:[DB-PASSWORD]@db.[REF].supabase.co:5432/postgres Note that you cannot retrieve the database password via the management API, so for the user's existing projects you will need to collect their database password in your UI. ### Create new projects[#](https://supabase.com/docs/guides/integrations/build-a-supabase-oauth-integration#create-new-projects) Use the [`/v1/projects` endpoint](https://api.supabase.com/api/v1#/projects/createProject) to create a new project. When creating a new project, you can either ask the user to provide a database password, or you can generate a secure password for them. In any case, make sure to securely store the database password on your end which will allow you to construct the Postgres URI. ### Configure custom Auth SMTP[#](https://supabase.com/docs/guides/integrations/build-a-supabase-oauth-integration#configure-custom-auth-smtp) You can configure the user's [custom SMTP settings](https://supabase.com/docs/guides/auth/auth-smtp) using the [`/config/auth` endpoint](https://api.supabase.com/api/v1#/projects%20config/updateV1AuthConfig) . ### Handling dynamic redirect URLs[#](https://supabase.com/docs/guides/integrations/build-a-supabase-oauth-integration#handling-dynamic-redirect-urls) To handle multiple, dynamically generated redirect URLs within the same OAuth app, you can leverage the `state` query parameter. When starting the OAuth process, include the desired, encoded redirect URL in the `state` parameter. Once authorization is complete, we will sends the `state` value back to your app. You can then verify its integrity and extract the correct redirect URL, decoding it and redirecting the user to the correct URL. Current limitations[#](https://supabase.com/docs/guides/integrations/build-a-supabase-oauth-integration#current-limitations) ----------------------------------------------------------------------------------------------------------------------------- Only some features are available until we roll out fine-grained access control. If you need full database access, you will need to prompt the user for their database password. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/integrations/build-a-supabase-oauth-integration%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/integrations/build-a-supabase-oauth-integration%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Database Migrations | Supabase Docs Home Database Migrations ======================= How to manage schema migrations for your Supabase project. -------------------------------------------------------------- * * * Database migrations are SQL statements that create, update, or delete your existing database schemas. They are a common way of tracking changes to your database over time. Schema migrations[#](https://supabase.com/docs/guides/deployment/database-migrations#schema-migrations) -------------------------------------------------------------------------------------------------------- For this guide, we'll create a table called `employees` and see how we can make changes to it. You will need to [install](https://supabase.com/docs/guides/local-development#quickstart) the Supabase CLI and start the local development stack. If a lock timeout error occurs, in your migration file, consider increasing your [`lock_timeout`](https://postgresqlco.nf/doc/en/param/lock_timeout/) setting. 1 ### Create your first migration file To get started, generate a [new migration](https://supabase.com/docs/reference/cli/supabase-migration-new) to store the SQL needed to create our `employees` table. ###### Terminal 1supabase migration new create_employees_table 2 ### Add the SQL to your migration file This creates a new migration file in supabase/migrations directory. To that file, add the SQL to create this `employees` table. ###### supabase/migrations/\_create\_employees\_table.sql 1create table if not exists employees (2 id bigint primary key generated always as identity,3 name text not null,4 email text,5 created_at timestamptz default now()6); 3 ### Apply your first migration Run this migration to create the `employees` table. Now you can visit your new `employees` table in the local Dashboard. ###### Terminal 1supabase migration up 4 ### Modify your employees table Next, modify your `employees` table by adding a column for `department`. ###### Terminal 1supabase migration new add_department_column 5 ### Add a new column to your table To that new migration file, add the SQL to create a new `department` column. ###### supabase/migrations/\_add\_department\_column.sql 1alter table if exists public.employees2add department text default 'Hooli'; 6 ### Apply your second migration Run this migration to update your existing `employees` table. ###### Terminal 1supabase migration up Finally, you should see the `department` column added to your `employees` table in the local Dashboard. View the [complete code](https://github.com/supabase/supabase/tree/master/examples/database/employees) for this example on GitHub. ### Seeding data[#](https://supabase.com/docs/guides/deployment/database-migrations#seeding-data) Now that you are managing your database with migrations scripts, it would be great have some seed data to use every time you reset the database. 1 ### Populate your table Create a seed script in supabase/seed.sql. To that file, add the SQL to insert data into your `employees` table. ###### supabase/seed.sql 1insert into public.employees2 (name)3values4 ('Erlich Bachman'),5 ('Richard Hendricks'),6 ('Monica Hall'); 2 ### Reset your database Reset your database to reapply migrations and populate with seed data. ###### Terminal 1supabase db reset You should now see the `employees` table, along with your seed data in the Dashboard! All of your database changes are captured in code, and you can reset to a known state at any time, complete with seed data. ### Diffing changes[#](https://supabase.com/docs/guides/deployment/database-migrations#diffing-changes) This workflow is great if you know SQL and are comfortable creating tables and columns. If not, you can still use the Dashboard to create tables and columns, and then use the CLI to diff your changes and create migrations. 1 ### Create your table from the Dashboard Create a new table called `cities`, with columns `id`, `name` and `population`. Then generate a [schema diff](https://supabase.com/docs/reference/cli/supabase-db-diff) . ###### Terminal 1supabase db diff -f create_cities_table 2 ### Add schema diff as a migration A new migration file is created for you. Alternately, you can copy the table definitions directly from the Table Editor. ###### supabase/migrations/\_create\_cities\_table.sql 1create table "public"."cities" (2 "id" bigint primary key generated always as identity,3 "name" text,4 "population" bigint5); 3 ### Test your migration Test your new migration file by resetting your local database. ###### Terminal 1supabase db reset The last step is deploying these changes to a live Supabase project. Deploy your project[#](https://supabase.com/docs/guides/deployment/database-migrations#deploy-your-project) ------------------------------------------------------------------------------------------------------------ You've been developing your project locally, making changes to your tables via migrations. It's time to deploy your project to the Supabase Platform and start scaling up to millions of users! Head over to [Supabase](https://supabase.com/dashboard) and create a new project to deploy to. 1 ### Log in to the Supabase CLI [Login](https://supabase.com/docs/reference/cli/supabase-login) to the Supabase CLI using an auto-generated Personal Access Token. ###### Terminal 1supabase login 2 ### Link your project [Link](https://supabase.com/docs/reference/cli/supabase-link) to your remote project by selecting from the on-screen prompt. ###### Terminal 1supabase link 3 ### Deploy database migrations [Push](https://supabase.com/docs/reference/cli/supabase-db-push) your migrations to the remote database. ###### Terminal 1supabase db push 4 ### Deploy database seed data (optional) [Push](https://supabase.com/docs/reference/cli/supabase-db-push) your migrations and seed the remote database. ###### Terminal 1supabase db push --include-seed Visiting your live project on [Supabase](https://supabase.com/dashboard/project/_) , you'll see a new `employees` table, complete with the `department` column you added in the second migration above. Watch video guide ![Video guide preview](https://supabase.com/docs/_next/image?url=https%3A%2F%2Fimg.youtube.com%2Fvi%2FKx5nHBmIxyQ%2F0.jpg&w=3840&q=75) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/deployment/database-migrations%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/deployment/database-migrations%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Google Colab | Supabase Docs AI & Vectors Google Colab ================ Use Google Colab to manage your Supabase Vector store. ---------------------------------------------------------- * * * [![](https://supabase.com/docs/img/ai/colab-badge.svg)](https://colab.research.google.com/github/supabase/supabase/blob/master/examples/ai/vector_hello_world.ipynb) Google Colab is a hosted Jupyter Notebook service. It provides free access to computing resources, including GPUs and TPUs, and is well-suited to machine learning, data science, and education. We can use Colab to manage collections using [Supabase Vecs](https://supabase.com/docs/guides/ai/vecs-python-client) . In this tutorial we'll connect to a database running on the Supabase [platform](https://supabase.com/dashboard/) . If you don't already have a database, you can create one here: [database.new](https://database.new/) . Create a new notebook[#](https://supabase.com/docs/guides/ai/google-colab#create-a-new-notebook) ------------------------------------------------------------------------------------------------- Start by visiting [colab.research.google.com](https://colab.research.google.com/) . There you can create a new notebook. ![Google Colab new notebook](https://supabase.com/docs/img/ai/google-colab/colab-new.png) Install Vecs[#](https://supabase.com/docs/guides/ai/google-colab#install-vecs) ------------------------------------------------------------------------------- We'll use the Supabase Vector client, [Vecs](https://supabase.com/docs/guides/ai/vecs-python-client) , to manage our collections. At the top of the notebook add the notebook paste the following code and hit the "execute" button (`ctrl+enter`): 1pip install vecs ![Install vecs](https://supabase.com/docs/img/ai/google-colab/install-vecs.png) Connect to your database[#](https://supabase.com/docs/guides/ai/google-colab#connect-to-your-database) ------------------------------------------------------------------------------------------------------- On your project dashboard, click [Connect](https://supabase.com/dashboard/project/_?showConnect=true) . The connection string should look like `postgres://postgres.xxxx:password@xxxx.pooler.supabase.com:6543/postgres` Create a new code block below the install block (`ctrl+m b`) and add the following code using the Postgres URI you copied above: 1import vecs23DB_CONNECTION = "postgres://postgres.xxxx:password@xxxx.pooler.supabase.com:6543/postgres"45# create vector store client6vx = vecs.create_client(DB_CONNECTION) Execute the code block (`ctrl+enter`). If no errors were returned then your connection was successful. Create a collection[#](https://supabase.com/docs/guides/ai/google-colab#create-a-collection) --------------------------------------------------------------------------------------------- Now we're going to create a new collection and insert some documents. Create a new code block below the install block (`ctrl+m b`). Add the following code to the code block and execute it (`ctrl+enter`): 1collection = vx.get_or_create_collection(name="colab_collection", dimension=3)23collection.upsert(4 vectors=[5 (6 "vec0", # the vector's identifier7 [0.1, 0.2, 0.3], # the vector. list or np.array8 {"year": 1973} # associated metadata9 ),10 (11 "vec1",12 [0.7, 0.8, 0.9],13 {"year": 2012}14 )15 ]16) This will create a table inside your database within the `vecs` schema, called `colab_collection`. You can view the inserted items in the [Table Editor](https://supabase.com/dashboard/project/_/editor/) , by selecting the `vecs` schema from the schema dropdown. ![Colab documents](https://supabase.com/docs/img/ai/google-colab/colab-documents.png) Query your documents[#](https://supabase.com/docs/guides/ai/google-colab#query-your-documents) ----------------------------------------------------------------------------------------------- Now we can search for documents based on their similarity. Create a new code block and execute the following code: 1collection.query(2 query_vector=[0.4,0.5,0.6], # required3 limit=5, # number of records to return4 filters={}, # metadata filters5 measure="cosine_distance", # distance measure to use6 include_value=False, # should distance measure values be returned?7 include_metadata=False, # should record metadata be returned?8) You will see that this returns two documents in an array `['vec1', 'vec0']`: ![Colab results](https://supabase.com/docs/img/ai/google-colab/colab-results.png) It also returns a warning: 1Query does not have a covering index for cosine_distance. You can lean more about creating indexes in the [Vecs documentation](https://supabase.github.io/vecs/api/#create-an-index) . Resources[#](https://supabase.com/docs/guides/ai/google-colab#resources) ------------------------------------------------------------------------- * Vecs API: [supabase.github.io/vecs/api](https://supabase.github.io/vecs/api) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/ai/google-colab%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/ai/google-colab%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Subscribing to Database Changes | Supabase Docs Realtime Subscribing to Database Changes =================================== Listen to database changes in real-time from your website or application. ----------------------------------------------------------------------------- * * * You can use Supabase to subscribe to real-time database changes. There are two options available: 1. [Broadcast](https://supabase.com/docs/guides/realtime/broadcast) . This is the recommended method for scalability and security. 2. [Postgres Changes](https://supabase.com/docs/guides/realtime/postgres-changes) . This is a simpler method. It requires less setup, but does not scale as well as Broadcast. Using Broadcast[#](https://supabase.com/docs/guides/realtime/subscribing-to-database-changes#using-broadcast) -------------------------------------------------------------------------------------------------------------- To automatically send messages when a record is created, updated, or deleted, we can attach a [Postgres trigger](https://supabase.com/docs/guides/database/postgres/triggers) to any table. Supabase Realtime provides a `realtime.broadcast_changes()` function which we can use in conjunction with a trigger. This function will use a private channel and needs broadcast authorization RLS policies to be met. ### Broadcast authorization[#](https://supabase.com/docs/guides/realtime/subscribing-to-database-changes#broadcast-authorization) [Realtime Authorization](https://supabase.com/docs/guides/realtime/authorization) is required for receiving Broadcast messages. This is an example of a policy that allows authenticated users to listen to messages from topics: 1create policy "Authenticated users can receive broadcasts"2on "realtime"."messages"3for select4to authenticated5using ( true ); ### Create a trigger function[#](https://supabase.com/docs/guides/realtime/subscribing-to-database-changes#create-a-trigger-function) Let's create a function that we can call any time a record is created, updated, or deleted. This function will make use of some of Postgres's native [trigger variables](https://www.postgresql.org/docs/current/plpgsql-trigger.html#PLPGSQL-DML-TRIGGER) . For this example, we want to have a topic with the name `topic:` to which we're going to broadcast events. 1create or replace function public.your_table_changes()2returns trigger3security definer4language plpgsql5as $$6begin7 perform realtime.broadcast_changes(8 'topic:' || coalesce(NEW.id, OLD.id) ::text, -- topic - the topic to which you're broadcasting where you can use the topic id to build the topic name9 TG_OP, -- event - the event that triggered the function10 TG_OP, -- operation - the operation that triggered the function11 TG_TABLE_NAME, -- table - the table that caused the trigger12 TG_TABLE_SCHEMA, -- schema - the schema of the table that caused the trigger13 NEW, -- new record - the record after the change14 OLD -- old record - the record before the change15 );16 return null;17end;18$$; ### Create a trigger[#](https://supabase.com/docs/guides/realtime/subscribing-to-database-changes#create-a-trigger) Let's set up a trigger so the function is executed after any changes to the table. 1create trigger handle_your_table_changes2after insert or update or delete3on public.your_table4for each row5execute function your_table_changes (); #### Listening on client side[#](https://supabase.com/docs/guides/realtime/subscribing-to-database-changes#listening-on-client-side) Finally, on the client side, listen to the topic `topic:` to receive the events. Remember to set the channel as a private channel, since `realtime.broadcast_changes` uses Realtime Authorization. 1import { createClient } from '@supabase/supabase-js'2const supabase = createClient('your_project_url', 'your_supabase_api_key')34// ---cut---5const gameId = 'id'6await supabase.realtime.setAuth() // Needed for Realtime Authorization7const changes = supabase8 .channel(`topic:${gameId}`, {9 config: { private: true },10 })11 .on('broadcast', { event: 'INSERT' }, (payload) => console.log(payload))12 .on('broadcast', { event: 'UPDATE' }, (payload) => console.log(payload))13 .on('broadcast', { event: 'DELETE' }, (payload) => console.log(payload))14 .subscribe() Using Postgres Changes[#](https://supabase.com/docs/guides/realtime/subscribing-to-database-changes#using-postgres-changes) ---------------------------------------------------------------------------------------------------------------------------- Postgres Changes are simple to use, but have some [limitations](https://supabase.com/docs/guides/realtime/postgres-changes#limitations) as your application scales. We recommend using Broadcast for most use cases. ### Enable Postgres Changes[#](https://supabase.com/docs/guides/realtime/subscribing-to-database-changes#enable-postgres-changes) You'll first need to create a `supabase_realtime` publication and add your tables (that you want to subscribe to) to the publication: 1begin;23-- remove the supabase_realtime publication4drop5 publication if exists supabase_realtime;67-- re-create the supabase_realtime publication with no tables8create publication supabase_realtime;910commit;1112-- add a table called 'messages' to the publication13-- (update this to match your tables)14alter15 publication supabase_realtime add table messages; ### Streaming inserts[#](https://supabase.com/docs/guides/realtime/subscribing-to-database-changes#streaming-inserts) You can use the `INSERT` event to stream all new rows. 1// @noImplicitAny: false2import { createClient } from '@supabase/supabase-js'3const supabase = createClient('your_project_url', 'your_supabase_api_key')45// ---cut---6const channel = supabase7 .channel('schema-db-changes')8 .on(9 'postgres_changes',10 {11 event: 'INSERT',12 schema: 'public',13 },14 (payload) => console.log(payload)15 )16 .subscribe() ### Streaming updates[#](https://supabase.com/docs/guides/realtime/subscribing-to-database-changes#streaming-updates) You can use the `UPDATE` event to stream all updated rows. 1// @noImplicitAny: false2import { createClient } from '@supabase/supabase-js'3const supabase = createClient('your_project_url', 'your_supabase_api_key')45// ---cut---6const channel = supabase7 .channel('schema-db-changes')8 .on(9 'postgres_changes',10 {11 event: 'UPDATE',12 schema: 'public',13 },14 (payload) => console.log(payload)15 )16 .subscribe() ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/realtime/subscribing-to-database-changes%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/realtime/subscribing-to-database-changes%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Network Restrictions | Supabase Docs Platform Network Restrictions ======================== * * * If you can't find the Network Restrictions section at the bottom of your [Database Settings](https://supabase.com/dashboard/project/_/database/settings) , update your version of Postgres in the [Infrastructure Settings](https://supabase.com/dashboard/project/_/settings/infrastructure) . Each Supabase project comes with configurable restrictions on the IP ranges that are allowed to connect to Postgres and its pooler ("your database"). These restrictions are enforced before traffic reaches your database. If a connection is not restricted by IP, it still needs to authenticate successfully with valid database credentials. If direct connections to your database [resolve to a IPv6 address](https://supabase.com/dashboard/project/_/database/settings) , you need to add both IPv4 and IPv6 CIDRs to the list of allowed CIDRs. Network Restrictions will be applied to all database connection routes, whether pooled or direct. You will need to add both the IPv4 and IPv6 networks you want to allow. There are two exceptions: If you have been granted an extension on the IPv6 migration OR if you have purchased the [IPv4 add-on](https://supabase.com/dashboard/project/_/settings/addons) , you need only add IPv4 CIDRs. To get started via the Dashboard:[#](https://supabase.com/docs/guides/platform/network-restrictions#to-get-started-via-the-dashboard) -------------------------------------------------------------------------------------------------------------------------------------- Network restrictions can be configured in the [Database Settings](https://supabase.com/dashboard/project/_/database/settings) page. Ensure that you have [Owner or Admin permissions](https://supabase.com/docs/guides/platform/access-control#manage-team-members) for the project that you are enabling network restrictions. To get started via the Management API:[#](https://supabase.com/docs/guides/platform/network-restrictions#to-get-started-via-the-management-api) ------------------------------------------------------------------------------------------------------------------------------------------------ You can also manage network restrictions using the Management API: 1# Get your access token from https://supabase.com/dashboard/account/tokens2export SUPABASE_ACCESS_TOKEN="your-access-token"3export PROJECT_REF="your-project-ref"45# Get current network restrictions6curl -X GET "https://api.supabase.com/v1/projects/$PROJECT_REF/network-restrictions" \7 -H "Authorization: Bearer $SUPABASE_ACCESS_TOKEN"89# Update network restrictions10curl -X POST "https://api.supabase.com/v1/projects/$PROJECT_REF/network-restrictions/apply" \11 -H "Authorization: Bearer $SUPABASE_ACCESS_TOKEN" \12 -H "Content-Type: application/json" \13 -d '{14 "db_allowed_cidrs": [15 "192.168.0.1/24",16 ]17 }' To get started via the CLI:[#](https://supabase.com/docs/guides/platform/network-restrictions#to-get-started-via-the-cli) -------------------------------------------------------------------------------------------------------------------------- 1. [Install](https://supabase.com/docs/guides/cli) the Supabase CLI 1.22.0+. 2. [Log in](https://supabase.com/docs/guides/cli/local-development#log-in-to-the-supabase-cli) to your Supabase account using the CLI. 3. If your project was created before 23rd December 2022, it will need to be [upgraded to the latest Supabase version](https://supabase.com/docs/guides/platform/migrating-and-upgrading-projects) before Network Restrictions can be used. 4. Ensure that you have [Owner or Admin permissions](https://supabase.com/docs/guides/platform/access-control#manage-team-members) for the project that you are enabling network restrictions. ### Check restrictions[#](https://supabase.com/docs/guides/platform/network-restrictions#check-restrictions) You can use the `get` subcommand of the CLI to retrieve the restrictions currently in effect. If restrictions have been applied, the output of the `get` command will reflect the IP ranges allowed to connect: 1> supabase network-restrictions --project-ref {ref} get --experimental2DB Allowed IPv4 CIDRs: &[183.12.1.1/24]3DB Allowed IPv6 CIDRs: &[2001:db8:3333:4444:5555:6666:7777:8888/64]4Restrictions applied successfully: true If restrictions have never been applied to your project, the list of allowed CIDRs will be empty, but they will also not have been applied ("Restrictions applied successfully: false"). As a result, all IPs are allowed to connect to your database: 1> supabase network-restrictions --project-ref {ref} get --experimental2DB Allowed IPv4 CIDRs: []3DB Allowed IPv6 CIDRs: []4Restrictions applied successfully: false ### Update restrictions[#](https://supabase.com/docs/guides/platform/network-restrictions#update-restrictions) The `update` subcommand is used to apply network restrictions to your project: 1> supabase network-restrictions --project-ref {ref} update --db-allow-cidr 183.12.1.1/24 --db-allow-cidr 2001:db8:3333:4444:5555:6666:7777:8888/64 --experimental2DB Allowed IPv4 CIDRs: &[183.12.1.1/24]3DB Allowed IPv6 CIDRs: &[2001:db8:3333:4444:5555:6666:7777:8888/64]4Restrictions applied successfully: true The restrictions specified (in the form of CIDRs) replaces any restrictions that might have been applied in the past. To add to the existing restrictions, you must include the existing restrictions within the list of CIDRs provided to the `update` command. ### Remove restrictions[#](https://supabase.com/docs/guides/platform/network-restrictions#remove-restrictions) To remove all restrictions on your project, you can use the `update` subcommand with the CIDR `0.0.0.0/0`: 1> supabase network-restrictions --project-ref {ref} update --db-allow-cidr 0.0.0.0/0 --db-allow-cidr ::/0 --experimental2DB Allowed IPv4 CIDRs: &[0.0.0.0/0]3DB Allowed IPv6 CIDRs: &[::/0]4Restrictions applied successfully: true Limitations[#](https://supabase.com/docs/guides/platform/network-restrictions#limitations) ------------------------------------------------------------------------------------------- * The current iteration of Network Restrictions applies to connections to Postgres and the database pooler; it doesn't currently apply to APIs offered over HTTPS (e.g., PostgREST, Storage, and Auth). This includes using Supabase client libraries like [supabase-js](https://supabase.com/docs/reference/javascript) . * If network restrictions are enabled, direct access to your database from Edge Functions will always be blocked. Using the Supabase client library [supabase-js](https://supabase.com/docs/reference/javascript) is recommended to connect to a database with network restrictions from Edge Functions. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/platform/network-restrictions%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/platform/network-restrictions%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Configure Phone Login & MFA | Supabase Docs Self-Hosting Configure Phone Login & MFA =============================== Set up phone login SMS providers, OTP settings, and multi-factor authentication for self-hosted Supabase with Docker. ------------------------------------------------------------------------------------------------------------------------- * * * This guide covers the **server-side configuration** for phone login and multi-factor authentication (MFA) on a self-hosted Supabase instance running with Docker Compose. For client-side implementation, see [Phone Login](https://supabase.com/docs/guides/auth/phone-login) and [Multi-Factor Authentication](https://supabase.com/docs/guides/auth/auth-mfa) . Before you begin[#](https://supabase.com/docs/guides/self-hosting/self-hosted-phone-mfa#before-you-begin) ---------------------------------------------------------------------------------------------------------- You need: * A working self-hosted Supabase installation. See [Self-Hosting with Docker](https://supabase.com/docs/guides/self-hosting/docker) . * An account with an SMS provider (e.g., Twilio) Phone auth is **enabled by default** in the Docker setup (`ENABLE_PHONE_SIGNUP=true` in `.env`). However, without an SMS provider configured, the Auth service has no way to deliver OTP codes. SMS provider configuration[#](https://supabase.com/docs/guides/self-hosting/self-hosted-phone-mfa#sms-provider-configuration) ------------------------------------------------------------------------------------------------------------------------------ The default `.env.example` and `docker-compose.yml` include commented-out SMS provider placeholders. The example below uses Twilio - you'll need a Twilio account with an account SID, auth token, and message service SID. See [Twilio's documentation](https://www.twilio.com/docs/messaging) for how to obtain these credentials. To enable SMS delivery: ### Step 1: Uncomment and configure the environment variables[#](https://supabase.com/docs/guides/self-hosting/self-hosted-phone-mfa#step-1-uncomment-and-configure-the-environment-variables) 1SMS_PROVIDER=twilio2SMS_OTP_EXP=603SMS_OTP_LENGTH=64SMS_MAX_FREQUENCY=60s5SMS_TEMPLATE=Your code is {{ .Code }}67## Twilio credentials8SMS_TWILIO_ACCOUNT_SID=your-account-sid9SMS_TWILIO_AUTH_TOKEN=your-auth-token10SMS_TWILIO_MESSAGE_SERVICE_SID=your-message-service-sid ### Step 2: Uncomment the matching lines in Docker Compose configuration[#](https://supabase.com/docs/guides/self-hosting/self-hosted-phone-mfa#step-2-uncomment-the-matching-lines-in-docker-compose-configuration) Uncomment the `GOTRUE_SMS_*` lines in the `auth` service's `environment` block: 1auth:2 environment:3 # ... existing variables ...4 GOTRUE_SMS_PROVIDER: ${SMS_PROVIDER}5 GOTRUE_SMS_OTP_EXP: ${SMS_OTP_EXP}6 GOTRUE_SMS_OTP_LENGTH: ${SMS_OTP_LENGTH}7 GOTRUE_SMS_MAX_FREQUENCY: ${SMS_MAX_FREQUENCY}8 GOTRUE_SMS_TEMPLATE: ${SMS_TEMPLATE}9 GOTRUE_SMS_TWILIO_ACCOUNT_SID: ${SMS_TWILIO_ACCOUNT_SID}10 GOTRUE_SMS_TWILIO_AUTH_TOKEN: ${SMS_TWILIO_AUTH_TOKEN}11 GOTRUE_SMS_TWILIO_MESSAGE_SERVICE_SID: ${SMS_TWILIO_MESSAGE_SERVICE_SID} ### Step 3: Restart the auth service[#](https://supabase.com/docs/guides/self-hosting/self-hosted-phone-mfa#step-3-restart-the-auth-service) 1docker compose up -d --force-recreate --no-deps auth ### Step 4: Verify[#](https://supabase.com/docs/guides/self-hosting/self-hosted-phone-mfa#step-4-verify) 1docker compose exec auth env | grep GOTRUE_SMS Confirm your provider and credentials appear in the output. For providers other than Twilio, add the provider-specific `GOTRUE_SMS_*` lines manually to `docker-compose.yml`. OTP settings[#](https://supabase.com/docs/guides/self-hosting/self-hosted-phone-mfa#otp-settings) -------------------------------------------------------------------------------------------------- ### Expiration[#](https://supabase.com/docs/guides/self-hosting/self-hosted-phone-mfa#expiration) The default OTP expiration is **60 seconds**. This is often too short for production use, consider increasing it. Set `SMS_OTP_EXP` in `.env` (value is in seconds): 1# Set expiration to 5 minutes2SMS_OTP_EXP=300 And ensure `GOTRUE_SMS_OTP_EXP: ${SMS_OTP_EXP}` is uncommented in `docker-compose.yml`. ### Length[#](https://supabase.com/docs/guides/self-hosting/self-hosted-phone-mfa#length) The default OTP length is 6 digits. You can set it to any value between 6 and 10: 1SMS_OTP_LENGTH=8 ### Rate limiting[#](https://supabase.com/docs/guides/self-hosting/self-hosted-phone-mfa#rate-limiting) `SMS_MAX_FREQUENCY` controls the minimum interval between SMS sends to the same phone number. The default is 60 seconds: 1## Allow one SMS every 30 seconds2SMS_MAX_FREQUENCY=30s Test OTPs for development[#](https://supabase.com/docs/guides/self-hosting/self-hosted-phone-mfa#test-otps-for-development) ---------------------------------------------------------------------------------------------------------------------------- To avoid sending real SMS during development, use `SMS_TEST_OTP` to map phone numbers to fixed OTP codes: 1SMS_TEST_OTP=16505551234:123456,16505555678:654321 And uncomment `GOTRUE_SMS_TEST_OTP: ${SMS_TEST_OTP}` in `docker-compose.yml`. When a test phone number requests an OTP, the Auth service skips SMS delivery and accepts only the mapped code. Other phone numbers continue to use the real SMS provider. Remove test OTPs before deploying to production. You can also set an expiration with `SMS_TEST_OTP_VALID_UNTIL` (ISO 8601 datetime, e.g., `2026-12-31T23:59:59Z`) so they stop working automatically. Multi-factor authentication (MFA)[#](https://supabase.com/docs/guides/self-hosting/self-hosted-phone-mfa#multi-factor-authentication-mfa) ------------------------------------------------------------------------------------------------------------------------------------------ The Auth service supports three MFA factor types. Configure them by uncommenting variables in `.env` and the matching `GOTRUE_MFA_*` lines in `docker-compose.yml`. ### App authenticator (TOTP)[#](https://supabase.com/docs/guides/self-hosting/self-hosted-phone-mfa#app-authenticator-totp) TOTP is **enabled by default** - users can enroll with apps like Google Authenticator or Authy without any additional configuration. To disable TOTP: 1MFA_TOTP_ENROLL_ENABLED=false2MFA_TOTP_VERIFY_ENABLED=false ### Phone MFA[#](https://supabase.com/docs/guides/self-hosting/self-hosted-phone-mfa#phone-mfa) Phone MFA is **disabled by default** (opt-in). It uses the same SMS provider configuration as phone login. To enable: 1MFA_PHONE_ENROLL_ENABLED=true2MFA_PHONE_VERIFY_ENABLED=true ### Maximum enrolled factors[#](https://supabase.com/docs/guides/self-hosting/self-hosted-phone-mfa#maximum-enrolled-factors) By default, a user can enroll up to 10 MFA factors. To change this: 1MFA_MAX_ENROLLED_FACTORS=5 Troubleshooting[#](https://supabase.com/docs/guides/self-hosting/self-hosted-phone-mfa#troubleshooting) -------------------------------------------------------------------------------------------------------- ### OTP expires too quickly[#](https://supabase.com/docs/guides/self-hosting/self-hosted-phone-mfa#otp-expires-too-quickly) The default `SMS_OTP_EXP` is 60 seconds. Increase it in `.env`: 1SMS_OTP_EXP=300 Ensure `GOTRUE_SMS_OTP_EXP: ${SMS_OTP_EXP}` is uncommented in `docker-compose.yml`, then restart: 1docker compose up -d --force-recreate --no-deps auth ### SMS not being delivered[#](https://supabase.com/docs/guides/self-hosting/self-hosted-phone-mfa#sms-not-being-delivered) Check the auth container logs for errors: 1docker compose logs auth --tail 50 Verify provider credentials reach the container: 1docker compose exec auth env | grep GOTRUE_SMS Common causes: * Provider credentials are in `.env` but the matching `GOTRUE_SMS_*` line is still commented out in `docker-compose.yml` * Provider credentials are wrong * Phone number format is wrong (use E.164 format: `+1234567890`) ### Variables added to the environment but not working[#](https://supabase.com/docs/guides/self-hosting/self-hosted-phone-mfa#variables-added-to-the-environment-but-not-working) Configuration variables from `.env` are **not** automatically available inside the container unless there's a matching passthrough definition in `docker-compose.yml`. Check, e.g., for: 1docker compose exec auth env | grep -E 'GOTRUE_SMS|GOTRUE_MFA' After changing the configuration environment variables, recreate the Auth service container: 1docker compose up -d --force-recreate --no-deps auth ### Rate limit errors[#](https://supabase.com/docs/guides/self-hosting/self-hosted-phone-mfa#rate-limit-errors) If users see "rate limit exceeded" errors, check `SMS_MAX_FREQUENCY` (minimum interval between sends) and the global rate limit `GOTRUE_RATE_LIMIT_SMS_SENT` (default: 30 per hour). ### Additional resources[#](https://supabase.com/docs/guides/self-hosting/self-hosted-phone-mfa#additional-resources) * [Multi-Factor Authentication (Phone)](https://supabase.com/docs/guides/auth/auth-mfa/phone) * [Multi-Factor Authentication (TOTP)](https://supabase.com/docs/guides/auth/auth-mfa/totp) * [Auth server on GitHub](https://github.com/supabase/auth) (check README and `example.env`) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/self-hosting/self-hosted-phone-mfa%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/self-hosting/self-hosted-phone-mfa%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Python client | Supabase Docs AI & Vectors Python client ================= Manage unstructured vector stores in PostgreSQL. ---------------------------------------------------- * * * Supabase provides a Python client called [`vecs`](https://github.com/supabase/vecs) for managing unstructured vector stores. This client provides a set of useful tools for creating and querying collections in Postgres using the [pgvector](https://supabase.com/docs/guides/database/extensions/pgvector) extension. Quick start[#](https://supabase.com/docs/guides/ai/vecs-python-client#quick-start) ----------------------------------------------------------------------------------- Let's see how Vecs works using a local database. Make sure you have the Supabase CLI [installed](https://supabase.com/docs/guides/cli#installation) on your machine. ### Initialize your project[#](https://supabase.com/docs/guides/ai/vecs-python-client#initialize-your-project) Start a local Postgres instance in any folder using the `init` and `start` commands. Make sure you have Docker running! 1# Initialize your project2supabase init34# Start Postgres5supabase start ### Create a collection[#](https://supabase.com/docs/guides/ai/vecs-python-client#create-a-collection) Inside a Python shell, run the following commands to create a new collection called "docs", with 3 dimensions. 1import vecs23# create vector store client4vx = vecs.create_client("postgresql://postgres:postgres@localhost:54322/postgres")56# create a collection of vectors with 3 dimensions7docs = vx.get_or_create_collection(name="docs", dimension=3) ### Add embeddings[#](https://supabase.com/docs/guides/ai/vecs-python-client#add-embeddings) Now we can insert some embeddings into our "docs" collection using the `upsert()` command: 1import vecs23# create vector store client4docs = vecs.get_or_create_collection(name="docs", dimension=3)56# a collection of vectors with 3 dimensions7vectors=[8 ("vec0", [0.1, 0.2, 0.3], {"year": 1973}),9 ("vec1", [0.7, 0.8, 0.9], {"year": 2012})10]1112# insert our vectors13docs.upsert(vectors=vectors) ### Query the collection[#](https://supabase.com/docs/guides/ai/vecs-python-client#query-the-collection) You can now query the collection to retrieve a relevant match: 1import vecs23docs = vecs.get_or_create_collection(name="docs", dimension=3)45# query the collection filtering metadata for "year" = 20126docs.query(7 data=[0.4,0.5,0.6], # required8 limit=1, # number of records to return9 filters={"year": {"$eq": 2012}}, # metadata filters10) Deep dive[#](https://supabase.com/docs/guides/ai/vecs-python-client#deep-dive) ------------------------------------------------------------------------------- For a more in-depth guide on `vecs` collections, see [API](https://supabase.com/docs/guides/ai/python/api) . Resources[#](https://supabase.com/docs/guides/ai/vecs-python-client#resources) ------------------------------------------------------------------------------- * Official Vecs Documentation: [https://supabase.github.io/vecs/api](https://supabase.github.io/vecs/api) * Source Code: [https://github.com/supabase/vecs](https://github.com/supabase/vecs) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/ai/vecs-python-client%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/ai/vecs-python-client%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # General configuration | Supabase Docs Auth General configuration ========================= General configuration options for Supabase Auth --------------------------------------------------- * * * This section covers the [general configuration options](https://supabase.com/dashboard/project/_/auth) for Supabase Auth. If you are looking for another type of configuration, you may be interested in one of the following sections: * [Policies](https://supabase.com/dashboard/project/_/auth/policies) to manage Row Level Security policies for your tables. * [Sign In / Providers](https://supabase.com/dashboard/project/_/auth/providers) to configure authentication providers and login methods for your users. * [Third Party Auth](https://supabase.com/dashboard/project/_/auth/third-party) to use third-party authentication (TPA) systems based on JWTs to access your project. * [Sessions](https://supabase.com/dashboard/project/_/auth/sessions) to configure settings for user sessions and refresh tokens. * [Rate limits](https://supabase.com/dashboard/project/_/auth/rate-limits) to safeguard against bursts of incoming traffic to prevent abuse and maximize stability. * [Email Templates](https://supabase.com/dashboard/project/_/auth/templates) to configure what emails your users receive. * [Custom SMTP](https://supabase.com/dashboard/project/_/auth/smtp) to configure how emails are sent. * [Multi-Factor](https://supabase.com/dashboard/project/_/auth/mfa) to require users to provide additional verification factors to authenticate. * [URL Configuration](https://supabase.com/dashboard/project/_/auth/url-configuration) to configure site URL and redirect URLs for authentication. Read more [in the redirect URLs documentation](https://supabase.com/docs/guides/auth/redirect-urls) . * [Attack Protection](https://supabase.com/dashboard/project/_/auth/protection) to configure security settings to protect your project from attacks. * [Auth Hooks (BETA)](https://supabase.com/dashboard/project/_/auth/auth-hooks) to use Postgres functions or HTTP endpoints to customize the behavior of Supabase Auth to meet your needs. * [Audit Logs (BETA)](https://supabase.com/dashboard/project/_/auth/audit-logs) to track and monitor auth events in your project. * [Performance](https://supabase.com/dashboard/project/_/auth/performance) to configure and optimize authentication server settings. Supabase Auth provides these [general configuration options](https://supabase.com/dashboard/project/_/auth/providers) to control user access to your application: * **Allow new users to sign up**: Users will be able to sign up. If this config is disabled, only existing users can sign in. * **Confirm Email**: Users will need to confirm their email address before signing in for the first time. * Having **Confirm Email** disabled assumes that the user's email does not need to be verified in order to login and implicitly confirms the user's email in the database. * This option can be found in the email provider under the provider-specific configuration. * **Allow anonymous sign-ins**: Allow anonymous users to be created. * **Allow manual linking**: Allow users to link their accounts manually. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/auth/general-configuration%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/auth/general-configuration%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Logging | Supabase Docs Telemetry Logging =========== * * * The Supabase Platform includes a Logs Explorer that allows log tracing and debugging. Log retention is based on your [project's pricing plan](https://supabase.com/pricing) . Product logs[#](https://supabase.com/docs/guides/telemetry/logs#product-logs) ------------------------------------------------------------------------------ Supabase provides a logging interface specific to each product. You can use simple regular expressions for keywords and patterns to search log event messages. You can also export and download the log events matching your query as a spreadsheet. APIPostgresAuthStorageRealtimeEdge Functions [API logs](https://supabase.com/dashboard/project/_/logs/edge-logs) show all network requests and response for the REST and GraphQL [APIs](https://supabase.com/docs/guides/database/api) . If [Read Replicas](https://supabase.com/docs/guides/platform/read-replicas) are enabled, logs are automatically filtered between databases as well as the [API Load Balancer](https://supabase.com/docs/guides/platform/read-replicas#api-load-balancer) endpoint. Logs for a specific endpoint can be toggled with the `Source` button on the upper-right section of the dashboard. When viewing logs originating from the API Load Balancer endpoint, the upstream database or the one that eventually handles the request can be found under the `Redirect Identifier` field. This is equivalent to `metadata.load_balancer_redirect_identifier` when querying the underlying logs. ![API Logs](https://supabase.com/docs/img/guides/platform/logs/logs-api.png) * * * Working with API logs[#](https://supabase.com/docs/guides/telemetry/logs#working-with-api-logs) ------------------------------------------------------------------------------------------------ [API logs](https://supabase.com/dashboard/project/_/logs/edge-logs) run through the Cloudflare edge servers and will have attached Cloudflare metadata under the `metadata.request.cf.*` fields. ### Allowed headers[#](https://supabase.com/docs/guides/telemetry/logs#allowed-headers) A strict list of request and response headers are permitted in the API logs. Request and response headers will still be received by the server(s) and client(s), but will not be attached to the API logs generated. Request headers: * `accept` * `cf-connecting-ip` * `cf-ipcountry` * `host` * `user-agent` * `x-forwarded-proto` * `referer` * `content-length` * `x-real-ip` * `x-client-info` * `x-forwarded-user-agent` * `range` * `prefer` Response headers: * `cf-cache-status` * `cf-ray` * `content-location` * `content-range` * `content-type` * `content-length` * `date` * `transfer-encoding` * `x-kong-proxy-latency` * `x-kong-upstream-latency` * `sb-gateway-mode` * `sb-gateway-version` ### Additional request metadata[#](https://supabase.com/docs/guides/telemetry/logs#additional-request-metadata) To attach additional metadata to a request, it is recommended to use the `User-Agent` header for purposes such as device or version identification. For example: 1node MyApp/1.2.3 (device-id:abc123)2Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0 MyApp/1.2.3 (Foo v1.3.2; Bar v2.2.2) Do not log Personal Identifiable Information (PII) within the `User-Agent` header, to avoid infringing data protection privacy laws. Overly fine-grained and detailed user agents may allow fingerprinting and identification of the end user through PII. Logging Postgres queries[#](https://supabase.com/docs/guides/telemetry/logs#logging-postgres-queries) ------------------------------------------------------------------------------------------------------ To enable query logs for other categories of statements: 1. [Enable the pgAudit extension](https://supabase.com/dashboard/project/_/database/extensions) . 2. Configure `pgaudit.log` (see below). Perform a fast reboot if needed. 3. View your query logs under [Logs > Postgres Logs](https://supabase.com/dashboard/project/_/logs/postgres-logs) . ### Configuring `pgaudit.log`[#](https://supabase.com/docs/guides/telemetry/logs#configuring-pgauditlog) The stored value under `pgaudit.log` determines the classes of statements that are logged by [pgAudit extension](https://www.pgaudit.org/) . Refer to the pgAudit documentation for the [full list of values](https://github.com/pgaudit/pgaudit/blob/master/README.md#pgauditlog) . To enable logging for function calls/do blocks, writes, and DDL statements for a single session, execute the following within the session: 1-- temporary single-session config update2set pgaudit.log = 'function, write, ddl'; To _permanently_ set a logging configuration (beyond a single session), execute the following, then perform a fast reboot: 1-- equivalent permanent config update.2alter role postgres set pgaudit.log to 'function, write, ddl'; To help with debugging, we recommend adjusting the log scope to only relevant statements as having too wide of a scope would result in a lot of noise in your Postgres logs. Note that in the above example, the role is set to `postgres`. To log user-traffic flowing through the [HTTP APIs](https://supabase.com/docs/guides/database/api#rest-api-overview) powered by PostgREST, set your configuration values for the `authenticator`. 1-- for API-related logs2alter role authenticator set pgaudit.log to 'write'; By default, the log level will be set to `log`. To view other levels, run the following: 1-- adjust log level2alter role postgres set pgaudit.log_level to 'info';3alter role postgres set pgaudit.log_level to 'debug5'; Note that as per the pgAudit [log\_level documentation](https://github.com/pgaudit/pgaudit/blob/master/README.md#pgauditlog_level) , `error`, `fatal`, and `panic` are not allowed. To reset system-wide settings, execute the following, then perform a fast reboot: 1-- resets stored config.2alter role postgres reset pgaudit.log If any permission errors are encountered when executing `alter role postgres ...`, it is likely that your project has yet to receive the patch to the latest version of [supautils](https://github.com/supabase/supautils) , which is currently being rolled out. ### `RAISE`d log messages in Postgres[#](https://supabase.com/docs/guides/telemetry/logs#raise-d-log-messages-in-postgres) Messages that are manually logged via `RAISE INFO`, `RAISE NOTICE`, `RAISE WARNING`, and `RAISE LOG` are shown in Postgres Logs. Note that only messages at or above your logging level are shown. Syncing of messages to Postgres Logs may take a few minutes. If your logs aren't showing, check your logging level by running: 1show log_min_messages; Note that `LOG` is a higher level than `WARNING` and `ERROR`, so if your level is set to `LOG`, you will not see `WARNING` and `ERROR` messages. Logging realtime connections[#](https://supabase.com/docs/guides/telemetry/logs#logging-realtime-connections) -------------------------------------------------------------------------------------------------------------- Realtime doesn't log new WebSocket connections or Channel joins by default. Enable connection logging per client by including an `info` `log_level` parameter when instantiating the Supabase client. 1import { createClient } from '@supabase/supabase-js'23const options = {4 realtime: {5 params: {6 log_level: 'info',7 },8 },9}10const supabase = createClient('https://xyzcompany.supabase.co', 'publishable-or-anon-key', options) Logs Explorer[#](https://supabase.com/docs/guides/telemetry/logs#logs-explorer) -------------------------------------------------------------------------------- The [Logs Explorer](https://supabase.com/dashboard/project/_/logs-explorer) exposes logs from each part of the Supabase stack as a separate table that can be queried and joined using SQL. ![Logs Explorer](https://supabase.com/docs/img/guides/platform/logs/logs-explorer.png) You can access the following logs from the **Sources** drop-down: * `auth_logs`: GoTrue server logs, containing authentication/authorization activity. * `edge_logs`: Edge network logs, containing request and response metadata retrieved from Cloudflare. * `function_edge_logs`: Edge network logs for only edge functions, containing network requests and response metadata for each execution. * `function_logs`: Function internal logs, containing any `console` logging from within the edge function. * `postgres_logs`: Postgres database logs, containing statements executed by connected applications. * `realtime_logs`: Realtime server logs, containing client connection information. * `storage_logs`: Storage server logs, containing object upload and retrieval information. Querying with the Logs Explorer[#](https://supabase.com/docs/guides/telemetry/logs#querying-with-the-logs-explorer) -------------------------------------------------------------------------------------------------------------------- The Logs Explorer uses BigQuery and supports all [available SQL functions and operators](https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators) . ### Timestamp display and behavior[#](https://supabase.com/docs/guides/telemetry/logs#timestamp-display-and-behavior) Each log entry is stored with a `timestamp` as a `TIMESTAMP` data type. Use the appropriate [timestamp function](https://cloud.google.com/bigquery/docs/reference/standard-sql/timestamp_functions#timestamp) to utilize the `timestamp` field in a query. Raw top-level timestamp values are rendered as unix microsecond. To render the timestamps in a human-readable format, use the `DATETIME()` function to convert the unix timestamp display into an ISO-8601 timestamp. 1-- timestamp column without datetime()2select timestamp from ....3-- 166427018000045-- timestamp column with datetime()6select datetime(timestamp) from ....7-- 2022-09-27T09:17:10.439Z ### Unnesting arrays[#](https://supabase.com/docs/guides/telemetry/logs#unnesting-arrays) Each log event stores metadata an array of objects with multiple levels, and can be seen by selecting single log events in the Logs Explorer. To query arrays, use `unnest()` on each array field and add it to the query as a join. This allows you to reference the nested objects with an alias and select their individual fields. For example, to query the edge logs without any joins: 1select timestamp, metadata from edge_logs as t; The resulting `metadata` key is rendered as an array of objects in the Logs Explorer. In the following diagram, each box represents a nested array of objects: ![Without Unnesting](https://supabase.com/docs/img/unnesting-none.png) Perform a `cross join unnest()` to work with the keys nested in the `metadata` key. To query for a nested value, add a join for each array level: 1select timestamp, request.method, header.cf_ipcountry2from3 edge_logs as t4 cross join unnest(t.metadata) as metadata5 cross join unnest(metadata.request) as request6 cross join unnest(request.headers) as header; This surfaces the following columns available for selection: ![With Two Level Unnesting](https://supabase.com/docs/img/unnesting-2.png) This allows you to select the `method` and `cf_ipcountry` columns. In JS dot notation, the full paths for each selected column are: * `metadata[].request[].method` * `metadata[].request[].headers[].cf_ipcountry` ### LIMIT and result row limitations[#](https://supabase.com/docs/guides/telemetry/logs#limit-and-result-row-limitations) The Logs Explorer has a maximum of 1000 rows per run. Use `LIMIT` to optimize your queries by reducing the number of rows returned further. ### Best practices[#](https://supabase.com/docs/guides/telemetry/logs#best-practices) 1. Include a filter over **timestamp** Querying your entire log history might seem appealing. For **Enterprise** customers that have a large retention range, you run the risk of timeouts due additional time required to scan the larger dataset. 2. Avoid selecting large nested objects. Select individual values instead. When querying large objects, the columnar storage engine selects each column associated with each nested key, resulting in a large number of columns being selected. This inadvertently impacts the query speed and may result in timeouts or memory errors, especially for projects with a lot of logs. Instead, select only the values required. 1-- ❌ Avoid doing this2select3 datetime(timestamp),4 m as metadata -- <- metadata contains many nested keys5from6 edge_logs as t7 cross join unnest(t.metadata) as m;89-- ✅ Do this10select11 datetime(timestamp),12 r.method -- <- select only the required values13from14 edge_logs as t15 cross join unnest(t.metadata) as m16 cross join unnest(m.request) as r; ### Examples and templates[#](https://supabase.com/docs/guides/telemetry/logs#examples-and-templates) The Logs Explorer includes **Templates** (available in the Templates tab or the dropdown in the Query tab) to help you get started. For example, you can enter the following query in the SQL Editor to retrieve each user's IP address: 1select datetime(timestamp), h.x_real_ip2from3 edge_logs4 cross join unnest(metadata) as m5 cross join unnest(m.request) as r6 cross join unnest(r.headers) as h7where h.x_real_ip is not null and r.method = "GET"; ### Logs field reference[#](https://supabase.com/docs/guides/telemetry/logs#logs-field-reference) Refer to the full field reference for each available source below. Do note that in order to access each nested key, you would need to perform the [necessary unnesting joins](https://supabase.com/docs/guides/telemetry/logs#unnesting-arrays) API GatewayAuthAuth Audit LogsStorageFunction EdgeFunction RuntimePostgresRealtimePostgRESTSupavisor (Shared Pooler)PgBouncer (Dedicated Pooler)Database Version Upgrade | Path | Type | | --- | --- | | id | string | | timestamp | datetime | | event\_message | string | | identifier | string | | metadata.load\_balancer\_redirect\_identifier | string | | metadata.request.cf.asOrganization | string | | metadata.request.cf.asn | number | | metadata.request.cf.botManagement.corporateProxy | boolean | | metadata.request.cf.botManagement.detectionIds | number\[\] | | metadata.request.cf.botManagement.ja3Hash | string | | metadata.request.cf.botManagement.score | number | | metadata.request.cf.botManagement.staticResource | boolean | | metadata.request.cf.botManagement.verifiedBot | boolean | | metadata.request.cf.city | string | | metadata.request.cf.clientTcpRtt | number | | metadata.request.cf.clientTrustScore | number | | metadata.request.cf.colo | string | | metadata.request.cf.continent | string | | metadata.request.cf.country | string | | metadata.request.cf.edgeRequestKeepAliveStatus | number | | metadata.request.cf.httpProtocol | string | | metadata.request.cf.latitude | string | | metadata.request.cf.longitude | string | | metadata.request.cf.metroCode | string | | metadata.request.cf.postalCode | string | | metadata.request.cf.region | string | | metadata.request.cf.timezone | string | | metadata.request.cf.tlsCipher | string | | metadata.request.cf.tlsClientAuth.certPresented | string | | metadata.request.cf.tlsClientAuth.certRevoked | string | | metadata.request.cf.tlsClientAuth.certVerified | string | | metadata.request.cf.tlsExportedAuthenticator.clientFinished | string | | metadata.request.cf.tlsExportedAuthenticator.clientHandshake | string | | metadata.request.cf.tlsExportedAuthenticator.serverFinished | string | | metadata.request.cf.tlsExportedAuthenticator.serverHandshake | string | | metadata.request.cf.tlsVersion | string | | metadata.request.headers.cf\_connecting\_ip | string | | metadata.request.headers.cf\_ipcountry | string | | metadata.request.headers.cf\_ray | string | | metadata.request.headers.host | string | | metadata.request.headers.referer | string | | metadata.request.headers.x\_client\_info | string | | metadata.request.headers.x\_forwarded\_proto | string | | metadata.request.headers.x\_real\_ip | string | | metadata.request.host | string | | metadata.request.method | string | | metadata.request.path | string | | metadata.request.protocol | string | | metadata.request.search | string | | metadata.request.url | string | | metadata.response.headers.cf\_cache\_status | string | | metadata.response.headers.cf\_ray | string | | metadata.response.headers.content\_location | string | | metadata.response.headers.content\_range | string | | metadata.response.headers.content\_type | string | | metadata.response.headers.date | string | | metadata.response.headers.sb\_gateway\_version | string | | metadata.response.headers.transfer\_encoding | string | | metadata.response.headers.x\_kong\_proxy\_latency | string | | metadata.response.origin\_time | number | | metadata.response.status\_code | number | ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/telemetry/logs%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/telemetry/logs%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Seeding your database | Supabase Docs Local Development Seeding your database ========================= Populate your database with initial data for reproducible environments across local and testing. ---------------------------------------------------------------------------------------------------- * * * What is seed data?[#](https://supabase.com/docs/guides/local-development/seeding-your-database#what-is-seed-data) ------------------------------------------------------------------------------------------------------------------ Seeding is the process of populating a database with initial data, typically used to provide sample or default records for testing and development purposes. You can use this to create "reproducible environments" for local development, staging, and production. Using seed files[#](https://supabase.com/docs/guides/local-development/seeding-your-database#using-seed-files) --------------------------------------------------------------------------------------------------------------- Seed files are executed the first time you run `supabase start` and every time you run `supabase db reset`. Seeding occurs _after_ all database migrations have been completed. As a best practice, only include data insertions in your seed files, and avoid adding schema statements. By default, if no specific configuration is provided, the system will look for a seed file matching the pattern `supabase/seed.sql`. This maintains backward compatibility with earlier versions, where the seed file was placed in the `supabase` folder. You can add any SQL statements to this file. For example: 1insert into countries2 (name, code)3values4 ('United States', 'US'),5 ('Canada', 'CA'),6 ('Mexico', 'MX'); If you want to manage multiple seed files or organize them across different folders, you can configure additional paths or glob patterns in your `config.toml` (see the [next section](https://supabase.com/docs/guides/local-development/seeding-your-database#splitting-up-your-seed-file) for details). ### Splitting up your seed file[#](https://supabase.com/docs/guides/local-development/seeding-your-database#splitting-up-your-seed-file) For better modularity and maintainability, you can split your seed data into multiple files. For example, you can organize your seeds by table and include files such as `countries.sql` and `cities.sql`. Configure them in `config.toml` like so: 1[db.seed]2enabled = true3sql_paths = ['./countries.sql', './cities.sql'] Or to include all `.sql` files under a specific folder you can do: 1[db.seed]2enabled = true3sql_paths = ['./seeds/*.sql'] The CLI processes seed files in the order they are declared in the `sql_paths` array. If a glob pattern is used and matches multiple files, those files are sorted in lexicographic order to ensure consistent execution. Additionally: * The base folder for the pattern matching is `supabase` so `./countries.sql` will search for `supabase/countries.sql` * Files matched by multiple patterns will be deduplicated to prevent redundant seeding. * If a pattern does not match any files, a warning will be logged to help you troubleshoot potential configuration issues. Generating seed data[#](https://supabase.com/docs/guides/local-development/seeding-your-database#generating-seed-data) ----------------------------------------------------------------------------------------------------------------------- You can generate seed data for local development using [Snaplet](https://github.com/snaplet/seed) . To use Snaplet, you need to have Node.js and npm installed. You can add Node.js to your project by running `npm init -y` in your project directory. If this is your first time using Snaplet to seed your project, you'll need to set up Snaplet with the following command: 1npx @snaplet/seed init This command will analyze your database and its structure, and then generate a JavaScript client which can be used to define exactly how your data should be generated using code. The `init` command generates a configuration file, `seed.config.ts` and an example script, `seed.ts`, as a starting point. During `init` if you are not using an Object Relational Mapper (ORM) or your ORM is not in the supported list, choose `node-postgres`. In most cases you only want to generate data for specific schemas or tables. This is defined with `select`. Here is an example `seed.config.ts` configuration file: 1export default defineConfig({2 adapter: async () => {3 const client = new Client({4 connectionString: 'postgresql://postgres:postgres@localhost:54322/postgres',5 })6 await client.connect()7 return new SeedPg(client)8 },9 // We only want to generate data for the public schema10 select: ['!*', 'public.*'],11}) Suppose you have a database with the following schema: ![An example schema](https://supabase.com/docs/img/guides/cli/snaplet-example-schema.png) You can use the seed script example generated by Snaplet `seed.ts` to define the values you want to generate. For example: * A `Post` with the title `"There is a lot of snow around here!"` * The `Post.createdBy` user with an email address ending in `"@acme.org"` * Three `Post.comments` from three different users. 1import { createSeedClient } from '@snaplet/seed'2import { copycat } from '@snaplet/copycat'34async function main() {5 const seed = await createSeedClient({ dryRun: true })67 await seed.Post([8 {9 title: 'There is a lot of snow around here!',10 createdBy: {11 email: (ctx) =>12 copycat.email(ctx.seed, {13 domain: 'acme.org',14 }),15 },16 Comment: (x) => x(3),17 },18 ])1920 process.exit()21}2223main() Running `npx tsx seed.ts > supabase/seed.sql` generates the relevant SQL statements inside your `supabase/seed.sql` file: 1-- The `Post.createdBy` user with an email address ending in `"@acme.org"`2INSERT INTO "User" (name, email) VALUES ("John Snow", "snow@acme.org")34--- A `Post` with the title `"There is a lot of snow around here!"`5INSERT INTO "Post" (title, content, createdBy) VALUES (6 "There is a lot of snow around here!",7 "Lorem ipsum dolar",8 1)910--- Three `Post.Comment` from three different users.11INSERT INTO "User" (name, email) VALUES ("Stephanie Shadow", "shadow@domain.com")12INSERT INTO "Comment" (text, userId, postId) VALUES ("I love cheese", 2, 1)1314INSERT INTO "User" (name, email) VALUES ("John Rambo", "rambo@trymore.dev")15INSERT INTO "Comment" (text, userId, postId) VALUES ("Lorem ipsum dolar sit", 3, 1)1617INSERT INTO "User" (name, email) VALUES ("Steven Plank", "s@plank.org")18INSERT INTO "Comment" (text, userId, postId) VALUES ("Actually, that's not correct...", 4, 1) Whenever your database structure changes, you will need to regenerate `@snaplet/seed` to keep it in sync with the new structure. You can do this by running: 1npx @snaplet/seed sync You can further enhance your seed script by using Large Language Models to generate more realistic data. To enable this feature, set one of the following environment variables in your `.env` file: 1OPENAI_API_KEY=2GROQ_API_KEY= After setting the environment variables, run the following commands to sync and generate the seed data: 1npx @snaplet/seed sync2npx tsx seed.ts > supabase/seed.sql For more information, check out Snaplet's [seed documentation](https://snaplet-seed.netlify.app/seed/integrations/supabase) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/local-development/seeding-your-database%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/local-development/seeding-your-database%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Storage Quickstart | Supabase Docs Storage Storage Quickstart ====================== Learn how to use Supabase to store and serve files. ------------------------------------------------------- * * * This guide shows the basic functionality of Supabase Storage. Find a full [example application on GitHub](https://github.com/supabase/supabase/tree/master/examples/user-management/nextjs-user-management) . Concepts[#](https://supabase.com/docs/guides/storage/quickstart#concepts) -------------------------------------------------------------------------- Supabase Storage consists of Files, Folders, and Buckets. ### Files[#](https://supabase.com/docs/guides/storage/quickstart#files) Files can be any sort of media file. This includes images, GIFs, and videos. It is best practice to store files outside of your database because of their sizes. For security, HTML files are returned as plain text. ### Folders[#](https://supabase.com/docs/guides/storage/quickstart#folders) Folders are a way to organize your files (just like on your computer). There is no right or wrong way to organize your files. You can store them in whichever folder structure suits your project. ### Buckets[#](https://supabase.com/docs/guides/storage/quickstart#buckets) Buckets are distinct containers for files and folders. You can think of them like "super folders". Generally you would create distinct buckets for different Security and Access Rules. For example, you might keep all video files in a "video" bucket, and profile pictures in an "avatar" bucket. File, Folder, and Bucket names **must follow** [AWS object key naming guidelines](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html) and avoid use of any other characters. Create a bucket[#](https://supabase.com/docs/guides/storage/quickstart#create-a-bucket) ---------------------------------------------------------------------------------------- You can create a bucket using the Supabase Dashboard. Since the storage is interoperable with your Postgres database, you can also use SQL or our client libraries. Here we create a bucket called "avatars": DashboardSQLJavaScriptDartSwiftPython 1. Go to the [Storage](https://supabase.com/dashboard/project/_/storage/buckets) page in the Dashboard. 2. Click **New Bucket** and enter a name for the bucket. 3. Click **Create Bucket**. Upload a file[#](https://supabase.com/docs/guides/storage/quickstart#upload-a-file) ------------------------------------------------------------------------------------ You can upload a file from the Dashboard, or within a browser using our JS libraries. DashboardJavaScriptDart 1. Go to the [Storage](https://supabase.com/dashboard/project/_/storage/buckets) page in the Dashboard. 2. Select the bucket you want to upload the file to. 3. Click **Upload File**. 4. Select the file you want to upload. Download a file[#](https://supabase.com/docs/guides/storage/quickstart#download-a-file) ---------------------------------------------------------------------------------------- You can download a file from the Dashboard, or within a browser using our JS libraries. DashboardJavaScriptDartSwiftPython 1. Go to the [Storage](https://supabase.com/dashboard/project/_/storage/buckets) page in the Dashboard. 2. Select the bucket that contains the file. 3. Select the file that you want to download. 4. Click **Download**. Add security rules[#](https://supabase.com/docs/guides/storage/quickstart#add-security-rules) ---------------------------------------------------------------------------------------------- To restrict access to your files you can use either the Dashboard or SQL. DashboardSQL 1. Go to the [Storage](https://supabase.com/dashboard/project/_/storage/buckets) page in the Dashboard. 2. Click **Policies** in the sidebar. 3. Click **Add Policies** in the `OBJECTS` table to add policies for Files. You can also create policies for Buckets. 4. Choose whether you want the policy to apply to downloads (SELECT), uploads (INSERT), updates (UPDATE), or deletes (DELETE). 5. Give your policy a unique name. 6. Write the policy using SQL. * * * Watch video guide ![Video guide preview](https://supabase.com/docs/_next/image?url=https%3A%2F%2Fimg.youtube.com%2Fvi%2FJ9mTPY8rIXE%2F0.jpg&w=3840&q=75) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/storage/quickstart%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/storage/quickstart%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # How to do automatic retries with `supabase-js` | Supabase Docs REST API How to do automatic retries with `supabase-js` ================================================== Learn how to configure automatic retries for your Supabase API requests. ---------------------------------------------------------------------------- * * * ##### Important You should only enable retries if your requests fail with network errors (e.g. 520 status from Cloudflare). A high number of retries have the potential to exhaust the Data API connection pool, which could result in lower throughput and failed requests. Built-in retries for PostgREST queries[#](https://supabase.com/docs/guides/api/automatic-retries-in-supabase-js#built-in-retries-for-postgrest-queries) -------------------------------------------------------------------------------------------------------------------------------------------------------- Starting with `supabase-js` v2.102.0, PostgREST queries (`.from()`, `.rpc()`) include built-in automatic retries for transient errors. Retries are **enabled by default** and use exponential backoff with jitter. Retryable errors include HTTP status codes 408 (Request Timeout), 409 (Conflict), 503 (Service Unavailable), and 504 (Gateway Timeout), as well as network failures. Only idempotent HTTP methods (GET, HEAD, OPTIONS) and POST requests (used by PostgREST) are retried. ### Disable built-in retries[#](https://supabase.com/docs/guides/api/automatic-retries-in-supabase-js#disable-built-in-retries) If you prefer to handle retries yourself, you can disable the built-in retry behavior: 1import { createClient } from '@supabase/supabase-js'23const supabase = createClient('https://your-supabase-url.supabase.co', 'your-anon-key', {4 db: {5 retry: false,6 },7}) Custom retries with `fetch-retry`[#](https://supabase.com/docs/guides/api/automatic-retries-in-supabase-js#custom-retries-with-fetch-retry) -------------------------------------------------------------------------------------------------------------------------------------------- For more control over retry behavior, or to add retries to non-PostgREST requests (auth, storage, functions), you can use the `fetch-retry` package. This approach wraps the native `fetch` function and applies to all requests made by the client. ### 1\. Install dependencies[#](https://supabase.com/docs/guides/api/automatic-retries-in-supabase-js#1-install-dependencies) To get started, ensure you have both `supabase-js` and `fetch-retry` installed in your project: 1npm install @supabase/supabase-js fetch-retry ### 2\. Wrap the fetch function[#](https://supabase.com/docs/guides/api/automatic-retries-in-supabase-js#2-wrap-the-fetch-function) The `fetch-retry` package works by wrapping the native `fetch` function. You can create a custom fetch instance with retry logic and pass it to the `supabase-js` client. 1import { createClient } from '@supabase/supabase-js'2import fetchRetry from 'fetch-retry'34// Wrap the global fetch with fetch-retry5const fetchWithRetry = fetchRetry(fetch)67// Create a Supabase client instance with the custom fetch8const supabase = createClient(9 'https://your-supabase-url.supabase.co',10 'sb_publishable_... or anon key',11 {12 global: {13 fetch: fetchWithRetry,14 },15 }16) ### 3\. Configure retry options[#](https://supabase.com/docs/guides/api/automatic-retries-in-supabase-js#3-configure-retry-options) You can configure `fetch-retry` options to control retry behavior, such as the number of retries, retry delay, and which errors should trigger a retry. Here is an example with custom retry options: 1const fetchWithRetry = fetchRetry(fetch, {2 retries: 3, // Number of retry attempts3 retryDelay: (attempt) => Math.min(1000 * 2 ** attempt, 30000), // Exponential backoff4 retryOn: [520], // Retry only on Cloudflare errors5}) In this example, the `retryDelay` function implements an exponential backoff strategy, and retries are triggered only for specific HTTP status codes. ### 4\. Using the Supabase client[#](https://supabase.com/docs/guides/api/automatic-retries-in-supabase-js#4-using-the-supabase-client) With `fetch-retry` integrated, you can use the Supabase client as usual. The retry logic will automatically apply to all network requests made by `supabase-js`. 1async function fetchData() {2 const { data, error } = await supabase.from('your_table').select('*')34 if (error) {5 console.error('Error fetching data:', error)6 } else {7 console.log('Fetched data:', data)8 }9}1011fetchData() ### 5\. Fine-tuning retries for specific requests[#](https://supabase.com/docs/guides/api/automatic-retries-in-supabase-js#5-fine-tuning-retries-for-specific-requests) If you need different retry logic for certain requests, you can use the `retryOn` with a custom function to inspect the URL or response and decide whether to retry the request. 1const fetchWithRetry = fetchRetry(fetch, {2 retryDelay: (attempt) => Math.min(1000 * 2 ** attempt, 30000),3 retryOn: (attempt, error, response) => {4 const shouldRetry5 = (attempt: number, error: Error | null, response: Response | null) =>6 attempt < 37 && response8 && response.status == 520 // Cloudflare errors9 && response.url.includes('rpc/your_stored_procedure')1011 if (shouldRetry(attempt, error, response)) {12 console.log(`Retrying request... Attempt #${attempt}`, response)13 return true14 }1516 return false17 }18})1920async function yourStoredProcedure() {21 const { data, error } = await supabase22 .rpc('your_stored_procedure', { param1: 'value1' });2324 if (error) {25 console.log('Error executing RPC:', error);26 } else {27 console.log('Response:', data);28 }29}3031yourStoredProcedure(); By using `retryOn` with a custom function, you can define specific conditions for retrying requests. In this example, the retry logic is applied only to requests targeting a specific stored procedure. Conclusion[#](https://supabase.com/docs/guides/api/automatic-retries-in-supabase-js#conclusion) ------------------------------------------------------------------------------------------------ For most use cases, the built-in PostgREST retry mechanism is sufficient. Use `fetch-retry` when you need retries on non-PostgREST requests or need fine-grained control over retry behavior. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/api/automatic-retries-in-supabase-js%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/api/automatic-retries-in-supabase-js%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Billing FAQ | Supabase Docs Platform Billing FAQ =============== This documentation covers frequently asked questions around subscription plans, payments, invoices and billing in general ----------------------------------------------------------------------------------------------------------------------------- * * * Organizations and projects[#](https://supabase.com/docs/guides/platform/billing-faq#organizations-and-projects) ---------------------------------------------------------------------------------------------------------------- #### What are organizations and projects?[#](https://supabase.com/docs/guides/platform/billing-faq#what-are-organizations-and-projects) The Supabase Platform has "organizations" and "projects". An organization may contain multiple projects. Each project is a dedicated Supabase instance with all of its sub-services including Storage, Auth, Functions and Realtime. Each organization only has a single subscription with a single plan (Free, Pro, Team or Enterprise). Project add-ons such as [Compute](https://supabase.com/docs/guides/platform/compute-add-ons) , [IPv4](https://supabase.com/docs/guides/platform/ipv4-address) , [Log Drains](https://supabase.com/docs/guides/platform/log-drains) , [Advanced MFA](https://supabase.com/docs/guides/auth/auth-mfa/phone) , [Custom Domains](https://supabase.com/docs/guides/platform/custom-domains) and [PITR](https://supabase.com/docs/guides/platform/backups#point-in-time-recovery) are configured per project and are added to your organization subscription. Read more on [About billing on Supabase](https://supabase.com/docs/guides/platform/billing-on-supabase#organization-based-billing) . #### How many free projects can I have?[#](https://supabase.com/docs/guides/platform/billing-faq#how-many-free-projects-can-i-have) You are entitled to two active free projects. Paused projects do not count towards your quota. Note that within an organization, we count the free project limits from all members that are either Owner or Admin. If you’ve got another organization member with the Admin or Owner role that has already exhausted their free project quota, you won’t be able to launch another free project in that organization. You can create another Free Plan organization or change the role of the affected member in your [organization’s team settings](https://supabase.com/dashboard/org/_/team) . #### Can I mix free and paid projects in a single organization?[#](https://supabase.com/docs/guides/platform/billing-faq#can-i-mix-free-and-paid-projects-in-a-single-organization) The subscription plan is set on the organization level and it is not possible to mix paid and non-paid projects inside a single organization. However, you can have a paid and a free organization and make use of the [self-serve project transfers](https://supabase.com/docs/guides/platform/project-transfer) to organize your projects. All projects in an organization benefit from the subscription plan. If your organization is on the Pro Plan, all projects within the organization benefit from no project pausing, automated backups and so on. #### Can I transfer my projects to another organization?[#](https://supabase.com/docs/guides/platform/billing-faq#can-i-transfer-my-projects-to-another-organization) Yes, you can transfer your projects to another organization. You can find instructions on how to transfer your projects [here](https://supabase.com/docs/guides/platform/project-transfer) . #### Can I transfer my credits to another organization?[#](https://supabase.com/docs/guides/platform/billing-faq#can-i-transfer-my-credits-to-another-organization) Yes, you can transfer the credits to another organization. Submit a [support ticket](https://supabase.help/) . Pricing[#](https://supabase.com/docs/guides/platform/billing-faq#pricing) -------------------------------------------------------------------------- See the [Pricing page](https://supabase.com/pricing) for details. #### Are there any charges for paused projects?[#](https://supabase.com/docs/guides/platform/billing-faq#are-there-any-charges-for-paused-projects) No, we do not charge for paused projects. Compute hours are only counted for active instances. Paused projects do not incur any compute usage charges. #### How are multiple projects billed under a paid organization?[#](https://supabase.com/docs/guides/platform/billing-faq#how-are-multiple-projects-billed-under-a-paid-organization) We provide a dedicated server for every Supabase project. Each paid organization comes with $10 in Compute Credits to cover one project on the default compute size. Additional projects start at ~$10 a month (billed hourly). Running 3 projects in a Pro Plan organization on the default Micro instance: * $25 Pro Plan * $30 for 3 projects on the default compute size * $10 Compute credits ⇒ $45 / month Refer to our [Compute](https://supabase.com/docs/guides/platform/manage-your-usage/compute#billing-examples) docs for more examples and insights. #### How does compute billing work?[#](https://supabase.com/docs/guides/platform/billing-faq#how-does-compute-billing-work) Each Supabase project is a dedicated VM and Postgres database. By default, your instance runs on the Micro compute instance. You have the option to upgrade your compute size in your [Project settings](https://supabase.com/dashboard/project/_/settings/addons) . See [Compute Add-ons](https://supabase.com/docs/guides/platform/compute-add-ons) for available options. When you change your compute size, there are no immediate upfront charges. Instead, you will be billed based on the compute hours during your billing cycle reset. If you launch additional instances on your paid plan, we will add the corresponding compute hours to your final invoice. If you upgrade your project to a larger instance for 10 hours and then downgrade, you’ll only pay for the larger instance for the 10 hours of usage at the end of your billing cycle. You can see your current compute usage on your [organization’s usage page](https://supabase.com/dashboard/org/_/usage) . Read more about [Compute usage](https://supabase.com/docs/guides/platform/manage-your-usage/compute) . #### What is egress and how is it billed?[#](https://supabase.com/docs/guides/platform/billing-faq#what-is-egress-and-how-is-it-billed) Egress refers to the total bandwidth (network traffic) quota available to each organization. This quota can be utilized for various purposes such as Storage, Realtime, Auth, Functions, Supavisor, Log Drains and Database. Each plan includes a specific egress quota, and any additional usage beyond that quota is billed accordingly. We differentiate between cached (served via our CDN from cache hits) and uncached egress and give quotas for each type and have varying pricing (cached egress is cheaper). Cached egress only applies to Storage. Read more about [Egress usage](https://supabase.com/docs/guides/platform/manage-your-usage/egress) . Plans and subscriptions[#](https://supabase.com/docs/guides/platform/billing-faq#plans-and-subscriptions) ---------------------------------------------------------------------------------------------------------- #### How do I change my subscription plan?[#](https://supabase.com/docs/guides/platform/billing-faq#how-do-i-change-my-subscription-plan) Change your subscription plan in your [organization's billing settings](https://supabase.com/dashboard/org/_/billing) . To upgrade to an Enterprise Plan, complete the [Enterprise request form](https://forms.supabase.com/enterprise) . #### What happens if I cancel my subscription?[#](https://supabase.com/docs/guides/platform/billing-faq#what-happens-if-i-cancel-my-subscription) The organization is given [credits](https://supabase.com/docs/guides/platform/credits) for unused time on the subscription plan. The credits will not expire and can be used again in the future. You may see an additional charge for unbilled excessive usage charges from your previous billing cycle. Read more about [downgrades](https://supabase.com/docs/guides/platform/manage-your-subscription#downgrade) . #### I mistakenly upgraded the wrong organization and then downgraded it. Could you issue a refund?[#](https://supabase.com/docs/guides/platform/billing-faq#i-mistakenly-upgraded-the-wrong-organization-and-then-downgraded-it-could-you-issue-a-refund) We can transfer the amount as [credits](https://supabase.com/docs/guides/platform/credits) to another organization of your choice. You can use these credits to upgrade the organization, or if you have already upgraded, the credits will be used to pay the next month's invoice. Please create a [support ticket](https://supabase.help/) for this case. #### How do I get an annual subscription?[#](https://supabase.com/docs/guides/platform/billing-faq#how-do-i-get-an-annual-subscription) We currently do not support annual plans officially. However, you can do a [credit top-up](https://supabase.com/docs/guides/platform/credits#credit-top-ups) to avoid monthly payments. Quotas and spend caps[#](https://supabase.com/docs/guides/platform/billing-faq#quotas-and-spend-caps) ------------------------------------------------------------------------------------------------------ #### What will happen when I exceed the Free Plan quota?[#](https://supabase.com/docs/guides/platform/billing-faq#what-will-happen-when-i-exceed-the-free-plan-quota) You will be notified when you exceed the Free Plan quota. It is important to take action at this point. If you continue to exceed the limits without reducing your usage, service restrictions will apply. To avoid service restrictions, you have two options: reduce your usage or upgrade to a paid plan. Learn more about restrictions in the [Fair Use Policy](https://supabase.com/docs/guides/platform/billing-faq#fair-use-policy) section. #### What will happen when I exceed the Pro Plan quota and have the spend cap on?[#](https://supabase.com/docs/guides/platform/billing-faq#what-will-happen-when-i-exceed-the-pro-plan-quota-and-have-the-spend-cap-on) You will be notified when you exceed your Pro Plan quota. To unblock yourself, you can toggle off your spend cap in your [organization's billing settings](https://supabase.com/dashboard/org/_/billing) to pay for over-usage beyond the Pro plans limits. If you continue to exceed the limits without reducing your usage or turning off the spend cap, restrictions will apply. Learn more about restrictions in the [Fair Use Policy](https://supabase.com/docs/guides/platform/billing-faq#fair-use-policy) section. #### How do I scale beyond the limits of my Pro Plan?[#](https://supabase.com/docs/guides/platform/billing-faq#how-do-i-scale-beyond-the-limits-of-my-pro-plan) The Pro Plan has a Spend Cap enabled by default to keep costs under control. If you want to scale beyond the plan's included quota, switch off the Spend Cap to pay for additional usage beyond the plans included limits. You can toggle the Spend Cap in the [organization's billing settings](https://supabase.com/dashboard/org/_/billing) . Read more about the [Spend Cap](https://supabase.com/docs/guides/platform/cost-control#spend-cap) . Fair Use Policy[#](https://supabase.com/docs/guides/platform/billing-faq#fair-use-policy) ------------------------------------------------------------------------------------------ #### What is the Fair Use Policy?[#](https://supabase.com/docs/guides/platform/billing-faq#what-is-the-fair-use-policy) Our Fair Use Policy gives developers the freedom to build and experiment with Supabase, while protecting our infrastructure. Under the Fair Use policy, service restrictions may apply to your organization if: * You continually exceed the Free Plan quota * You continually exceed Pro Plan quota and have the spend cap enabled * You have overdue invoices * You have an expired credit card You will receive a notification before Fair Use Policy restrictions are applied. However, in some cases, like suspected abuse of our services, restrictions may be applied without prior notice. #### What is a grace period and does it reset after usage drops?[#](https://supabase.com/docs/guides/platform/billing-faq#what-is-a-grace-period-and-does-it-reset-after-usage-drops) When your organization exceeds plan limits, you receive a grace period before fair use policy applies. After this grace period ends, the dashboard will continue to show a notice indicating that your grace period is over, even if you have dropped back under plan limits. This is a warning that serves as an indicator that your organization previously exceeded usage limits. This persistent warning means that if you exceed your plan limits again, you will not receive another grace period and your project will be restricted. The notice and indicator will automatically clear if you continue to stay under plan limits for multiple billing cycles. #### How is the Fair Use Policy applied?[#](https://supabase.com/docs/guides/platform/billing-faq#how-is-the-fair-use-policy-applied) The Fair Use Policy is applied through service restrictions. This could mean: * Pausing projects * Switching databases to read-only mode * Disabling new project launches/transfers * Responding with a [402 status code](https://supabase.com/docs/guides/platform/http-status-codes#402-service-restriction) for all API requests The Fair Use Policy is generally applied to all projects of the restricted organization. #### How can I remove restrictions applied from the Fair Use Policy?[#](https://supabase.com/docs/guides/platform/billing-faq#how-can-i-remove-restrictions-applied-from-the-fair-use-policy) To remove restrictions, you will need to address the issue that caused the restriction. This could be reducing your usage, paying overdue invoices, updating your payment method, or any other issue that caused the restriction. Once the issue is resolved, the restriction will be lifted. Restrictions due to usage limits are lifted once your quota refills at the start of the next billing cycle. Note that there may be a short delay after your billing period resets before restrictions are fully lifted. You can see when your current billing cycle ends on the [billing page](https://supabase.com/dashboard/org/_/billing) under "Upcoming Invoice". You can also lift restrictions immediately by [upgrading](https://supabase.com/dashboard/org/_/billing?panel=subscriptionPlan) to Pro (if on Free Plan) or by [disabling spend cap](https://supabase.com/dashboard/org/_/billing?panel=costControl) (if on Pro Plan with spend cap enabled). Pausing or deleting a project stops new usage from accumulating, but does not remove usage that already occurred during the current billing cycle. For quota-based limits, that usage still counts until the billing period resets. Reports and invoices[#](https://supabase.com/docs/guides/platform/billing-faq#reports-and-invoices) ---------------------------------------------------------------------------------------------------- #### Where do I find my invoices?[#](https://supabase.com/docs/guides/platform/billing-faq#where-do-i-find-my-invoices) You can find all invoices from your organization on your [organization’s invoices page](https://supabase.com/dashboard/org/_/billing#invoices) . #### Where can I see a breakdown of usage?[#](https://supabase.com/docs/guides/platform/billing-faq#where-can-i-see-a-breakdown-of-usage) You can find the breakdown of your usage on your [organization’s usage page](https://supabase.com/dashboard/org/_/usage) . #### Where can I check my credit balance?[#](https://supabase.com/docs/guides/platform/billing-faq#where-can-i-check-my-credit-balance) You can check your Credit balance on the [organization’s billing page](https://supabase.com/dashboard/org/_/billing) . Credits will be used on future invoices before charging your payment method. If you have enough credits to cover an invoice, there is no charge at all. #### Can I include the VAT number?[#](https://supabase.com/docs/guides/platform/billing-faq#can-i-include-the-vat-number) You can update your VAT number in the Tax ID section of your [organization’s billing page](https://supabase.com/dashboard/org/_/billing) . #### Can I change the details of an existing invoice?[#](https://supabase.com/docs/guides/platform/billing-faq#can-i-change-the-details-of-an-existing-invoice) Any changes made to your billing details will only be reflected in your upcoming invoices. Our payment provider cannot regenerate previous invoices. Therefore, make sure to update the billing details before the upcoming invoices are finalized. Payments and billing cycle[#](https://supabase.com/docs/guides/platform/billing-faq#payments-and-billing-cycle) ---------------------------------------------------------------------------------------------------------------- #### What payment methods are available?[#](https://supabase.com/docs/guides/platform/billing-faq#what-payment-methods-are-available) We accept credit card payments only. If you cannot pay via credit card, we do offer alternatives for larger upfront payments. Create a [support ticket](https://supabase.help/) in case you’re interested. #### What credit card brands are supported?[#](https://supabase.com/docs/guides/platform/billing-faq#what-credit-card-brands-are-supported) Visa, Mastercard, American Express, Japan Credit Bureau (JCB), China UnionPay (CUP), Cartes Bancaires #### What currency can I pay in?[#](https://supabase.com/docs/guides/platform/billing-faq#what-currency-can-i-pay-in) All our invoices are issued in USD, but you can pay in any currency so long as the credit card provider allows charging in USD after conversion. #### Can I change the payment method?[#](https://supabase.com/docs/guides/platform/billing-faq#can-i-change-the-payment-method) Yes, you will have to add the new payment method before being allowed to remove the old one. This can be done from your dashboard on the [organization’s billing page](https://supabase.com/dashboard/org/_/billing) . Read more on [Manage your payment methods](https://supabase.com/docs/guides/platform/manage-your-subscription#manage-your-payment-methods) . #### Can I pay upfront for multiple months?[#](https://supabase.com/docs/guides/platform/billing-faq#can-i-pay-upfront-for-multiple-months) You can top up your credit balance to cover multiple months through your [organization’s billing page](https://supabase.com/dashboard/org/_/billing) . Read more on [Credit top-ups](https://supabase.com/docs/guides/platform/credits#credit-top-ups) . #### When are payments taken?[#](https://supabase.com/docs/guides/platform/billing-faq#when-are-payments-taken) Payments are taken at the beginning of each billing cycle. You will be charged once a month. You can see the current billing cycle and upcoming invoice in your [organization's billing settings](https://supabase.com/dashboard/org/_/billing) . The subscription plan fee is charged upfront, whereas usage-charges, including compute, are charged in arrears based on your usage. Read more on [Your monthly invoice](https://supabase.com/docs/guides/platform/your-monthly-invoice) . #### Where can I change my billing details?[#](https://supabase.com/docs/guides/platform/billing-faq#where-can-i-change-my-billing-details) You can update your billing details on the [organization’s billing page](https://supabase.com/dashboard/org/_/billing) . Note that any changes made to your billing details will only be reflected in your upcoming invoices. Our payment provider cannot regenerate previous invoices. #### What happens if I am unable to make the payment?[#](https://supabase.com/docs/guides/platform/billing-faq#what-happens-if-i-am-unable-to-make-the-payment) When an invoice becomes overdue, we will pause your projects and downgrade your organization to the Free Plan. You will be able to restore your projects once you have paid all outstanding invoices. #### Why am I overdue?[#](https://supabase.com/docs/guides/platform/billing-faq#why-am-i-overdue) We were unable to charge your payment method. This likely means that the payment was not successfully processed with the credit card on your account profile. You can be overdue when * A card is expired * The bank declined the payment * You had insufficient funds * There was no card on record Check your payment methods in your [organization’s billing page](https://supabase.com/dashboard/org/_/billing) to ensure there are no expired payment methods and the correct payment method is marked as default. If you are still facing issues, raise a [support ticket](https://supabase.help/) . Payments are always in USD and may show up as coming from Singapore, given our payment entity is in Singapore. Make sure you allow payments from Singapore and in USD #### Can I delay my payment?[#](https://supabase.com/docs/guides/platform/billing-faq#can-i-delay-my-payment) No, you cannot delay your payment. #### Can I get a refund of my unused credits?[#](https://supabase.com/docs/guides/platform/billing-faq#can-i-get-a-refund-of-my-unused-credits) No, we do not provide refunds. Please refer to our [Terms of Service](https://supabase.com/terms#1-fees) . #### What do I do if my bill looks wrong?[#](https://supabase.com/docs/guides/platform/billing-faq#what-do-i-do-if-my-bill-looks-wrong) Take a moment to review our [Your monthly invoice](https://supabase.com/docs/guides/platform/your-monthly-invoice) page, which may help clarify any questions about your invoice. If it still looks wrong, submit a [support ticket](https://supabase.help/) through the dashboard. Select the affected organization and provide the invoice number for us to look at your case. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/platform/billing-faq%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/platform/billing-faq%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Going to Production | Supabase Docs AI & Vectors Going to Production ======================= Going to production checklist for AI applications. ------------------------------------------------------ * * * This guide will help you to prepare your application for production. We'll provide actionable steps to help you scale your application, ensure that it is reliable, can handle the load, and provide optimal accuracy for your use case. See our [Engineering for Scale](https://supabase.com/docs/guides/ai/engineering-for-scale) guide for more information about engineering at scale. Do you need indexes?[#](https://supabase.com/docs/guides/ai/going-to-prod#do-you-need-indexes) ----------------------------------------------------------------------------------------------- Sequential scans will result in significantly higher latencies and lower throughput, guaranteeing 100% accuracy and not being RAM bound. There are a couple of cases where you might not need indexes: * You have a small dataset and don't need to scale it. * You are not expecting high amounts of vector search queries per second. * You need to guarantee 100% accuracy. You don't have to create indexes in these cases and can use sequential scans instead. This type of workload will not be RAM bound and will not require any additional resources but will result in higher latencies and lower throughput. Extra CPU cores may help to improve queries per second, but it will not help to improve latency. On the other hand, if you need to scale your application, you will need to [create indexes](https://supabase.com/docs/guides/ai/vector-indexes) . This will result in lower latencies and higher throughput, but will require additional RAM to make use of Postgres Caching. Also, using indexes will result in lower accuracy, since you are replacing exact (KNN) search with approximate (ANN) search. HNSW vs IVFFlat indexes[#](https://supabase.com/docs/guides/ai/going-to-prod#hnsw-vs-ivfflat-indexes) ------------------------------------------------------------------------------------------------------ `pgvector` supports two types of indexes: HNSW and IVFFlat. We recommend using [HNSW](https://supabase.com/docs/guides/ai/vector-indexes/hnsw-indexes) because of its [performance](https://supabase.com/blog/increase-performance-pgvector-hnsw#hnsw-performance-1536-dimensions) and [robustness against changing data](https://supabase.com/docs/guides/ai/vector-indexes/hnsw-indexes#when-should-you-create-hnsw-indexes) . ![dbpedia embeddings comparing ivfflat and hnsw queries-per-second using the 4XL compute add-on](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fai%2Fgoing-prod%2Fdbpedia-ivfflat-vs-hnsw-4xl--light.png&w=3840&q=75) HNSW, understanding `ef_construction`, `ef_search`, and `m`[#](https://supabase.com/docs/guides/ai/going-to-prod#hnsw-understanding-efconstruction--efsearch--and-m) --------------------------------------------------------------------------------------------------------------------------------------------------------------------- Index build parameters: * `m` is the number of bi-directional links created for every new element during construction. Higher `m` is suitable for datasets with high dimensionality and/or high accuracy requirements. Reasonable values for `m` are between 2 and 100. Range 12-48 is a good starting point for most use cases (16 is the default value). * `ef_construction` is the size of the dynamic list for the nearest neighbors (used during the construction algorithm). Higher `ef_construction` will result in better index quality and higher accuracy, but it will also increase the time required to build the index. `ef_construction` has to be at least 2 \* `m` (64 is the default value). At some point, increasing `ef_construction` does not improve the quality of the index. You can measure accuracy when `ef_search`\=`ef_construction`: if accuracy is lower than 0.9, then there is room for improvement. Search parameters: * `ef_search` is the size of the dynamic list for the nearest neighbors (used during the search). Increasing `ef_search` will result in better accuracy, but it will also increase the time required to execute a query (40 is the default value). ![dbpedia embeddings comparing hnsw queries-per-second using different build parameters](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fai%2Fgoing-prod%2Fdbpedia-hnsw-build-parameters--light.png&w=3840&q=75) IVFFlat, understanding `probes` and `lists`[#](https://supabase.com/docs/guides/ai/going-to-prod#ivfflat-understanding-probes-and-lists) ----------------------------------------------------------------------------------------------------------------------------------------- Indexes used for approximate vector similarity search in pgvector divides a dataset into partitions. The number of these partitions is defined by the `lists` constant. The `probes` controls how many lists are going to be searched during a query. The values of lists and probes directly affect accuracy and queries per second (QPS). * Higher `lists` means an index will be built slower, but you can achieve better QPS and accuracy. * Higher `probes` means that select queries will be slower, but you can achieve better accuracy. * `lists` and `probes` are not independent. Higher `lists` means that you will have to use higher `probes` to achieve the same accuracy. You can find more examples of how `lists` and `probes` constants affect accuracy and QPS in [pgvector 0.4.0 performance](https://supabase.com/blog/pgvector-performance) blogpost. ![multi database](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fai%2Fgoing-prod%2Flists-count--light.png&w=3840&q=75) Performance tips when using indexes[#](https://supabase.com/docs/guides/ai/going-to-prod#performance-tips-when-using-indexes) ------------------------------------------------------------------------------------------------------------------------------ First, a few generic tips which you can pick and choose from: 1. The Supabase managed platform will automatically optimize Postgres configs for you based on your compute add-on. But if you self-host, consider **adjusting your Postgres config** based on RAM & CPU cores. See [example optimizations](https://gist.github.com/egor-romanov/323e2847851bbd758081511785573c08) for more details. 2. Prefer `inner-product` to `L2` or `Cosine` distances if your vectors are normalized (like `text-embedding-ada-002`). If embeddings are not normalized, `Cosine` distance should give the best results with an index. 3. **Pre-warm your database.** Implement the warm-up technique before transitioning to production or running benchmarks. * Use [pg\_prewarm](https://www.postgresql.org/docs/current/pgprewarm.html) to load the index into RAM `select pg_prewarm('vecs.docs_vec_idx');`. This will help to avoid cold cache issues. * Execute 10,000 to 50,000 "warm-up" queries before each benchmark/prod. This will help to utilize cache and buffers more efficiently. 4. **Establish your workload.** Fine-tune `m` and `ef_construction` or `lists` constants for the pgvector index to accelerate your queries (at the expense of a slower build times). For instance, for benchmarks with 1,000,000 OpenAI embeddings, we set `m` and `ef_construction` to 32 and 80, and it resulted in 35% higher QPS than 24 and 56 values respectively. 5. **Benchmark your own specific workloads.** Doing this during cache warm-up helps gauge the best value for the index build parameters, balancing accuracy with queries per second (QPS). Going into production[#](https://supabase.com/docs/guides/ai/going-to-prod#going-into-production) -------------------------------------------------------------------------------------------------- 1. Decide if you are going to use indexes or not. You can skip the rest of this guide if you do not use indexes. 2. Over-provision RAM during preparation. You can scale down in step `5`, but it's better to start with a larger size to get the best results for RAM requirements. (We'd recommend at least 8XL if you're using Supabase.) 3. Upload your data to the database. If you use the [`vecs`](https://supabase.com/docs/guides/ai/python/api) library, it will automatically generate an index with default parameters. 4. Run a benchmark using randomly generated queries and observe the results. Again, you can use the `vecs` library with the `ann-benchmarks` tool. Do it with default values for index build parameters, you can later adjust them to get the best results. 5. Monitor the RAM usage, and save it as a note for yourself. You would likely want to use a compute add-on in the future that has the same amount of RAM that was used at the moment (both actual RAM usage and RAM used for cache and buffers). 6. Scale down your compute add-on to the one that would have the same amount of RAM used at the moment. 7. Repeat step 3 to load the data into RAM. You should see QPS increase on subsequent runs, and stop when it no longer increases. 8. Run a benchmark using real queries and observe the results. You can use the `vecs` library for that as well with `ann-benchmarks` tool. Tweak `ef_search` for HNSW or `probes` for IVFFlat until you see that both accuracy and QPS match your requirements. 9. If you want higher QPS you can increase `m` and `ef_construction` for HNSW or `lists` for IVFFlat parameters (consider switching from IVF to HNSW). You have to rebuild the index with a higher `m` and `ef_construction` values and repeat steps 6-7 to find the best combination of `m`, `ef_construction` and `ef_search` constants to achieve the best QPS and accuracy values. Higher `m`, `ef_construction` mean that index will build slower, but you can achieve better QPS and accuracy. Higher `ef_search` mean that select queries will be slower, but you can achieve better accuracy. Useful links[#](https://supabase.com/docs/guides/ai/going-to-prod#useful-links) -------------------------------------------------------------------------------- Don't forget to check out the general [Production Checklist](https://supabase.com/docs/guides/platform/going-into-prod) to ensure your project is secure, performant, and will remain available for your users. You can look at our [Choosing Compute Add-on](https://supabase.com/docs/guides/ai/choosing-compute-addon) guide to get a basic understanding of how much compute you might need for your workload. Or take a look at our [pgvector 0.5.0 performance](https://supabase.com/blog/increase-performance-pgvector-hnsw) and [pgvector 0.4.0 performance](https://supabase.com/blog/pgvector-performance) blog posts to see what pgvector is capable of and how the above technique can be used to achieve the best results. ![multi database](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fai%2Fgoing-prod%2Fsize-to-rps--light.png&w=3840&q=75) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/ai/going-to-prod%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/ai/going-to-prod%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Structured and Unstructured | Supabase Docs AI & Vectors Structured and Unstructured =============================== Supabase is flexible enough to associate structured and unstructured metadata with embeddings. -------------------------------------------------------------------------------------------------- * * * Most vector stores treat metadata associated with embeddings like NoSQL, unstructured data. Supabase is flexible enough to store unstructured and structured metadata. Structured[#](https://supabase.com/docs/guides/ai/structured-unstructured#structured) -------------------------------------------------------------------------------------- 1create table docs (2 id uuid primary key,3 embedding extensions.vector(3),4 content text,5 url text6);78insert into docs9 (id, embedding, content, url)10values11 ('79409372-7556-4ccc-ab8f-5786a6cfa4f7', array[0.1, 0.2, 0.3], 'Hello world', '/hello-world'); Notice that we've associated two pieces of metadata, `content` and `url`, with the embedding. Those fields can be filtered, constrained, indexed, and generally operated on using the full power of SQL. Structured metadata fits naturally with a traditional Supabase application, and can be managed via database [migrations](https://supabase.com/docs/guides/deployment/database-migrations) . Unstructured[#](https://supabase.com/docs/guides/ai/structured-unstructured#unstructured) ------------------------------------------------------------------------------------------ 1create table docs (2 id uuid primary key,3 embedding extensions.vector(3),4 meta jsonb5);67insert into docs8 (id, embedding, meta)9values10 (11 '79409372-7556-4ccc-ab8f-5786a6cfa4f7',12 array[0.1, 0.2, 0.3],13 '{"content": "Hello world", "url": "/hello-world"}'14 ); An unstructured approach does not specify the metadata fields that are expected. It stores all metadata in a flexible `json`/`jsonb` column. The tradeoff is that the querying/filtering capabilities of a schemaless data type are less flexible than when each field has a dedicated column. It also pushes the burden of metadata data integrity onto application code, which is more error prone than enforcing constraints in the database. The unstructured approach is recommended: * for ephemeral/interactive workloads e.g. data science or scientific research * when metadata fields are user-defined or unknown * during rapid prototyping Client libraries like python's [vecs](https://github.com/supabase/vecs) use this structure. For example, running: 1#!/usr/bin/env python32import vecs34# In practice, do not hard-code your password. Use environment variables.5DB_CONNECTION = "postgresql://:@:/"67# create vector store client8vx = vecs.create_client(DB_CONNECTION)910docs = vx.get_or_create_collection(name="docs", dimension=1536)1112docs.upsert(vectors=[13 ('79409372-7556-4ccc-ab8f-5786a6cfa4f7', [100, 200, 300], { url: '/hello-world' })14]) automatically creates the unstructured SQL table during the call to `get_or_create_collection`. Note that when working with client libraries that emit SQL DDL, like `create table ...`, you should add that SQL to your migrations when moving to production to maintain a single source of truth for your database's schema. Hybrid[#](https://supabase.com/docs/guides/ai/structured-unstructured#hybrid) ------------------------------------------------------------------------------ The structured metadata style is recommended when the fields being tracked are known in advance. If you have a combination of known and unknown metadata fields, you can accommodate the unknown fields by adding a `json`/`jsonb` column to the table. In that situation, known fields should continue to use dedicated columns for best query performance and throughput. 1create table docs (2 id uuid primary key,3 embedding extensions.vector(3),4 content text,5 url string,6 meta jsonb7);89insert into docs10 (id, embedding, content, url, meta)11values12 (13 '79409372-7556-4ccc-ab8f-5786a6cfa4f7',14 array[0.1, 0.2, 0.3],15 'Hello world',16 '/hello-world',17 '{"key": "value"}'18 ); Choosing the right model[#](https://supabase.com/docs/guides/ai/structured-unstructured#choosing-the-right-model) ------------------------------------------------------------------------------------------------------------------ Both approaches create a table where you can store your embeddings and some metadata. You should choose the best approach for your use-case. In summary: * Structured metadata is best when fields are known in advance or query patterns are predictable e.g. a production Supabase application * Unstructured metadata is best when fields are unknown/user-defined or when working with data interactively e.g. exploratory research Both approaches are valid, and the one you should choose depends on your use-case. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/ai/structured-unstructured%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/ai/structured-unstructured%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Compute and Disk | Supabase Docs Platform Compute and Disk ==================== * * * Compute[#](https://supabase.com/docs/guides/platform/compute-and-disk#compute) ------------------------------------------------------------------------------- Every project on the Supabase Platform comes with its own dedicated Postgres instance. The following table describes the base instances, Nano (free plan) and Micro (paid plans), with additional compute instance sizes available if you need extra performance when scaling up. ##### Nano instances in paid plan organizations In paid organizations, Nano Compute are billed at the same price as Micro Compute. It is recommended to upgrade your Project from Nano Compute to Micro Compute when it's convenient for you. Compute sizes are not auto-upgraded because of the downtime incurred. See [Supabase Pricing](https://supabase.com/pricing) for more information. You cannot launch Nano instances on paid plans, only Micro and above - but you might have Nano instances after upgrading from Free Plan. | Compute Size | Hourly Price USD | Monthly Price USD | CPU | Memory | Max DB Size (Recommended)[1](https://supabase.com/docs/guides/platform/compute-and-disk#user-content-fn-2) | | --- | --- | --- | --- | --- | --- | | Nano[2](https://supabase.com/docs/guides/platform/compute-and-disk#user-content-fn-3) | $0 | $0 | Shared | Up to 0.5 GB | 500 MB | | Micro | $0.01344 | ~$10 | 2-core ARM (shared) | 1 GB | 10 GB | | Small | $0.0206 | ~$15 | 2-core ARM (shared) | 2 GB | 50 GB | | Medium | $0.0822 | ~$60 | 2-core ARM (shared) | 4 GB | 100 GB | | Large | $0.1517 | ~$110 | 2-core ARM (dedicated) | 8 GB | 200 GB | | XL | $0.2877 | ~$210 | 4-core ARM (dedicated) | 16 GB | 500 GB | | 2XL | $0.562 | ~$410 | 8-core ARM (dedicated) | 32 GB | 1 TB | | 4XL | $1.32 | ~$960 | 16-core ARM (dedicated) | 64 GB | 2 TB | | 8XL | $2.562 | ~$1,870 | 32-core ARM (dedicated) | 128 GB | 4 TB | | 12XL | $3.836 | ~$2,800 | 48-core ARM (dedicated) | 192 GB | 6 TB | | 16XL | $5.12 | ~$3,730 | 64-core ARM (dedicated) | 256 GB | 10 TB | | \>16XL | \- | [Contact Us](https://supabase.com/dashboard/support/new?category=sales&subject=Enquiry%20about%20larger%20instance%20sizes) | Custom | Custom | Custom | Compute sizes can be changed by first selecting your project in the dashboard [here](https://supabase.com/dashboard/project/_/settings/compute-and-disk) and the upgrade process will [incur downtime](https://supabase.com/docs/guides/platform/compute-and-disk#upgrades) . ![Compute Size Selection](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fguides%2Fplatform%2Fcompute-size-selection--light.png&w=3840&q=75) We charge hourly for additional compute based on your usage. Read more about [usage-based billing for compute](https://supabase.com/docs/guides/platform/manage-your-usage/compute) . ### Dedicated vs shared CPU[#](https://supabase.com/docs/guides/platform/compute-and-disk#dedicated-vs-shared-cpu) All Postgres databases on Supabase run in isolated environments. Compute instances smaller than `Large` compute size have CPUs which can burst to higher performance levels for short periods of time. Instances bigger than `Large` have predictable performance levels and do not exhibit the same burst behavior. ### Compute upgrades [#](https://supabase.com/docs/guides/platform/compute-and-disk#upgrades) Compute instance changes are usually applied with less than 2 minutes of downtime, but can take longer depending on the underlying Cloud Provider. When considering compute upgrades, assess whether your bottlenecks are hardware-constrained or software-constrained. For example, you may want to look into [optimizing the number of connections](https://supabase.com/docs/guides/platform/performance#optimizing-the-number-of-connections) or [examining query performance](https://supabase.com/docs/guides/platform/performance#examining-query-performance) . When you're happy with your Postgres instance's performance, then you can focus on additional compute resources. For example, you can load test your application in staging to understand your compute requirements. You can also start out on a smaller tier, [create a report](https://supabase.com/dashboard/project/_/observability) in the Dashboard to monitor your CPU utilization, and upgrade as needed. Disk[#](https://supabase.com/docs/guides/platform/compute-and-disk#disk) ------------------------------------------------------------------------- Supabase databases are backed by high performance SSD disks. The _effective performance_ depends on a combination of all the following factors: * Compute size * Provisioned Disk Throughput * Provisioned Disk IOPS: Input/Output Operations per Second, which measures the number of read and write operations. * Disk type: io2 or gp3 * Disk size The disk size and the disk type dictate the maximum IOPS and throughput that can be provisioned. The effective IOPS is the lower of the IOPS supported by the compute size or the provisioned IOPS of the disk. Similarly, the effective throughout is the lower of the throughput supported by the compute size and the provisioned throughput of the disk. The following sections explain how these attributes affect disk performance. ### Compute size[#](https://supabase.com/docs/guides/platform/compute-and-disk#compute-size) The compute size of your project affects the effective disk throughput and IOPS. The table below shows both the baseline (sustained) limits and the burst (maximum) limits for each instance size. For instance, an 8XL compute instance has a throughput of 1,188 MB/s and IOPS of 40,000. | Compute Instance | Baseline Throughput (MB/s) | Max Throughput (MB/s) | Baseline IOPS | Max IOPS | | --- | --- | --- | --- | --- | | Nano (free) | 5 MB/s | 261 MB/s | 250 IOPS | 11,800 IOPS | | Micro | 11 MB/s | 261 MB/s | 500 IOPS | 11,800 IOPS | | Small | 22 MB/s | 261 MB/s | 1,000 IOPS | 11,800 IOPS | | Medium | 43 MB/s | 261 MB/s | 2,000 IOPS | 11,800 IOPS | | Large | 79 MB/s | 594 MB/s | 3,600 IOPS | 20,000 IOPS | | XL | 149 MB/s | 594 MB/s | 6,000 IOPS | 20,000 IOPS | | 2XL | 297 MB/s | 594 MB/s | 12,000 IOPS | 20,000 IOPS | | 4XL | 594 MB/s | 594 MB/s | 20,000 IOPS | 20,000 IOPS | | 8XL | 1,188 MB/s | 1,188 MB/s | 40,000 IOPS | 40,000 IOPS | | 12XL | 1,781 MB/s | 1,781 MB/s | 50,000 IOPS | 50,000 IOPS | | 16XL | 2,375 MB/s | 2,375 MB/s | 80,000 IOPS | 80,000 IOPS | | 24XL | 3,750 MB/s | 3,750 MB/s | 120,000 IOPS | 120,000 IOPS | | 24XL - Optimized CPU | 3,750 MB/s | 3,750 MB/s | 120,000 IOPS | 120,000 IOPS | | 24XL - Optimized Memory | 3,750 MB/s | 3,750 MB/s | 120,000 IOPS | 120,000 IOPS | | 24XL - High Memory | 3,750 MB/s | 3,750 MB/s | 120,000 IOPS | 120,000 IOPS | | 48XL | 5,000 MB/s | 5,000 MB/s | 240,000 IOPS | 240,000 IOPS | | 48XL - Optimized CPU | 5,000 MB/s | 5,000 MB/s | 240,000 IOPS | 240,000 IOPS | | 48XL - Optimized Memory | 5,000 MB/s | 5,000 MB/s | 240,000 IOPS | 240,000 IOPS | | 48XL - High Memory | 5,000 MB/s | 5,000 MB/s | 240,000 IOPS | 240,000 IOPS | Smaller compute instances like Nano, Micro, Small, and Medium can burst above baseline for short periods of time. Once burst capacity is exhausted, performance returns to baseline. If you need consistent disk performance, consider upgrading your compute size. Larger compute instances (4XL and above) are designed for sustained, high performance with specific IOPS and throughput limits which you can [configure](https://supabase.com/docs/guides/platform/manage-your-usage/disk-throughput) . If you hit your IOPS or throughput limit, throttling will occur. ### Choosing the right compute instance for consistent disk performance[#](https://supabase.com/docs/guides/platform/compute-and-disk#choosing-the-right-compute-instance-for-consistent-disk-performance) If you need consistent disk performance, choose the 4XL or larger compute instance. If you're unsure of how much throughput or IOPS your application requires, you can load test your project and inspect these [metrics in the Dashboard](https://supabase.com/dashboard/project/_/observability) . If the `Disk IO % consumed` stat is more than 1%, it indicates that your workload has exceeded the baseline IO throughput during the day. If this metric goes to 100%, the workload has used up all available disk IO budget. Projects that use any disk IO budget are good candidates for upgrading to a larger compute instance with higher throughput. ### Provisioned disk throughput and IOPS[#](https://supabase.com/docs/guides/platform/compute-and-disk#provisioned-disk-throughput-and-iops) The default disk type is gp3, which comes with a baseline throughput of 125 MB/s and a default IOPS of 3,000. You can provision additional IOPS and throughput from the [Database Settings](https://supabase.com/dashboard/project/_/settings/compute-and-disk) page, but keep in mind that the effective IOPS and throughput will be limited by the compute instance size. This requires Large compute size or above. Be aware that increasing IOPS or throughput incurs additional charges. ### Disk types[#](https://supabase.com/docs/guides/platform/compute-and-disk#disk-types) When selecting your disk, it's essential to focus on the performance needs of your workload. Here's a comparison of our available disk types: | | General Purpose SSD (gp3) | High Performance SSD (io2) | | --- | --- | --- | | **Use Case** | General workloads, development environments, small to medium databases | High-performance needs, large-scale databases, mission-critical applications | | **Max Disk Size** | 16 TB | 60 TB | | **Max IOPS** | 16,000 IOPS (at 32 GB disk size) | 80,000 IOPS (at 80 GB disk size) | | **Throughput** | 125 MB/s (default) to 1,000 MB/s (maximum) | Automatically scales with IOPS | | **Best For** | Great value for most use cases | Low latency and very high IOPS requirements | | **Pricing** | Disk: 8 GB included, then $0.125 per GB
IOPS: 3,000 included, then $0.024 per IOPS
Throughput: 125 MB/s included, then $0.95 per MB/s | Disk: $0.195 per GB
IOPS: $0.119 per IOPS
Throughput: Scales with IOPS at no additional cost | For general, day-to-day operations, gp3 should be more than enough. If you need high throughput and IOPS for critical systems, io2 will provide the performance required. Compute instance size changes will not change your selected disk type or disk size, but your IO limits may change according to what your selected compute instance size supports. ### Disk size[#](https://supabase.com/docs/guides/platform/compute-and-disk#disk-size) * General Purpose (gp3) disks come with a baseline of 3,000 IOPS and 125 MB/s. You can provision additional 500 IOPS for every GB of disk size and additional 0.25 MB/s throughput per provisioned IOPS. * High Performance (io2) disks can be provisioned with 1,000 IOPS per GB of disk size. Limits and constraints[#](https://supabase.com/docs/guides/platform/compute-and-disk#limits-and-constraints) ------------------------------------------------------------------------------------------------------------- ### Postgres replication slots, WAL senders, and connections[#](https://supabase.com/docs/guides/platform/compute-and-disk#postgres-replication-slots-wal-senders-and-connections) [Replication Slots](https://postgresqlco.nf/doc/en/param/max_replication_slots) and [WAL Senders](https://postgresqlco.nf/doc/en/param/max_wal_senders/) are used to enable [Postgres Replication](https://supabase.com/docs/guides/database/replication) . Each compute instance also has limits on the maximum number of database connections and connection pooler clients it can handle. The maximum number of replication slots, WAL senders, database connections, and pooler clients depends on your compute instance size, as follows: | Compute instance | Max Replication Slots | Max WAL Senders | Database Max Connections[3](https://supabase.com/docs/guides/platform/compute-and-disk#user-content-fn-1) | Connection Pooler Max Clients | | --- | --- | --- | --- | --- | | Nano (free) | 5 | 5 | 60 | 200 | | Micro | 5 | 5 | 60 | 200 | | Small | 5 | 5 | 90 | 400 | | Medium | 5 | 5 | 120 | 600 | | Large | 8 | 8 | 160 | 800 | | XL | 24 | 24 | 240 | 1,000 | | 2XL | 80 | 80 | 380 | 1,500 | | 4XL | 80 | 80 | 480 | 3,000 | | 8XL | 80 | 80 | 490 | 6,000 | | 12XL | 80 | 80 | 500 | 9,000 | | 16XL | 80 | 80 | 500 | 12,000 | As mentioned in the Postgres [documentation](https://postgresqlco.nf/doc/en/param/max_replication_slots/) , setting `max_replication_slots` to a lower value than the current number of replication slots will prevent the server from starting. If you are downgrading your compute instance, ensure that you are using fewer slots than the maximum number of replication slots available for the new compute instance. ### Constraints[#](https://supabase.com/docs/guides/platform/compute-and-disk#constraints) * You can modify disk attributes up to **four times** within a rolling 24-hour window. A new modification can be initiated as soon as the previous one completes. If you reach this limit, you will encounter throttling and must wait for the rolling 24-hour window to permit further adjustments. * You can increase disk size but cannot decrease it. Footnotes[#](https://supabase.com/docs/guides/platform/compute-and-disk#footnote-label) ---------------------------------------------------------------------------------------- 1. Database size for each compute instance is the default recommendation but the actual performance of your database has many contributing factors, including resources available to it and the size of the data contained within it. See the [shared responsibility model](https://supabase.com/docs/guides/platform/shared-responsibility-model) for more information. [↩](https://supabase.com/docs/guides/platform/compute-and-disk#user-content-fnref-2) 2. Compute resources on the Free plan are subject to change. [↩](https://supabase.com/docs/guides/platform/compute-and-disk#user-content-fnref-3) 3. Database max connections are recommended values and can be [customized via `max_connections`](https://supabase.com/docs/guides/database/custom-postgres-config) depending on your use case. Be aware of [these considerations](https://supabase.com/docs/guides/troubleshooting/how-to-change-max-database-connections-_BQ8P5) before modifying. [↩](https://supabase.com/docs/guides/platform/compute-and-disk#user-content-fnref-1) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/platform/compute-and-disk%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/platform/compute-and-disk%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Identities | Supabase Docs Auth Identities ============== * * * An identity is an authentication method associated with a user. Supabase Auth supports the following types of identity: * Email * Phone * OAuth * SAML A user can have more than one identity. Anonymous users have no identity until they link an identity to their user. The user identity object[#](https://supabase.com/docs/guides/auth/identities#the-user-identity-object) ------------------------------------------------------------------------------------------------------- The user identity object contains the following attributes: | Attributes | Type | Description | | --- | --- | --- | | provider\_id | `string` | The provider id returned by the provider. If the provider is an OAuth provider, the id refers to the user's account with the OAuth provider. If the provider is `email` or `phone`, the id is the user's id from the `auth.users` table. | | user\_id | `string` | The user's id that the identity is linked to. | | identity\_data | `object` | The identity metadata. For OAuth and SAML identities, this contains information about the user from the provider. | | id | `string` | The unique id of the identity. | | provider | `string` | The provider name. | | email | `string` | The email is a generated column that references the optional email property in the identity\_data | | created\_at | `string` | The timestamp that the identity was created. | | last\_sign\_in\_at | `string` | The timestamp that the identity was last used to sign in. | | updated\_at | `string` | The timestamp that the identity was last updated. | ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/auth/identities%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/auth/identities%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # OAuth 2.1 Server | Supabase Docs Auth OAuth 2.1 Server ==================== * * * Supabase Auth can act as an OAuth 2.1 and OpenID Connect (OIDC) identity provider. This allows other applications and services to use your Supabase project as their authentication provider, just like "Sign in with Google" or "Sign in with GitHub". You can use this to build "Sign in with \[Your App\]" experiences, authenticate AI agents through the Model Context Protocol (MCP), power developer platforms with third-party integrations, or implement standards-compliant enterprise SSO. Use cases[#](https://supabase.com/docs/guides/auth/oauth-server#use-cases) --------------------------------------------------------------------------- There are several reasons why you might want to enable OAuth 2.1 Server in your Supabase project: * **Developer platforms and marketplaces**: Allow third-party developers to build integrations and apps for your platform. Partners can offer "Sign in with \[Your App\]" to their users, with your control over data access through Row Level Security policies. * **AI agents and automation**: Authenticate AI agents, LLM tools, and MCP servers that need to access user data. The Model Context Protocol provides automatic OAuth discovery and client registration for AI applications. * **Mobile and desktop apps**: Issue OAuth tokens to your own mobile apps, desktop applications, or other first-party clients. All tokens respect your existing Row Level Security policies and work with Custom Access Token Hooks. * **Enterprise SSO**: Provide OpenID Connect (OIDC) authentication for enterprise customers who need standards-compliant identity federation across multiple services. Overview[#](https://supabase.com/docs/guides/auth/oauth-server#overview) ------------------------------------------------------------------------- Supabase Auth implements the OAuth 2.1 authorization code flow with PKCE (Proof Key for Code Exchange). When a third-party application wants to access user data: 1. The application redirects the user to your authorization endpoint 2. Supabase Auth validates the request and redirects to your custom authorization UI 3. The user authenticates (using any of your enabled auth methods) and approves access 4. Supabase Auth issues an authorization code 5. The application exchanges the code for access and refresh tokens 6. The application uses the access token to make authenticated API requests Access tokens are standard Supabase JWTs that include `user_id`, `role`, and `client_id` claims. Your existing Row Level Security policies automatically apply to OAuth tokens, giving you fine-grained control over what each client can access. ### Supported standards[#](https://supabase.com/docs/guides/auth/oauth-server#supported-standards) * **OAuth 2.1**: Latest OAuth specification with mandatory PKCE * **OpenID Connect**: ID tokens (with `openid` scope), UserInfo endpoint, and OIDC discovery * **Standard scopes**: `openid`, `email`, `profile`, and `phone` scopes for controlling data access * **Dynamic client registration**: Automatic registration for MCP-compatible clients * **JWKS endpoint**: Public keys for third parties to validate tokens ### Integration with existing auth[#](https://supabase.com/docs/guides/auth/oauth-server#integration-with-existing-auth) OAuth 2.1 Server works seamlessly with your existing Supabase Auth configuration: * Users can authenticate using any enabled method (password, magic link, social providers, MFA, phone) * [Custom Access Token Hooks](https://supabase.com/guides/auth/auth-hooks/access-token-hook) apply to OAuth tokens, allowing you to customize claims like `audience` or add client-specific permissions * Row Level Security policies control data access using the `client_id` claim in tokens * All standard Supabase features (email templates, hooks, rate limiting) continue to work Set up OAuth 2.1 server[#](https://supabase.com/docs/guides/auth/oauth-server#set-up-oauth-21-server) ------------------------------------------------------------------------------------------------------ To enable OAuth 2.1 Server in your project, follow these guides: [Getting Started\ \ Enable OAuth 2.1, configure your authorization endpoint, and register your first client.](https://supabase.com/docs/guides/auth/oauth-server/getting-started) [OAuth Flows\ \ Detailed walkthrough of authorization code and refresh token flows.](https://supabase.com/docs/guides/auth/oauth-server/oauth-flows) [MCP Authentication\ \ Authenticate AI agents and LLM tools using Model Context Protocol.](https://supabase.com/docs/guides/auth/oauth-server/mcp-authentication) [Token Security & RLS\ \ Control data access with Row Level Security policies for OAuth clients.](https://supabase.com/docs/guides/auth/oauth-server/token-security) Resources[#](https://supabase.com/docs/guides/auth/oauth-server#resources) --------------------------------------------------------------------------- * [GitHub Discussion](https://github.com/orgs/supabase/discussions/38022) - Share your use cases and help shape the roadmap * [Discord Community](https://discord.supabase.com/) - Get help and share what you're building ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/auth/oauth-server%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/auth/oauth-server%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Building ChatGPT plugins | Supabase Docs AI & Vectors Building ChatGPT plugins ============================ Use Supabase as a Retrieval Store for your ChatGPT plugin. -------------------------------------------------------------- * * * ChatGPT recently released [Plugins](https://openai.com/blog/chatgpt-plugins) which help ChatGPT access up-to-date information, run computations, or use third-party services. If you're building a plugin for ChatGPT, you'll probably want to answer questions from a specific source. We can solve this with “retrieval plugins”, which allow ChatGPT to access information from a database. What is ChatGPT Retrieval Plugin?[#](https://supabase.com/docs/guides/ai/examples/building-chatgpt-plugins#what-is-chatgpt-retrieval-plugin) --------------------------------------------------------------------------------------------------------------------------------------------- A [Retrieval Plugin](https://github.com/openai/chatgpt-retrieval-plugin) is a Python project designed to inject external data into a ChatGPT conversation. It does a few things: 1. Turn documents into smaller chunks. 2. Converts chunks into embeddings using OpenAI's `text-embedding-ada-002` model. 3. Stores the embeddings into a vector database. 4. Queries the vector database for relevant documents when a question is asked. It allows ChatGPT to dynamically pull relevant information into conversations from your data sources. This could be PDF documents, Confluence, or Notion knowledge bases. Example: Chat with Postgres docs[#](https://supabase.com/docs/guides/ai/examples/building-chatgpt-plugins#example-chat-with-postgres-docs) ------------------------------------------------------------------------------------------------------------------------------------------- Let’s build an example where we can “ask ChatGPT questions” about the Postgres documentation. Although ChatGPT already knows about the Postgres documentation because it is publicly available, this is a simple example which demonstrates how to work with PDF files. This plugin requires several steps: 1. Download all the [Postgres docs as a PDF](https://www.postgresql.org/files/documentation/pdf/15/postgresql-15-US.pdf) 2. Convert the docs into chunks of embedded text and store them in Supabase 3. Run our plugin locally so that we can ask questions about the Postgres docs. We'll be saving the Postgres documentation in Postgres, and ChatGPT will be retrieving the documentation whenever a user asks a question: ![diagram reference](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fai%2Fchatgpt-plugins%2Fchatgpt-plugin-scheme--light.png&w=3840&q=75) ### Step 1: Fork the ChatGPT Retrieval Plugin repository[#](https://supabase.com/docs/guides/ai/examples/building-chatgpt-plugins#step-1-fork-the-chatgpt-retrieval-plugin-repository) Fork the ChatGPT Retrieval Plugin repository to your GitHub account and clone it to your local machine. Read through the `README.md` file to understand the project structure. ### Step 2: Install dependencies[#](https://supabase.com/docs/guides/ai/examples/building-chatgpt-plugins#step-2-install-dependencies) Choose your desired datastore provider and remove unused dependencies from `pyproject.toml`. For this example, we'll use Supabase. And install dependencies with Poetry: 1poetry install ### Step 3: Create a Supabase project[#](https://supabase.com/docs/guides/ai/examples/building-chatgpt-plugins#step-3-create-a-supabase-project) Create a [Supabase project](https://supabase.com/dashboard) and database by following the instructions [here](https://supabase.com/docs/guides/platform) . Export the environment variables required for the retrieval plugin to work: 1export OPENAI_API_KEY=2export DATASTORE=supabase3export SUPABASE_URL=4export SUPABASE_SERVICE_ROLE_KEY= For Postgres datastore, you'll need to export these environment variables instead: 1export OPENAI_API_KEY=2export DATASTORE=postgres3export PG_HOST=4export PG_PASSWORD= ### Step 4: Run Postgres locally[#](https://supabase.com/docs/guides/ai/examples/building-chatgpt-plugins#step-4-run-postgres-locally) To start quicker you may use Supabase CLI to spin everything up locally as it already includes pgvector from the start. Install `supabase-cli`, go to the `examples/providers` folder in the repo and run: 1supabase start This will pull all docker images and run Supabase stack in docker on your local machine. It will also apply all the necessary migrations to set the whole thing up. You can then use your local setup the same way, just export the environment variables and follow to the next steps. Using `supabase-cli` is not required and you can use any other docker image or hosted version of Postgres that includes `pgvector`. Just make sure you run migrations from `examples/providers/supabase/migrations/20230414142107_init_pg_vector.sql`. ### Step 5: Obtain OpenAI API key[#](https://supabase.com/docs/guides/ai/examples/building-chatgpt-plugins#step-5-obtain-openai-api-key) To create embeddings Plugin uses OpenAI API and `text-embedding-ada-002` model. Each time we add some data to our datastore, or try to query relevant information from it, embedding will be created either for inserted data chunk, or for the query itself. To make it work we need to export `OPENAI_API_KEY`. If you already have an account in OpenAI, you just need to go to [User Settings - API keys](https://platform.openai.com/account/api-keys) and Create new secret key. ![OpenAI Secret Keys](https://supabase.com/docs/img/ai/chatgpt-plugins/openai-secret-keys.png) ### Step 6: Run the plugin[#](https://supabase.com/docs/guides/ai/examples/building-chatgpt-plugins#step-6-run-the-plugin) Execute the following command to run the plugin: 1poetry run dev2# output3INFO: Will watch for changes in these directories: ['./chatgpt-retrieval-plugin']4INFO: Uvicorn running on http://localhost:3333 (Press CTRL+C to quit)5INFO: Started reloader process [87843] using WatchFiles6INFO: Started server process [87849]7INFO: Waiting for application startup.8INFO: Application startup complete. The plugin will start on your localhost - port `:3333` by default. ### Step 6: Populating data in the datastore[#](https://supabase.com/docs/guides/ai/examples/building-chatgpt-plugins#step-6-populating-data-in-the-datastore) For this example, we'll upload Postgres documentation to the datastore. Download the [Postgres documentation](https://www.postgresql.org/files/documentation/pdf/15/postgresql-15-US.pdf) and use the `/upsert-file` endpoint to upload it: 1curl -X POST -F \\"file=@./postgresql-15-US.pdf\\" The plugin will split your data and documents into smaller chunks automatically. You can view the chunks using the Supabase dashboard or any other SQL client you prefer. The entire Postgres Documentation yielded 7,904 records, which is not a lot, but we can try to add index for `embedding` column to speed things up by a little. To do so, you should run the following SQL command: 1create index on documents2using hnsw (embedding vector_ip_ops)3with (lists = 10); This will create an index for the inner product distance function. Important to note that it is an approximate index. It will change the logic from performing the exact nearest neighbor search to the approximate nearest neighbor search. We are using `lists = 10`, because as a general guideline, you should start looking for optimal lists constant value with the formula: `rows / 1000` when you have less than 1 million records in your table. ### Step 7: Using our plugin within ChatGPT[#](https://supabase.com/docs/guides/ai/examples/building-chatgpt-plugins#step-7-using-our-plugin-within-chatgpt) To integrate our plugin with ChatGPT, register it in the ChatGPT dashboard. Assuming you have access to ChatGPT Plugins and plugin development, select the Plugins model in a new chat, then choose "Plugin store" and "Develop your own plugin." Enter `localhost:3333` into the domain input, and your plugin is now part of ChatGPT. ![ChatGPT Plugin Store](https://supabase.com/docs/img/ai/chatgpt-plugins/chatgpt-plugin-store.png) ![ChatGPT Local Plugin](https://supabase.com/docs/img/ai/chatgpt-plugins/chatgpt-local-plugin.png) You can now ask questions about Postgres and receive answers derived from the documentation. Let's try it out: ask ChatGPT to find out when to use `check` and when to use `using`. You will be able to see what queries were sent to our plugin and what it responded to. ![Ask ChatGPT](https://supabase.com/docs/img/ai/chatgpt-plugins/ask-chatgpt.png) And after ChatGPT receives a response from the plugin it will answer your question with the data from the documentation. ![ChatGPT Reply](https://supabase.com/docs/img/ai/chatgpt-plugins/chatgpt-reply.png) Resources[#](https://supabase.com/docs/guides/ai/examples/building-chatgpt-plugins#resources) ---------------------------------------------------------------------------------------------- * ChatGPT Retrieval Plugin: [github.com/openai/chatgpt-retrieval-plugin](https://github.com/openai/chatgpt-retrieval-plugin) * ChatGPT Plugins: [official documentation](https://platform.openai.com/docs/plugins/introduction) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/ai/examples/building-chatgpt-plugins%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/ai/examples/building-chatgpt-plugins%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Adding generative Q&A for your documentation | Supabase Docs AI & Vectors Adding generative Q&A for your documentation ================================================ Learn how to build a ChatGPT-style doc search powered using our headless search toolkit. -------------------------------------------------------------------------------------------- * * * Supabase provides a [Headless Search Toolkit](https://github.com/supabase/headless-vector-search) for adding "Generative Q&A" to your documentation. The toolkit is "headless", so that you can integrate it into your existing website and style it to match your website theme. You can see how this works with the Supabase docs. Just hit `cmd+k` and "ask" for something like "what are the features of Supabase?". You will see that the response is streamed back, using the information provided in the docs: ![headless search](https://supabase.com/docs/img/ai/headless-search/headless.png) Tech stack[#](https://supabase.com/docs/guides/ai/examples/headless-vector-search#tech-stack) ---------------------------------------------------------------------------------------------- * Supabase: Database & Edge Functions. * OpenAI: Embeddings and completions. * GitHub Actions: for ingesting your markdown docs. Toolkit[#](https://supabase.com/docs/guides/ai/examples/headless-vector-search#toolkit) ---------------------------------------------------------------------------------------- This toolkit consists of 2 parts: * The [Headless Vector Search](https://github.com/supabase/headless-vector-search) template which you can deploy in your own organization. * A [GitHub Action](https://github.com/supabase/embeddings-generator) which will ingest your markdown files, convert them to embeddings, and store them in your database. Usage[#](https://supabase.com/docs/guides/ai/examples/headless-vector-search#usage) ------------------------------------------------------------------------------------ There are 3 steps to build similarity search inside your documentation: 1. Prepare your database. 2. Ingest your documentation. 3. Add a search interface. ### Prepare your database[#](https://supabase.com/docs/guides/ai/examples/headless-vector-search#prepare-your-database) To prepare, create a [new Supabase project](https://database.new/) and store the database and API credentials, which you can find in the project [settings](https://supabase.com/dashboard/project/_/settings) . Now we can use the [Headless Vector Search](https://github.com/supabase/headless-vector-search#set-up) instructions to set up the database: 1. Clone the repo to your local machine: `git clone git@github.com:supabase/headless-vector-search.git` 2. Link the repo to your remote project: `supabase link --project-ref XXX` 3. Apply the database migrations: `supabase db push` 4. Set your OpenAI key as a secret: `supabase secrets set OPENAI_API_KEY=sk-xxx` 5. Deploy the Edge Functions: `supabase functions deploy --no-verify-jwt` 6. Expose `docs` schema via API in Supabase Dashboard [settings](https://supabase.com/dashboard/project/_/settings/api) > `API Settings` > `Exposed schemas` ### Ingest your documentation[#](https://supabase.com/docs/guides/ai/examples/headless-vector-search#ingest-your-documentation) Now we need to push your documentation into the database as embeddings. You can do this manually, but to make it easier we've created a [GitHub Action](https://github.com/marketplace/actions/supabase-embeddings-generator) which can update your database every time there is a Pull Request. In your knowledge base repository, create a new action called `.github/workflows/generate_embeddings.yml` with the following content: 1name: 'generate_embeddings'2on: # run on main branch changes3 push:4 branches:5 - main67jobs:8 generate:9 runs-on: ubuntu-latest10 steps:11 - uses: actions/checkout@v312 - uses: supabase/embeddings-generator@v0.0.x # Update this to the latest version.13 with:14 supabase-url: 'https://your-project-ref.supabase.co' # Update this to your project URL.15 supabase-service-role-key: ${{ secrets.SUPABASE_SERVICE_ROLE_KEY }}16 openai-key: ${{ secrets.OPENAI_API_KEY }}17 docs-root-path: 'docs' # the path to the root of your md(x) files Make sure to choose the latest version, and set your `SUPABASE_SERVICE_ROLE_KEY` and `OPENAI_API_KEY` as repository secrets in your repo settings (settings > secrets > actions). ### Add a search interface[#](https://supabase.com/docs/guides/ai/examples/headless-vector-search#add-a-search-interface) Now inside your docs, you need to create a search interface. Because this is a headless interface, you can use it with any language. The only requirement is that you send the user query to the `query` Edge Function, which will stream an answer back from OpenAI. It might look something like this: 1const onSubmit = (e: Event) => {2 e.preventDefault()3 answer.value = ""4 isLoading.value = true56 const query = new URLSearchParams({ query: inputRef.current!.value })7 const projectUrl = `https://your-project-ref.supabase.co/functions/v1`8 const queryURL = `${projectURL}/${query}`9 const eventSource = new EventSource(queryURL)1011 eventSource.addEventListener("error", (err) => {12 isLoading.value = false13 console.error(err)14 })1516 eventSource.addEventListener("message", (e: MessageEvent) => {17 isLoading.value = false1819 if (e.data === "[DONE]") {20 eventSource.close()21 return22 }2324 const completionResponse: CreateCompletionResponse = JSON.parse(e.data)25 const text = completionResponse.choices[0].text2627 answer.value += text28 });2930 isLoading.value = true31} Resources[#](https://supabase.com/docs/guides/ai/examples/headless-vector-search#resources) -------------------------------------------------------------------------------------------- * Read about how we built [ChatGPT for the Supabase Docs](https://supabase.com/blog/chatgpt-supabase-docs) . * Read the pgvector Docs for [Embeddings and vector similarity](https://supabase.com/docs/guides/database/extensions/pgvector) * See how to build something like this from scratch [using Next.js](https://supabase.com/docs/guides/ai/examples/nextjs-vector-search) . ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/ai/examples/headless-vector-search%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/ai/examples/headless-vector-search%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # New API Keys and Asymmetric Authentication | Supabase Docs Self-Hosting New API Keys and Asymmetric Authentication ============================================== Configure new API keys and ES256 asymmetric authentication for self-hosted Supabase. ---------------------------------------------------------------------------------------- * * * You can configure self-hosted Supabase to use the [new API keys](https://supabase.com/docs/guides/api/api-keys) alongside the legacy API keys (`ANON_KEY` and `SERVICE_ROLE_KEY` HS256-signed JWTs). Before you begin[#](https://supabase.com/docs/guides/self-hosting/self-hosted-auth-keys#before-you-begin) ---------------------------------------------------------------------------------------------------------- * Complete the [Docker setup guide](https://supabase.com/docs/guides/self-hosting/docker) , including running `generate-keys.sh` so that `JWT_SECRET`, `ANON_KEY`, and `SERVICE_ROLE_KEY` are set in your `.env` file. * Ensure `openssl` and `node` version 16 or newer are available on the machine where you will generate new keys. * If you are upgrading an existing self-hosted Supabase environment, make sure to check the [changelog](https://github.com/supabase/supabase/blob/master/docker/CHANGELOG.md) and add/update the following files: * `.env.example` (merge new sections into your `.env` file) * `docker-compose.yml` * `utils/add-new-auth-keys.sh` * `utils/rotate-new-api-keys.sh` * `volumes/api/kong-entrypoint.sh` * `volumes/api/kong.yml` Adding the new keys[#](https://supabase.com/docs/guides/self-hosting/self-hosted-auth-keys#adding-the-new-keys) ---------------------------------------------------------------------------------------------------------------- From your project directory where you have `docker-compose.yml`: 1sh utils/add-new-auth-keys.sh --update-env This generates new configuration environment variables and writes them to `.env`. Without `--update-env`, the script prints the values and prompts you interactively. The script reads `JWT_SECRET` from `.env` and includes it as a symmetric key inside both `JWT_KEYS` and `JWT_JWKS`. If you later change `JWT_SECRET`, you must regenerate the JWKS as well. After updating `.env`, enable new authentication by uncommenting these lines in `docker-compose.yml`: 1auth:2 environment:3 # JSON array of signing JWKs (EC private + legacy symmetric)4 GOTRUE_JWT_KEYS: ${JWT_KEYS:-[]}56realtime:7 environment:8 # JWKS for token verification (EC public + legacy symmetric)9 API_JWT_JWKS: ${JWT_JWKS:-{"keys":[]}}1011storage:12 environment:13 # JWKS for token verification (EC public + legacy symmetric)14 JWT_JWKS: ${JWT_JWKS:-{"keys":[]}} PostgREST does not need uncommenting - it already uses `PGRST_JWT_SECRET: ${JWT_JWKS:-${JWT_SECRET}}` which automatically picks up `JWT_JWKS` when set. Then restart all services: 1docker compose down && docker compose up -d ### New API keys format[#](https://supabase.com/docs/guides/self-hosting/self-hosted-auth-keys#new-api-keys-format) The new API keys use the [same format](https://supabase.com/docs/guides/api/api-keys) as the Supabase platform: 1sb_publishable_<22-char-random>_<8-char-checksum>2sb_secret_<22-char-random>_<8-char-checksum> ### Verifying the setup[#](https://supabase.com/docs/guides/self-hosting/self-hosted-auth-keys#verifying-the-setup) Test with the new publishable key: 1curl http:///rest/v1/ \2-H "apikey: your-supabase-publishable-key" You should receive a valid response from PostgREST. Then verify that the legacy key still works: 1curl http:///rest/v1/ \2-H "apikey: your-anon-key" Both should work and return the same result. You can also verify the public JWKS endpoint: 1curl http:///auth/v1/.well-known/jwks.json This should return the EC public key (the symmetric key is excluded). Third-party services can use this endpoint to obtain the public key and verify asymmetric user session JWTs without needing the private key. ### Environment variables configuration[#](https://supabase.com/docs/guides/self-hosting/self-hosted-auth-keys#environment-variables-configuration) New variables default to empty values in `.env.example`. When empty, the API gateway and all services operate in legacy-only mode: `sb_publishable` and `sb_secret` API keys are not configured. | Environment variable (existing and new) | Type | Description | | --- | --- | --- | | `JWT_SECRET` | Symmetric secret | **Existing:** Shared secret for signing and verifying HS256 JWTs. Used by multiple services. | | `ANON_KEY` | HS256 JWT | **Existing:** Legacy client-side API key. Embedded JWT with `role: "anon"`. | | `SERVICE_ROLE_KEY` | HS256 JWT | **Existing:** Legacy server-side API key. Embedded JWT with `role: "service_role"`. | | `SUPABASE_PUBLISHABLE_KEY` | Opaque | **New:** Short random key with checksum. Replaces `ANON_KEY` for **client-side** use. | | `SUPABASE_SECRET_KEY` | Opaque | **New:** Short random key with checksum. Replaces `SERVICE_ROLE_KEY` for **server-side** use. | | `JWT_KEYS` | JSON array | **New:** JSON array of signing JWKs containing the new asymmetric key pair and the legacy symmetric key. Used by Auth to sign tokens. | | `JWT_JWKS` | JWKS (JSON) | **New:** Contains the new public key and the legacy symmetric key. Used by PostgREST, Realtime, and Storage to verify tokens. | ### Differences from the Supabase platform[#](https://supabase.com/docs/guides/self-hosting/self-hosted-auth-keys#differences-from-the-supabase-platform) * **One key per role.** Self-hosted Supabase supports a single `sb_publishable` and a single `sb_secret`. The platform allows creating multiple `sb_` keys per project. * **No checksum validation.** The opaque keys use the same format as the platform (`sb_publishable__`), but the API gateway does not validate the checksum. Keys are matched as opaque strings by the API gateway. ### Backward compatibility[#](https://supabase.com/docs/guides/self-hosting/self-hosted-auth-keys#backward-compatibility) The new authentication configuration is fully backward compatible: * **All new variables are optional.** If left with empty values, the API gateway (Kong) and all services behave exactly as before. * **Kong accepts both key types simultaneously.** You can migrate clients incrementally - some using legacy API keys, others using the new ones. * **JWKS includes the symmetric key.** `JWT_JWKS` contains both the EC public key (for verifying new ES256 tokens) and the legacy `JWT_SECRET` as a symmetric JWK (for verifying old HS256 tokens). Services that receive `JWT_JWKS` can verify both token types. * **Services fall back gracefully.** PostgREST uses `${JWT_JWKS:-${JWT_SECRET}}` - if `JWT_JWKS` is empty, it uses `JWT_SECRET` directly. * **No database changes required.** The asymmetric key system operates entirely at the API gateway and service configuration layer. When `JWT_KEYS` is set, Auth will start signing new user session JWTs with the new asymmetric ES256 key pair. Make sure all services that verify tokens (PostgREST, Realtime, Storage) are configured with `JWT_JWKS` so they can verify both the new ES256 and legacy HS256 tokens. Rotating the new API keys[#](https://supabase.com/docs/guides/self-hosting/self-hosted-auth-keys#rotating-the-new-api-keys) ---------------------------------------------------------------------------------------------------------------------------- If your new API keys are compromised or you want to rotate them periodically, you can regenerate `sb_publishable` and `sb_secret` without touching the asymmetric key pair: 1sh utils/rotate-new-api-keys.sh --update-env After rotating, restart services and update your client applications with the new keys: 1docker compose down && docker compose up -d Rotating new API keys does not invalidate existing user sessions. User session JWTs issued by Auth are unaffected because they are verified using the asymmetric key pair, which remains unchanged. Regenerating asymmetric key pair[#](https://supabase.com/docs/guides/self-hosting/self-hosted-auth-keys#regenerating-asymmetric-key-pair) ------------------------------------------------------------------------------------------------------------------------------------------ If the EC private key is compromised or you need to regenerate everything: 1sh utils/add-new-auth-keys.sh --update-env This generates a new EC P-256 key pair, new JWKS, new asymmetric JWTs, and new `sb_` API keys. After updating `.env` and restarting services: * New user session tokens will be signed with the new EC key. * Existing user session tokens signed with the old EC key will fail verification. Users will need to sign in again. * Existing user session tokens signed with the legacy symmetric key (`JWT_SECRET`) will continue to work, since `JWT_SECRET` hasn't changed and is still included in the new JWKS. Regenerating asymmetric keys invalidates all ES256 user sessions. Plan a maintenance window if your users have active sessions. How it works[#](https://supabase.com/docs/guides/self-hosting/self-hosted-auth-keys#how-it-works) -------------------------------------------------------------------------------------------------- Below are a few notes on the details of the new authentication architecture. ### What client SDK sends[#](https://supabase.com/docs/guides/self-hosting/self-hosted-auth-keys#what-client-sdk-sends) Every request via `supabase-js` includes two headers: * `apikey` - the API key (`sb_` or legacy JWT) * `Authorization` - when unauthenticated, the client SDK copies the API key here (`Bearer sb_publishable_xxx` or `Bearer eyJ...`). When authenticated, this contains the user session JWT minted by Auth. For **Realtime WebSocket** connections, the API key is sent as a `?apikey=` query parameter in the upgrade URL instead of an `apikey` header. **Storage** and **Edge Functions** accept requests without an API key. These services handle their own authentication. ### API gateway routing[#](https://supabase.com/docs/guides/self-hosting/self-hosted-auth-keys#api-gateway-routing) Kong is configured with two consumers that each accept both the legacy and new API keys: 1consumers:2 - username: anon3 keyauth_credentials:4 - key: $SUPABASE_ANON_KEY # legacy HS256 JWT (ANON_KEY)5 - key: $SUPABASE_PUBLISHABLE_KEY # new opaque key (omitted when not configured)6 - username: service_role7 keyauth_credentials:8 - key: $SUPABASE_SERVICE_KEY # legacy HS256 JWT (SERVICE_ROLE_KEY)9 - key: $SUPABASE_SECRET_KEY # new opaque key (omitted when not configured) When new API keys have not been added yet, the `kong-entrypoint.sh` script removes the empty credential entries before Kong loads the config. To assist with the authorization flows a specialized configuration in `kong.yml` substitutes internal, gateway-level-only pre-signed JWTs for `sb_publishable` and `sb_secret` API keys. These pre-signed JWTs are also auto-configured in `.env` but **should not** be used in any application code. | Route | Service | API key required | Header substitution | | --- | --- | --- | --- | | `/auth/v1/*` | Auth | Yes | `Authorization` | | `/rest/v1/*` | PostgREST | Yes | `Authorization` | | `/graphql/v1` | PostgREST | Yes | `Authorization` | | `/realtime/v1/api/*` | Realtime (REST) | Yes | `Authorization` | | `/realtime/v1/*` | Realtime (WebSocket) | Yes | `x-api-key` | | `/storage/v1/*` | Storage | No | `Authorization` | | `/functions/v1/*` | Edge Functions | No | \- | ### Request flows[#](https://supabase.com/docs/guides/self-hosting/self-hosted-auth-keys#request-flows) The API gateway (Kong) configuration has the logic to decide what `Authorization` header the upstream service, such as Auth, receives. The logic handles two cases: requests that only carry an API key (no user session), and requests that carry a user session JWT. #### Unauthenticated requests (API key only, no user session JWT)[#](https://supabase.com/docs/guides/self-hosting/self-hosted-auth-keys#unauthenticated-requests-api-key-only-no-user-session-jwt) When the client sends only an `apikey` header with the API key (no `Authorization` header), or also the API key duplicated in `Authorization` by `supabase-js`: 1. The client sends `apikey: sb_publishable_xxx` (or legacy `apikey: eyJ...`). 2. The API gateway checks the key and identifies the consumer (`anon` or `service_role`). 3. The API gateway inspects the `Authorization` header. Since it is either absent or starts with `Bearer sb_` (an opaque key, not a session JWT), the plugin replaces it: * **The new `sb_` key:** `Authorization` header is set to the internal pre-signed ES256 JWT that corresponds to the role. * **The Legacy JWT key:** `Authorization` header is set to the legacy HS256 JWT (the `apikey` value is copied as-is). 4. The upstream service receives a valid JWT in `Authorization` and verifies it using `JWT_JWKS` (or `JWT_SECRET`). #### Authenticated requests (user session JWT)[#](https://supabase.com/docs/guides/self-hosting/self-hosted-auth-keys#authenticated-requests-user-session-jwt) When the client has previously signed in through Auth and has a valid user session JWT token: 1. The client sends `Authorization: Bearer eyJ...` (a JWT session token from Auth) alongside `apikey: sb_publishable_xxx` (or legacy `apikey: eyJ...`). 2. The API gateway checks the API key and identifies the consumer. 3. The API gateway inspects the `Authorization` header. Since it exists and does **not** start with `Bearer sb_` (it's a real JWT, not an `sb_` API key), the plugin **passes it through unchanged**. This works the same way regardless of whether the `apikey` is a new `sb_` key or a legacy JWT - the gateway only looks at the `Authorization` header to decide whether a user session is present. 4. The upstream service verifies the session JWT. If Auth signed it with ES256 (when `JWT_KEYS` is configured), verification uses the EC public key. If Auth signed it with HS256 (legacy), verification uses the symmetric key. Both keys are available in `JWT_JWKS`. The `request-transformer` expression in `kong.yml` implements this as a single Lua conditional: 1-- Pseudocode for the Authorization header logic:2if authorization exists AND does not start with "Bearer sb_" then3 -- User session JWT: pass through unchanged4 keep authorization5elseif apikey matches secret key then6 -- Replace with pre-signed service_role ES256 JWT7 set authorization = "Bearer "8elseif apikey matches publishable key then9 -- Replace with pre-signed anon ES256 JWT10 set authorization = "Bearer "11else12 -- Legacy JWT key: copy apikey as authorization13 set authorization = apikey14end Additional resources[#](https://supabase.com/docs/guides/self-hosting/self-hosted-auth-keys#additional-resources) ------------------------------------------------------------------------------------------------------------------ * [Understanding API keys](https://supabase.com/docs/guides/api/api-keys) - How API keys work on the Supabase platform * [Auth architecture](https://supabase.com/docs/guides/auth/architecture) - How the Auth service handles authentication and token signing * [JWT Signing Keys](https://supabase.com/docs/guides/auth/signing-keys) - Best practices on managing keys used by Supabase Auth to create and verify JSON Web Tokens * [JSON Web Token (JWT)](https://supabase.com/docs/guides/auth/jwts) - How to best use JSON Web Tokens with Supabase * [Self-hosting with Docker](https://supabase.com/docs/guides/self-hosting/docker) - Initial setup guide, including legacy key generation On GitHub: * [Upcoming changes to Supabase API Keys (Discussion #29260)](https://github.com/orgs/supabase/discussions/29260) * [Supabase Auth: Asymmetric Keys support (Discussion #29289)](https://github.com/orgs/supabase/discussions/29289) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/self-hosting/self-hosted-auth-keys%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/self-hosting/self-hosted-auth-keys%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Custom Domains | Supabase Docs Platform Custom Domains ================== * * * Custom domains allow you to present a branded experience to your users. These are available as a [paid add-on for projects on a paid plan](https://supabase.com/dashboard/project/_/settings/addons?panel=customDomain) . There are two types of domains supported by Supabase: 1. Custom domains, where you use a domain such as `api.example.com` instead of the project's default domain. 2. Vanity subdomains (experimental), where you can set up a different subdomain on `supabase.co` for your project. You can choose either a custom domain or vanity subdomain for each project. Custom domains[#](https://supabase.com/docs/guides/platform/custom-domains#custom-domains) ------------------------------------------------------------------------------------------- Custom domains change the way your project's URLs appear to your users. This is useful when: * You are using [OAuth (Social Login)](https://supabase.com/docs/guides/auth/social-login) with Supabase Auth and the project's URL is shown on the OAuth consent screen. * You are creating APIs for third-party systems, for example, implementing webhooks or external API calls to your project via [Edge Functions](https://supabase.com/docs/guides/functions) . * You are storing URLs in a database or encoding them in QR codes. Custom domains help you keep your APIs portable for the long term. By using a custom domain you can migrate from one Supabase project to another, or make it easier to version APIs in the future. ### Limitations[#](https://supabase.com/docs/guides/platform/custom-domains#limitations) * Custom domains are not intended to enable hosting of frontend applications through [Edge Functions](https://supabase.com/docs/guides/functions) . * You can only attach a single custom domain to any given Supabase project. It is not possible to break out your project's resources into multiple custom domains. * Custom domains can only be powered by CNAME records. ### Configure a custom domain using the Supabase dashboard[#](https://supabase.com/docs/guides/platform/custom-domains#configure-a-custom-domain-using-the-supabase-dashboard) Follow the **Custom Domains** steps in the [General Settings](https://supabase.com/dashboard/project/_/settings/general) page in the Dashboard to set up a custom domain for your project. ### Configure a custom domain using the Supabase CLI[#](https://supabase.com/docs/guides/platform/custom-domains#configure-a-custom-domain-using-the-supabase-cli) This example assumes your Supabase project is `abcdefghijklmnopqrst` with a corresponding API URL `abcdefghijklmnopqrst.supabase.co` and configures a custom domain at `api.example.com`. To get started: 1. [Install](https://supabase.com/docs/guides/resources/supabase-cli) the latest version of the Supabase CLI. 2. [Log in](https://supabase.com/docs/guides/cli/local-development#log-in-to-the-supabase-cli) to your Supabase account using the CLI. 3. Ensure you have [Owner or Admin permissions](https://supabase.com/docs/guides/platform/access-control#manage-team-members) for the project. 4. Get a custom domain from a DNS provider. Currently, only subdomains are supported. * Use `api.example.com` instead of `example.com`. ### Add a CNAME record[#](https://supabase.com/docs/guides/platform/custom-domains#add-a-cname-record) You need to add a CNAME record to your domain's DNS settings to ensure your custom domain points to the Supabase project. If your project's default domain is `abcdefghijklmnopqrst.supabase.co` you should: * Create a CNAME record for `api.example.com` that resolves to `abcdefghijklmnopqrst.supabase.co.`. * Use a low TTL value to quickly propagate changes in case you make a mistake. ### Verify ownership of the domain[#](https://supabase.com/docs/guides/platform/custom-domains#verify-ownership-of-the-domain) Register your domain with Supabase to prove that you own it. You need to download two TXT records and add them to your DNS settings. In the CLI, run [`domains create`](https://supabase.com/docs/reference/cli/supabase-domains-create) to register the domain and Supabase and get your verification records: 1supabase domains create --project-ref abcdefghijklmnopqrst --custom-hostname api.example.com A single TXT records is returned. For example: 1[...]2Required outstanding validation records:3 _acme-challenge.api.example.com. TXT -> ca3-F1HvR9i938OgVwpCFwi1jTsbhe1hvT0Ic3efPY3Q Add the record to your domains' DNS settings. Make sure to trim surrounding whitespace. Use a low TTL value so you can quickly change the records if you make a mistake. Some DNS registrars automatically append your domain name to the DNS entries being created. As such, creating a DNS record for `api.example.com` might instead create a record for `api.example.com.example.com`. In such cases, remove the domain name from the records you're creating; as an example, you would create a TXT record for `api`, instead of `api.example.com`. ### Verify your domain[#](https://supabase.com/docs/guides/platform/custom-domains#verify-your-domain) Make sure you've configured all required DNS settings: * CNAME for your custom domain pointing to the Supabase project domain. * TXT record for `_acme-challenge.`. Use the [`domains reverify`](https://supabase.com/docs/reference/cli/supabase-domains-reverify) command to begin the verification process of your domain. You may need to run this command a few times because DNS records take a while to propagate. 1supabase domains reverify --project-ref abcdefghijklmnopqrst In the background, Supabase will check your DNS records and issue an SSL certificate. Supabase uses multiple Certificate Authorities (including Let's Encrypt, Google Trust Services and SSL.com) to ensure high availability. The specific issuer is chosen based on availability and this process can take up to 30 minutes. ### Prepare to activate your domain[#](https://supabase.com/docs/guides/platform/custom-domains#prepare-to-activate-your-domain) Before you activate your domain, prepare your applications and integrations for the domain change: * The project's Supabase domain remains active. * You do not need to change the Supabase URL in your applications immediately. * You can use it interchangeably with the custom domain. * Supabase Auth will use the custom domain immediately once activated. * OAuth flows will advertise the custom domain as a callback URL. * SAML will use the custom domain instead. This means that the `EntityID` of your project has changed, and this may cause SAML with existing identity providers to stop working. To prevent issues for your users, follow these steps: 1. For each of your Supabase OAuth providers: * In the provider's developer console (not in the Supabase dashboard), find the OAuth application and add the custom domain Supabase Auth callback URL **in addition to the Supabase project URL.** Example: * `https://abcdefghijklmnopqrst.supabase.co/auth/v1/callback` **and** * `https://api.example.com/auth/v1/callback` * [Sign in with Twitter](https://supabase.com/docs/guides/auth/social-login/auth-twitter) uses cookies bound to the project's domain. Make sure your frontend code uses the custom domain instead of the default project's domain. 2. For each of your SAML identity providers: * Contact your provider and ask them to update the metadata for the SAML application. They should use `https://api.example.com/auth/v1/...` instead of `https://abcdefghijklmnopqrst.supabase.co/auth/v1/sso/saml/{metadata,acs,slo}`. * Once these changes are made, SAML Single Sign-On will likely stop working until the domain is activated. Plan for this ahead of time. ### Activate your domain[#](https://supabase.com/docs/guides/platform/custom-domains#activate-your-domain) Once you've done the necessary preparations to activate the new domain for your project, you can activate it using the [`domains activate`](https://supabase.com/docs/reference/cli/supabase-domains-activate) CLI command. 1supabase domains activate --project-ref abcdefghijklmnopqrst When this step completes, Supabase will serve the requests from your new domain. The Supabase project domain **continues to work** and serve requests so you do not need to rush to change client code URLs. If you wish to use the new domain in client code, change the URL used in your Supabase client libraries: 1import { createClient } from '@supabase/supabase-js'23// Use a custom domain as the supabase URL4const supabase = createClient('https://api.example.com', 'publishable-or-anon-key') Similarly, your Edge Functions will now be available at `https://api.example.com/functions/v1/your_function_name`, and your Storage objects at `https://api.example.com/storage/v1/object/public/your_file_path.ext`. ### Remove a custom domain[#](https://supabase.com/docs/guides/platform/custom-domains#remove-a-custom-domain) Removing a custom domain may cause some issues when using Supabase Auth with OAuth or SAML. You may have to reverse the changes made in the _[Prepare to activate your domain](https://supabase.com/docs/guides/platform/custom-domains#prepare-to-activate-your-domain) _ step above. To remove an activated custom domain you can use the [`domains delete`](https://supabase.com/docs/reference/cli/supabase-domains-delete) CLI command. 1supabase domains delete --project-ref abcdefghijklmnopqrst Vanity subdomains[#](https://supabase.com/docs/guides/platform/custom-domains#vanity-subdomains) ------------------------------------------------------------------------------------------------- Vanity subdomains allow you to present a basic branded experience, compared to custom domains. They allow you to host your services at a custom subdomain on Supabase (e.g., `my-example-brand.supabase.co`) instead of the default, randomly assigned `abcdefghijklmnopqrst.supabase.co`. To get started: 1. [Install](https://supabase.com/docs/guides/resources/supabase-cli) the latest version of the Supabase CLI. 2. [Log in](https://supabase.com/docs/guides/cli/local-development#log-in-to-the-supabase-cli) to your Supabase account using the CLI. 3. Ensure that you have [Owner or Admin permissions](https://supabase.com/docs/guides/platform/access-control#manage-team-members) for the project you'd like to set up a vanity subdomain for. 4. Ensure that your organization is on a paid plan (Pro/Team/Enterprise Plan) in the [Billing page of the Dashboard](https://supabase.com/dashboard/org/_/billing) . ### Configure a vanity subdomain[#](https://supabase.com/docs/guides/platform/custom-domains#configure-a-vanity-subdomain) You can configure vanity subdomains via the CLI only. Let's assume your Supabase project's domain is `abcdefghijklmnopqrst.supabase.co` and you wish to configure a vanity subdomain at `my-example-brand.supabase.co`. ### Check subdomain availability[#](https://supabase.com/docs/guides/platform/custom-domains#check-subdomain-availability) Use the [`vanity-subdomains check-availability`](https://supabase.com/docs/reference/cli/supabase-vanity-subdomains-check-availability) command of the CLI to check if your desired subdomain is available for use: 1supabase vanity-subdomains --project-ref abcdefghijklmnopqrst check-availability --desired-subdomain my-example-brand --experimental ### Prepare to activate the subdomain[#](https://supabase.com/docs/guides/platform/custom-domains#prepare-to-activate-the-subdomain) Before you activate your vanity subdomain, prepare your applications and integrations for the subdomain change: * The project's Supabase domain remains active and will not go away. * You do not need to change the Supabase URL in your applications immediately or at once. * You can use it interchangeably with the custom domain. * Supabase Auth will use the subdomain immediately once activated. * OAuth flows will advertise the subdomain as a callback URL. * SAML will use the subdomain instead. This means that the `EntityID` of your project has changed, and this may cause SAML with existing identity providers to stop working. To prevent issues for your users, make sure you have gone through these steps: 1. Go through all of your Supabase OAuth providers: * In the provider's developer console (not in the Supabase dashboard!), find the OAuth application and add the subdomain Supabase Auth callback URL **in addition to the Supabase project URL.** Example: * `https://abcdefghijklmnopqrst.supabase.co/auth/v1/callback` **and** * `https://my-example-brand.supabase.co/auth/v1/callback` * [Sign in with Twitter](https://supabase.com/docs/guides/auth/social-login/auth-twitter) uses cookies bound to the project's domain. In this case make sure your frontend code uses the subdomain instead of the default project's domain. 2. Go through all of your SAML identity providers: * You will need to reach out via email to all of your existing identity providers and ask them to update the metadata for the SAML application (your project). Use `https://example-brand.supabase.co/auth/v1/...` instead of `https://abcdefghijklmnopqrst.supabase.co/auth/v1/sso/saml/{metadata,acs,slo}`. * Once these changes are made, SAML Single Sign-On will likely stop working until the domain is activated. Plan for this ahead of time. ### Activate a subdomain[#](https://supabase.com/docs/guides/platform/custom-domains#activate-a-subdomain) Once you've chosen an available subdomain and have done all the necessary preparations for it, you can reconfigure your Supabase project to start using it. Use the [`vanity-subdomains activate`](https://supabase.com/docs/reference/cli/supabase-vanity-subdomains-activate) command to activate and claim your subdomain: 1supabase vanity-subdomains --project-ref abcdefghijklmnopqrst activate --desired-subdomain my-example-brand --experimental If you wish to use the new domain in client code, you can set it up like so: 1import { createClient } from '@supabase/supabase-js'23// Use a custom domain as the supabase URL4const supabase = createClient('https://my-example-brand.supabase.co', 'publishable-or-anon-key') When using [Sign in with Twitter](https://supabase.com/docs/guides/auth/social-login/auth-twitter) make sure your frontend code is using the subdomain only. ### Remove a vanity subdomain[#](https://supabase.com/docs/guides/platform/custom-domains#remove-a-vanity-subdomain) Removing a subdomain may cause some issues when using Supabase Auth with OAuth or SAML. You may have to reverse the changes made in the _[Prepare to activate the subdomain](https://supabase.com/docs/guides/platform/custom-domains#prepare-to-activate-the-subdomain) _ step above. Use the [`vanity-subdomains delete`](https://supabase.com/docs/reference/cli/supabase-vanity-subdomains-delete) command of the CLI to remove the subdomain `my-example-brand.supabase.co` from your project. 1supabase vanity-subdomains delete --project-ref abcdefghijklmnopqrst --experimental Pricing[#](https://supabase.com/docs/guides/platform/custom-domains#pricing) ----------------------------------------------------------------------------- For a detailed breakdown of how charges are calculated, refer to [Manage Custom Domain usage](https://supabase.com/docs/guides/platform/manage-your-usage/custom-domains) . Watch video guide ![Video guide preview](https://supabase.com/docs/_next/image?url=https%3A%2F%2Fimg.youtube.com%2Fvi%2F6rcGnW_Mh-0%2F0.jpg&w=3840&q=75) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/platform/custom-domains%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/platform/custom-domains%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Creating API Routes | Supabase Docs REST API Creating API Routes ======================= * * * API routes are automatically created when you create Postgres Tables, Views, or Functions. Create a table[#](https://supabase.com/docs/guides/api/creating-routes#create-a-table) --------------------------------------------------------------------------------------- Let's create our first API route by creating a table called `todos` to store tasks. This creates a corresponding route `todos` which can accept `GET`, `POST`, `PATCH`, & `DELETE` requests. DashboardSQL 1. Go to the [Table editor](https://supabase.com/dashboard/project/_/editor) page in the Dashboard. 2. Click **New Table** and create a table with the name `todos`. 3. Click **Save**. 4. Click **New Column** and create a column with the name `task` and type `text`. 5. Click **Save**. API URL and keys[#](https://supabase.com/docs/guides/api/creating-routes#api-url-and-keys) ------------------------------------------------------------------------------------------- Every Supabase project has a unique API URL. Your API is secured behind an API gateway which requires an API Key for every request. To do this, you need to get the Project URL and key from [the project's **Connect** dialog](https://supabase.com/dashboard/project/_?showConnect=true) . ##### Changes to API keys Supabase is changing the way keys work to improve project security and developer experience. You can [read the full announcement](https://github.com/orgs/supabase/discussions/29260) , but in the transition period, you can use both the current `anon` and `service_role` keys and the new publishable key with the form `sb_publishable_xxx` which will replace the older keys. In most cases, you can get the correct key from [the Project's **Connect** dialog](https://supabase.com/dashboard/project/_?showConnect=true) , but if you want a specific key, you can find all keys in [the API Keys section of a Project's Settings page](https://supabase.com/dashboard/project/_/settings/api-keys/) : * **For legacy keys**, copy the `anon` key for client-side operations and the `service_role` key for server-side operations from the **Legacy API Keys** tab. * **For new keys**, open the **API Keys** tab, if you don't have a publishable key already, click **Create new API Keys**, and copy the value from the **Publishable key** section. [Read the API keys docs](https://supabase.com/docs/guides/api/api-keys) for a full explanation of all key types and their uses. The REST API is accessible through the URL `https://.supabase.co/rest/v1` Both of these routes require the key to be passed through an `apikey` header. Using the API[#](https://supabase.com/docs/guides/api/creating-routes#using-the-api) ------------------------------------------------------------------------------------- You can interact with your API directly via HTTP requests, or you can use the client libraries which we provide. Let's see how to make a request to the `todos` table which we created in the first step, using the API URL (`SUPABASE_URL`) and Key (`SUPABASE_PUBLISHABLE_KEY`) we provided: JavascriptcURL 1// Initialize the JS client2import { createClient } from '@supabase/supabase-js'3const supabase = createClient(SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY)45// Make a request6const { data: todos, error } = await supabase.from('todos').select('*') JS Reference: [`select()`](https://supabase.com/docs/reference/javascript/select) , [`insert()`](https://supabase.com/docs/reference/javascript/insert) , [`update()`](https://supabase.com/docs/reference/javascript/update) , [`upsert()`](https://supabase.com/docs/reference/javascript/upsert) , [`delete()`](https://supabase.com/docs/reference/javascript/delete) , [`rpc()`](https://supabase.com/docs/reference/javascript/rpc) (call Postgres functions). ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/api/creating-routes%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/api/creating-routes%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Upgrade to Postgres 17 | Supabase Docs Self-Hosting Upgrade to Postgres 17 ========================== Start a new self-hosted Supabase deployment with Postgres 17, or upgrade an existing Postgres 15 installation. ------------------------------------------------------------------------------------------------------------------ * * * Self-hosted Supabase ships with Postgres 15 by default. This guide covers two scenarios: * **New deployment** - start fresh with Postgres 17 (no existing data) * **Upgrade existing deployment** - migrate from Postgres 15 to Postgres 17 using `pg_upgrade` Before you begin[#](https://supabase.com/docs/guides/self-hosting/postgres-upgrade-17#before-you-begin) -------------------------------------------------------------------------------------------------------- * Complete the [Self-Hosting with Docker](https://supabase.com/docs/guides/self-hosting/docker) setup * Your current database image should be `supabase/postgres:15.x` (check with `docker inspect supabase-db --format '{{.Config.Image}}'`) New deployment with Postgres 17[#](https://supabase.com/docs/guides/self-hosting/postgres-upgrade-17#new-deployment-with-postgres-17) -------------------------------------------------------------------------------------------------------------------------------------- If you are starting a new self-hosted Supabase instance with **no existing data**, use the Postgres 17 compose override: 1docker compose -f docker-compose.yml -f docker-compose.pg17.yml up -d This uses the `docker-compose.pg17.yml` override file which swaps the database image: 1services:2 db:3 image: supabase/postgres:17.6.1.084 Always include both compose files when running commands. If you omit the override, Docker Compose falls back to the Postgres 15 image defined in `docker-compose.yml`. The rest of the setup is the same as the standard Docker guide. All init scripts (`roles.sql`, `jwt.sql`, `webhooks.sql`, etc.) are compatible with Postgres 17. If the new Postgres 17 container fails to start, make sure to check for an old `db-config` Docker volume. See [Postgres 17 fails to start with a leftover db-config volume](https://supabase.com/docs/guides/self-hosting/postgres-upgrade-17#postgres-17-fails-to-start-with-a-leftover-db-config-volume) for details. Upgrade an existing Postgres 15 deployment[#](https://supabase.com/docs/guides/self-hosting/postgres-upgrade-17#upgrade-an-existing-postgres-15-deployment) ------------------------------------------------------------------------------------------------------------------------------------------------------------ Upgrading an existing deployment uses `pg_upgrade` to migrate data in place. The included upgrade scripts automates the full process. ### What the upgrade does[#](https://supabase.com/docs/guides/self-hosting/postgres-upgrade-17#what-the-upgrade-does) 1. Pulls a specific Postgres 17 image and extracts upgrade binaries 2. Pulls supplemental upgrade scripts from Supabase's [Postgres](https://github.com/supabase/postgres) repository 3. Stops all self-hosted Supabase containers 4. Runs `pg_upgrade` inside a temporary Postgres 15 container 5. Runs additional tasks inside a temporary Postgres 17 container (re-enables extensions, applies patches, runs `VACUUM ANALYZE`) 6. Swaps data directories (the original is kept as a backup) 7. Starts self-hosted Supabase with Postgres 17 8. Applies additional role migrations (new in Postgres 17) ### Create a backup[#](https://supabase.com/docs/guides/self-hosting/postgres-upgrade-17#create-a-backup) ##### Back up your data before upgrading You should create your own independent backup in case of disk failure or other issues. The upgrade script automatically preserves the pgsodium key and original data directory as `./volumes/db/data.bak.pg15` as the final step. However, it is recommended to **always** create your own independent backup before starting: Back up the database data directory: 1cp -a ./volumes/db/data ./volumes/db/data-manual-backup Back up the pgsodium encryption key (stored in a Docker named volume): 1docker compose run --rm db cat /etc/postgresql-custom/pgsodium_root.key > ./pgsodium_root.key.backup The `db-config` Docker named volume contains the pgsodium root encryption key. If you lose this key and have vault secrets, they become unrecoverable. The `cp -a` above backs up the data directory but NOT the named volume. Optionally, take a logical backup too: 1docker exec supabase-db pg_dumpall -h localhost -U supabase_admin > ./pg15_dump.sql ### Requirements[#](https://supabase.com/docs/guides/self-hosting/postgres-upgrade-17#requirements) * At least **2x your current database size + 5 GB** of free disk space (`pg_upgrade` copies the data directory; the upgrade tarball is ~1.2 GB compressed) * The script prompts for confirmation at each major step (use `--yes` to skip prompts) * All self-hosted Supabase containers must be running before starting the upgrade * Requires `bash` * Must be run as root or using `sudo` ### Extensions removed in Postgres 17[#](https://supabase.com/docs/guides/self-hosting/postgres-upgrade-17#extensions-removed-in-postgres-17) The following extensions are **not available** in Postgres 17 builds. The upgrade script will prompt you to drop them if any of these are found: | Extension | Notes | | --- | --- | | `timescaledb` | Not built for Postgres 17 | | `plv8` | Not built for Postgres 17 | | `plcoffee` | Companion to plv8 | | `plls` | Companion to plv8 | None of the above extensions are installed by default in the self-hosted Supabase setup. If you have installed any of them manually and need to keep them, **do not proceed** with the upgrade. ### Run the upgrade[#](https://supabase.com/docs/guides/self-hosting/postgres-upgrade-17#run-the-upgrade) 1sudo bash utils/upgrade-pg17.sh The script might require your confirmation at some steps (e.g., while checking for disk space, or whether to disable extensions, or remove previous backups). ### After the upgrade[#](https://supabase.com/docs/guides/self-hosting/postgres-upgrade-17#after-the-upgrade) After a successful upgrade, always use both compose files: 1docker compose -f docker-compose.yml -f docker-compose.pg17.yml up -d To verify that Postgres 17 is running: 1docker compose -f docker-compose.yml -f docker-compose.pg17.yml exec db psql -U postgres -c "SELECT version();" The original Postgres 15 data is preserved at `./volumes/db/data.bak.pg15`. The pgsodium root key is saved as `./volumes/db/pgsodium_root.key.bak.pg15`. The upgrade binaries tarball is cached at `./volumes/db/pg17_upgrade_bin_*.tar.gz`. Once you have verified that everything works, you can reclaim disk space: 1rm -rf ./volumes/db/data.bak.pg15 ./volumes/db/pgsodium_root.key.bak.pg15 ./volumes/db/pg17_upgrade_bin_*.tar.gz Do not delete `data.bak.pg15` until you have verified the upgrade. Rollback is only possible while the backup exists. ### Rollback[#](https://supabase.com/docs/guides/self-hosting/postgres-upgrade-17#rollback) If you need to revert to Postgres 15 (run the following commands as root): 1docker compose -f docker-compose.yml -f docker-compose.pg17.yml down && \2rm -rf ./volumes/db/data && \3mv ./volumes/db/data.bak.pg15 ./volumes/db/data && \4docker compose run --rm db chown -R postgres:postgres /etc/postgresql-custom/ && \5docker compose up -d This restores the original data directory, fixes file ownership on the `db-config` volume (Supabase's Postgres 15 and 17 images use different user IDs), and starts with the old Postgres 15 image. ### Custom Postgres configuration[#](https://supabase.com/docs/guides/self-hosting/postgres-upgrade-17#custom-postgres-configuration) The Postgres 17 image loads any `.conf` files from `/etc/postgresql-custom/conf.d/` on startup. This directory is on the `db-config` named volume, so changes persist across restarts. This is a Supabase Postgres 17 image feature. The Postgres 15 image does not load files from `conf.d/`. To add custom Postgres settings, create a `.conf` file in the volume. Since `conf.d/` is on a Docker named volume (not a bind mount), you need to write through the container: 1docker exec supabase-db bash -c 'cat > /etc/postgresql-custom/conf.d/custom.conf << EOF2max_connections = 2003EOF' Restart to apply (`max_connections` requires a full restart): 1docker compose -f docker-compose.yml -f docker-compose.pg17.yml restart db Verify the new settings: 1docker compose -f docker-compose.yml -f docker-compose.pg17.yml exec db psql -U postgres -c "SHOW max_connections;" ### Upgrade process details[#](https://supabase.com/docs/guides/self-hosting/postgres-upgrade-17#upgrade-process-details) The upgrade script delegates the core migration work to two scripts from the [supabase/postgres](https://github.com/supabase/postgres) repository (`ansible/files/admin_api_scripts/pg_upgrade_scripts/`). **Phase 1 - Migrate data (Postgres 15 container):** 1. Disables extensions that are incompatible with `pg_upgrade` (`pg_graphql`, `pg_stat_monitor`, `pg_backtrace`, `wrappers`, `pgrouting`) and generates SQL to re-enable them after the upgrade 2. Temporarily grants superuser to the `postgres` role (required by `pg_upgrade`) 3. Extracts the previously saved Postgres 17 binaries tarball and runs `initdb` to create a new empty database 4. Runs `pg_upgrade --check` to verify the upgrade can succeed before making changes 5. Stops Postgres 15 and runs `pg_upgrade` to migrate all data to the new database 6. Copies Postgres configuration and the SQL scripts generated by `pg_upgrade` to a staging directory for the next phase **Phase 2 - Finalize (Postgres 17 container):** 1. Moves the upgraded data directory into place and starts Postgres 17 2. Applies extension compatibility patches for Wrappers, `pg_net`, `pg_cron`, and Vault (fixes ownership, grants, and foreign server options) 3. Runs the SQL scripts generated by `pg_upgrade` to update system catalogs and extension versions 4. Re-enables the extensions that were disabled in phase 1 5. Grants predefined roles (`pg_monitor`, `pg_read_all_data`, `pg_signal_backend`, and on Postgres 16+ also `pg_create_subscription`) and revokes the temporary superuser grant 6. Restarts Postgres and runs `vacuumdb --all --analyze-in-stages` to rebuild optimizer statistics After both phases complete, the upgrade script preserves the original Postgres 15 data directory as a backup and starts the full Supabase stack with Postgres 17. Troubleshooting[#](https://supabase.com/docs/guides/self-hosting/postgres-upgrade-17#troubleshooting) ------------------------------------------------------------------------------------------------------ ### pg\_upgrade fails with replication slot errors[#](https://supabase.com/docs/guides/self-hosting/postgres-upgrade-17#pgupgrade-fails-with-replication-slot-errors) `pg_upgrade` cannot proceed if there are active replication slots. Default self-hosted installs don't have any, but if you set up logical replication or have custom replication configurations, drop the slots before upgrading: 1docker exec supabase-db psql -h localhost -U supabase_admin -d postgres -c "2 SELECT pg_drop_replication_slot(slot_name)3 FROM pg_replication_slots;4" Then re-run the upgrade script. Replication slots will need to be manually recreated after the upgrade. ### "Permission denied" on the data directory[#](https://supabase.com/docs/guides/self-hosting/postgres-upgrade-17#permission-denied-on-the-data-directory) The upgrade script fixes file ownership automatically (Postgres 15 and 17 use different UIDs). If you still see permission errors, run: 1docker compose -f docker-compose.yml -f docker-compose.pg17.yml run --rm db \2chown -R postgres:postgres /var/lib/postgresql/data ### pgsodium / Supabase Vault errors[#](https://supabase.com/docs/guides/self-hosting/postgres-upgrade-17#pgsodium--supabase-vault-errors) The `db-config` named volume contains the pgsodium root encryption key at `/etc/postgresql-custom/pgsodium_root.key`. This volume is preserved during the upgrade. Never run `docker compose down -v` as this destroys named volumes and makes vault secrets unrecoverable. ### Services fail to connect after upgrade[#](https://supabase.com/docs/guides/self-hosting/postgres-upgrade-17#services-fail-to-connect-after-upgrade) Restart all services to pick up the new database: 1docker compose -f docker-compose.yml -f docker-compose.pg17.yml down && \2docker compose -f docker-compose.yml -f docker-compose.pg17.yml up -d ### Disk space issues during upgrade[#](https://supabase.com/docs/guides/self-hosting/postgres-upgrade-17#disk-space-issues-during-upgrade) The upgrade needs space for: * The upgrade tarball (~1.2 GB compressed, cached for re-runs) * A full copy of your database (created by `pg_upgrade`) * The original data (kept as backup) The script uses `/tmp` (or `TMPDIR` if set) for its staging directory, which holds the downloaded tarball and upgrade scripts. If your `/tmp` filesystem is small or mounted with limited space, you can point it to a different location, e.g.: 1sudo TMPDIR=/mnt/my-tmp bash utils/upgrade-pg17.sh If you run out of space mid-upgrade, the safest path is to roll back and free up disk space before retrying. ### Postgres 17 fails to start with a leftover db-config volume[#](https://supabase.com/docs/guides/self-hosting/postgres-upgrade-17#postgres-17-fails-to-start-with-a-leftover-db-config-volume) If you are starting a **fresh** Postgres 17 deployment (not upgrading from Postgres 15) and the container fails to start, the most likely cause is a leftover `db-config` volume from a previous Postgres 15 installation. Try to start the containers without the `-d` option and/or check the logs for errors about `postgresql.conf` or other configuration mismatch. To fix, remove the old volume and let Postgres 17 initialize a clean configuration: 1docker compose -f docker-compose.yml -f docker-compose.pg17.yml down && \2docker volume rm $(docker volume ls --filter "name=db-config" --format '{{.Name}}') && \3docker compose -f docker-compose.yml -f docker-compose.pg17.yml up -d Removing the `db-config` volume destroys any custom Postgres configuration and the pgsodium root key. Only do this for fresh installations with no existing data or vault secrets. ### Restoring from a manual backup[#](https://supabase.com/docs/guides/self-hosting/postgres-upgrade-17#restoring-from-a-manual-backup) If the upgrade fails and the script's built-in rollback isn't sufficient, restore from the manual backups created in the [Create a backup](https://supabase.com/docs/guides/self-hosting/postgres-upgrade-17#create-a-backup) step: Restore the data: 1docker compose -f docker-compose.yml -f docker-compose.pg17.yml down && \2rm -rf ./volumes/db/data && \3cp -a ./volumes/db/data-manual-backup ./volumes/db/data Restore the pgsodium key to the `db-config` volume: 1docker compose run --rm db \2 sh -c 'cat > /etc/postgresql-custom/pgsodium_root.key' < ./pgsodium_root.key.backup && \3docker compose run --rm db \4 chown postgres:postgres /etc/postgresql-custom/pgsodium_root.key && \5docker compose run --rm db \6 chmod 600 /etc/postgresql-custom/pgsodium_root.key Start Postgres 15: 1docker compose up -d ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/self-hosting/postgres-upgrade-17%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/self-hosting/postgres-upgrade-17%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Self-Hosted Functions | Supabase Docs Self-Hosting Self-Hosted Functions ========================= Run and manage Edge Functions in your self-hosted Supabase instance. ------------------------------------------------------------------------ * * * Edge Functions work out of the box in a self-hosted Supabase setup. The `functions` service, API gateway routing, and a `hello` example function are all [pre-configured](https://github.com/supabase/supabase/tree/master/docker) . On managed Supabase platform, Edge Functions are deployed across multiple regions. Self-hosted standalone instance configuration resembles a standard serverless setup. Invoke the default function[#](https://supabase.com/docs/guides/self-hosting/self-hosted-functions#invoke-the-default-function) -------------------------------------------------------------------------------------------------------------------------------- The default `hello` function is located at `volumes/functions/hello/index.ts`. You can invoke it immediately after starting your stack: 1curl http://:8000/functions/v1/hello This returns `"Hello from Edge Functions!"`. Create a new function[#](https://supabase.com/docs/guides/self-hosting/self-hosted-functions#create-a-new-function) -------------------------------------------------------------------------------------------------------------------- ### Step 1: Add a new function directory and the function code[#](https://supabase.com/docs/guides/self-hosting/self-hosted-functions#step-1-add-a-new-function-directory-and-the-function-code) 1mkdir -p volumes/functions/my-function &&2touch volumes/functions/my-function/index.ts add the following code to `index.ts`: 1Deno.serve(async (req: Request) => {2 const { name } = await req.json()3 const message = `Hello, ${name}!`45 return new Response(JSON.stringify({ message }), {6 headers: { 'Content-Type': 'application/json' },7 })8}) ### Step 2: Restart the functions service to pick up the new function[#](https://supabase.com/docs/guides/self-hosting/self-hosted-functions#step-2-restart-the-functions-service-to-pick-up-the-new-function) 1docker compose restart functions --no-deps ### Step 3: Invoke your function[#](https://supabase.com/docs/guides/self-hosting/self-hosted-functions#step-3-invoke-your-function) 1curl -X POST http://:8000/functions/v1/my-function \2 -H 'Content-Type: application/json' \3 -d '{"name": "World"}' You should be able to see the response from `my-function`: 1{"message":"Hello, World!"} Custom environment variables[#](https://supabase.com/docs/guides/self-hosting/self-hosted-functions#custom-environment-variables) ---------------------------------------------------------------------------------------------------------------------------------- ### Using an env file (recommended)[#](https://supabase.com/docs/guides/self-hosting/self-hosted-functions#using-an-env-file-recommended) For multiple variables or secrets, create a separate env file, e.g., `.env.functions` in your `docker/` directory: 1MY_CUSTOM_VAR=some-value Add `env_file` to the `functions` service in `docker-compose.yml` (variables in `env_file` load first, then `environment` values take precedence): 1functions:2 env_file:3 - .env.functions4 environment:5 JWT_SECRET: ${JWT_SECRET}6 SUPABASE_URL: http://kong:8000 Don't commit `.env.functions` to version control if it contains secrets. Add it to your `.gitignore`. Restart the functions service: 1docker compose up -d --force-recreate --no-deps functions ### Using inline environment variables[#](https://supabase.com/docs/guides/self-hosting/self-hosted-functions#using-inline-environment-variables) For one or two variables, you can add them directly under `environment` in `docker-compose.yml`: 1functions:2 environment:3 # Custom variables4 MY_CUSTOM_VAR: ${MY_CUSTOM_VAR}5 # Required variables6 JWT_SECRET: ${JWT_SECRET}7 SUPABASE_URL: http://kong:8000 Then define `MY_CUSTOM_VAR` in your main `.env` file, or specify the value directly. ### Accessing variables in functions[#](https://supabase.com/docs/guides/self-hosting/self-hosted-functions#accessing-variables-in-functions) All container environment variables are forwarded to function workers by `main/index.ts`. Access them with: 1const customVar = Deno.env.get('MY_CUSTOM_VAR') Calling Supabase services from functions[#](https://supabase.com/docs/guides/self-hosting/self-hosted-functions#calling-supabase-services-from-functions) ---------------------------------------------------------------------------------------------------------------------------------------------------------- The functions service is pre-configured with the following environment variables: | Variable | Value | Purpose | | --- | --- | --- | | `SUPABASE_URL` | `http://kong:8000` | Internal API gateway URL | | `SUPABASE_PUBLIC_URL` | `http://:8000` | Base URL for accessing Supabase from the Internet | | `JWT_SECRET` | Your secret key | Legacy symmetric encryption key used to sign and verify JWTs | | `SUPABASE_ANON_KEY` | Your anon key | Client-side API key with limited permissions (`anon` role). | | `SUPABASE_SERVICE_ROLE_KEY` | Your service role key | Server-side API key with full database access (`service_role` role) | | `SUPABASE_DB_URL` | Postgres connection string | Can be used for direct database access | Here's an example function that queries a table using `@supabase/supabase-js`: 1import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'23Deno.serve(async () => {4 const supabase = createClient(5 Deno.env.get('SUPABASE_URL')!,6 Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!7 )89 const { data, error } = await supabase.from('todos').select('*')1011 return new Response(JSON.stringify({ data, error }), {12 headers: { 'Content-Type': 'application/json' },13 })14}) ### Internal vs external URLs[#](https://supabase.com/docs/guides/self-hosting/self-hosted-functions#internal-vs-external-urls) This is a key distinction that affects how you build URLs in your functions: * **`SUPABASE_URL`** contains an internal Docker network hostname. Use it for server-side calls from your functions to other Supabase services (Auth, Storage, database via PostgREST). This is what the Supabase JS client should use inside functions. * **`SUPABASE_PUBLIC_URL`** is the externally-reachable URL of your Supabase instance (e.g., `:8000`). Use it if your function needs to build URLs that HTTP clients can reach from the outside. Managing functions via dashboard[#](https://supabase.com/docs/guides/self-hosting/self-hosted-functions#managing-functions-via-dashboard) ------------------------------------------------------------------------------------------------------------------------------------------ Self-hosted Studio [mounts](https://github.com/supabase/supabase/blob/df8729a82b1847e2989c14ede27965612761d503/docker/docker-compose.yml#L66) the same `volumes/functions` directory as the functions service. You can check what functions are available using **Edge Functions** > **Functions** UI. Deploying functions to a remote server[#](https://supabase.com/docs/guides/self-hosting/self-hosted-functions#deploying-functions-to-a-remote-server) ------------------------------------------------------------------------------------------------------------------------------------------------------ To deploy a function to a remote server running self-hosted Supabase, copy the function directory with `scp`: 1scp -r ./my-function user@:/path/to/self-hosted/volumes/functions/ Then restart the functions service on the remote host: 1ssh user@ 'cd /path/to/self-hosted && docker compose restart functions --no-deps' Copying functions from Supabase platform[#](https://supabase.com/docs/guides/self-hosting/self-hosted-functions#copying-functions-from-supabase-platform) ---------------------------------------------------------------------------------------------------------------------------------------------------------- If you have existing functions on Supabase platform, you can download them and run them on your self-hosted instance. There are two ways to get the function source code: * **Dashboard** - open the function details in Dashboard and click **Download**. * **Local development & CLI** - run `supabase functions download --project-ref ` to download the source. Use `scp` to copy the function into `volumes/functions//` on your self-hosted instance, then restart the functions service. For more details, see: * [Quick start - Download edge functions](https://supabase.com/docs/guides/functions/quickstart-dashboard#download-edge-functions) * [CLI commands - Download a function](https://supabase.com/docs/reference/cli/supabase-functions-download) Troubleshooting[#](https://supabase.com/docs/guides/self-hosting/self-hosted-functions#troubleshooting) -------------------------------------------------------------------------------------------------------- ### 400 "missing function name in request"[#](https://supabase.com/docs/guides/self-hosting/self-hosted-functions#400-missing-function-name-in-request) The request URL must include the function name after `/functions/v1/`. For example, `/functions/v1/hello` — not just `/functions/v1/`. ### 500 error on invocation[#](https://supabase.com/docs/guides/self-hosting/self-hosted-functions#500-error-on-invocation) Check the functions service logs: 1docker compose logs functions Common causes: syntax errors in your function code, invalid imports, or missing dependencies. ### 401 "invalid JWT"[#](https://supabase.com/docs/guides/self-hosting/self-hosted-functions#401-invalid-jwt) * Check that `FUNCTIONS_VERIFY_JWT` matches your intent (`true` or `false`) in `.env` * If verification is enabled, ensure you're passing a valid token: `Authorization: Bearer ` ### Changes to function code not reflected after editing[#](https://supabase.com/docs/guides/self-hosting/self-hosted-functions#changes-to-function-code-not-reflected-after-editing) Restart the functions service: 1docker compose restart functions --no-deps ### Custom env vars not available in functions[#](https://supabase.com/docs/guides/self-hosting/self-hosted-functions#custom-env-vars-not-available-in-functions) * Verify the variable is defined in `docker-compose.yml` (under `env_file` or `environment`) * Recreate the functions container after changing configuration * Check that the variable name matches exactly (case-sensitive) Use the following command to recreate the container, not just `restart`: 1docker compose up -d --force-recreate --no-deps functions ### Memory or timeout errors[#](https://supabase.com/docs/guides/self-hosting/self-hosted-functions#memory-or-timeout-errors) The default limits are 150 MB memory and 60 seconds timeout per function invocation. These are set in `volumes/functions/main/index.ts`. To adjust them, edit the `memoryLimitMb` and `workerTimeoutMs` values and restart the functions service. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/self-hosting/self-hosted-functions%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/self-hosting/self-hosted-functions%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Hugging Face Inference API | Supabase Docs AI & Vectors Hugging Face Inference API ============================== * * * [Hugging Face](https://huggingface.co/) is an open source hub for AI/ML models and tools. With over 100,000 machine learning models available, Hugging Face provides a great way to integrate specialized AI & ML tasks into your application. There are 3 ways to use Hugging Face models in your application: 1. Use the [Transformers](https://huggingface.co/docs/transformers/index) Python library to perform inference in a Python backend. 2. [Generate embeddings](https://supabase.com/docs/guides/ai/quickstarts/generate-text-embeddings) directly in Edge Functions using Transformers.js. 3. Use Hugging Face's hosted [Inference API](https://huggingface.co/inference-api) to execute AI tasks remotely on Hugging Face servers. This guide will walk you through this approach. AI tasks[#](https://supabase.com/docs/guides/ai/hugging-face#ai-tasks) ----------------------------------------------------------------------- Below are some of the types of tasks you can perform with Hugging Face: ### Natural language[#](https://supabase.com/docs/guides/ai/hugging-face#natural-language) * [Summarization](https://huggingface.co/tasks/summarization) * [Text classification](https://huggingface.co/tasks/text-classification) * [Text generation](https://huggingface.co/tasks/text-generation) * [Translation](https://huggingface.co/tasks/translation) * [Fill in the blank](https://huggingface.co/tasks/fill-mask) ### Computer vision[#](https://supabase.com/docs/guides/ai/hugging-face#computer-vision) * [Image to text](https://huggingface.co/tasks/image-to-text) * [Text to image](https://huggingface.co/tasks/text-to-image) * [Image classification](https://huggingface.co/tasks/image-classification) * [Video classification](https://huggingface.co/tasks/video-classification) * [Object detection](https://huggingface.co/tasks/object-detection) * [Image segmentation](https://huggingface.co/tasks/image-segmentation) ### Audio[#](https://supabase.com/docs/guides/ai/hugging-face#audio) * [Text to speech](https://huggingface.co/tasks/text-to-speech) * [Speech to text](https://huggingface.co/tasks/automatic-speech-recognition) * [Audio classification](https://huggingface.co/tasks/audio-classification) See a [full list of tasks](https://huggingface.co/tasks) . Access token[#](https://supabase.com/docs/guides/ai/hugging-face#access-token) ------------------------------------------------------------------------------- First generate a Hugging Face access token for your app: [https://huggingface.co/settings/tokens](https://huggingface.co/settings/tokens) Name your token based on the app its being used for and the environment. For example, if you are building an image generation app you might create 2 tokens: * "Image Generator (Dev)" * "Image Generator (Prod)" Since we will be using this token for the inference API, choose the `read` role. Though it is possible to use the Hugging Face inference API today without an access token, [you may be rate limited](https://huggingface.co/docs/huggingface.js/inference/README#usage) . To ensure you don't experience any unexpected downtime or errors, we recommend creating an access token. Edge Functions[#](https://supabase.com/docs/guides/ai/hugging-face#edge-functions) ----------------------------------------------------------------------------------- Edge Functions are server-side TypeScript functions that run on-demand. Since Edge Functions run on a server, you can safely give them access to your Hugging Face access token. You will need the `supabase` CLI [installed](https://supabase.com/docs/guides/cli) for the following commands to work. To create a new Edge Function, navigate to your local project and initialize Supabase if you haven't already: 1supabase init Then create an Edge Function: 1supabase functions new text-to-image Create a file called `.env.local` to store your Hugging Face access token: 1HUGGING_FACE_ACCESS_TOKEN= Let's modify the Edge Function to import Hugging Face's inference client and perform a `text-to-image` request: 1import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'2import { HfInference } from 'https://esm.sh/@huggingface/inference@2.3.2'34const hf = new HfInference(Deno.env.get('HUGGING_FACE_ACCESS_TOKEN'))56serve(async (req) => {7 const { prompt } = await req.json()89 const image = await hf.textToImage(10 {11 inputs: prompt,12 model: 'stabilityai/stable-diffusion-2',13 },14 {15 use_cache: false,16 }17 )1819 return new Response(image)20}) 1. This function creates a new instance of `HfInference` using the `HUGGING_FACE_ACCESS_TOKEN` environment variable. 2. It expects a POST request that includes a JSON request body. The JSON body should include a parameter called `prompt` that represents the text-to-image prompt that we will pass to Hugging Face's inference API. 3. Next we call `textToImage()`, passing in the user's prompt along with the model that we would like to use for the image generation. Today Hugging Face recommends `stabilityai/stable-diffusion-2`, but you can change this to any other text-to-image model. You can see a list of which models are supported for each task by navigating to their [models page](https://huggingface.co/models?pipeline_tag=text-to-image) and filtering by task. 4. We set `use_cache` to `false` so that repeat queries with the same prompt will produce new images. If the task and model you are using is deterministic (will always produce the same result based on the same input), consider setting `use_cache` to `true` for faster responses. 5. The `image` result returned from the API will be a `Blob`. We can pass the `Blob` directly into a `new Response()` which will automatically set the content type and body of the response from the `image`. Finally let's serve the Edge Function locally to test it: 1supabase functions serve --env-file .env.local --no-verify-jwt Remember to pass in the `.env.local` file using the `--env-file` parameter so that the Edge Function can access the `HUGGING_FACE_ACCESS_TOKEN`. For demo purposes we set `--no-verify-jwt` to make it easy to test the Edge Function without passing in a JWT token. In a real application you will need to pass the JWT as a `Bearer` token in the `Authorization` header. At this point, you can make an API request to your Edge Function using your preferred frontend framework (Next.js, React, Expo, etc). We can also test from the terminal using `curl`: 1curl --output result.jpg --location --request POST 'http://localhost:54321/functions/v1/text-to-image' \2 --header 'Content-Type: application/json' \3 --data '{"prompt":"Llama wearing sunglasses"}' In this example, your generated image will save to `result.jpg`: ![Llama wearing sunglasses example](https://supabase.com/docs/img/ai/hugging-face/llama-sunglasses-example.png) Next steps[#](https://supabase.com/docs/guides/ai/hugging-face#next-steps) --------------------------------------------------------------------------- You can now create an Edge Function that invokes a Hugging Face task using your model of choice. Try running some other [AI tasks](https://supabase.com/docs/guides/ai/hugging-face#ai-tasks) . Resources[#](https://supabase.com/docs/guides/ai/hugging-face#resources) ------------------------------------------------------------------------- * Official [Hugging Face site](https://huggingface.co/) . * Official [Hugging Face JS docs](https://huggingface.co/docs/huggingface.js) . * [Generate image captions](https://supabase.com/docs/guides/ai/examples/huggingface-image-captioning) using Hugging Face. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/ai/hugging-face%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/ai/hugging-face%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Concepts | Supabase Docs AI & Vectors Concepts ============ * * * Embeddings are core to many AI and vector applications. This guide covers these concepts. If you prefer to get started right away, see our guide on [Generating Embeddings](https://supabase.com/docs/guides/ai/quickstarts/generate-text-embeddings) . What are embeddings?[#](https://supabase.com/docs/guides/ai/concepts#what-are-embeddings) ------------------------------------------------------------------------------------------ Embeddings capture the "relatedness" of text, images, video, or other types of information. This relatedness is most commonly used for: * **Search:** how similar is a search term to a body of text? * **Recommendations:** how similar are two products? * **Classifications:** how do we categorize a body of text? * **Clustering:** how do we identify trends? Let's explore an example of text embeddings. Say we have three phrases: 1. "The cat chases the mouse" 2. "The kitten hunts rodents" 3. "I like ham sandwiches" Your job is to group phrases with similar meaning. If you are a human, this should be obvious. Phrases 1 and 2 are almost identical, while phrase 3 has a completely different meaning. Although phrases 1 and 2 are similar, they share no common vocabulary (besides "the"). Yet their meanings are nearly identical. How can we teach a computer that these are the same? Human language[#](https://supabase.com/docs/guides/ai/concepts#human-language) ------------------------------------------------------------------------------- Humans use words and symbols to communicate language. But words in isolation are mostly meaningless - we need to draw from shared knowledge & experience in order to make sense of them. The phrase “You should Google it” only makes sense if you know that Google is a search engine and that people have been using it as a verb. In the same way, we need to train a neural network model to understand human language. An effective model should be trained on millions of different examples to understand what each word, phrase, sentence, or paragraph could mean in different contexts. So how does this relate to embeddings? How do embeddings work?[#](https://supabase.com/docs/guides/ai/concepts#how-do-embeddings-work) ------------------------------------------------------------------------------------------------ Embeddings compress discrete information (words & symbols) into distributed continuous-valued data (vectors). If we took our phrases from before and plot them on a chart, it might look something like this: ![Vector similarity](https://supabase.com/docs/img/ai/vector-similarity.png) Phrases 1 and 2 would be plotted close to each other, since their meanings are similar. We would expect phrase 3 to live somewhere far away since it isn't related. If we had a fourth phrase, “Sally ate Swiss cheese”, this might exist somewhere between phrase 3 (cheese can go on sandwiches) and phrase 1 (mice like Swiss cheese). In this example we only have 2 dimensions: the X and Y axis. In reality, we would need many more dimensions to effectively capture the complexities of human language. Using embeddings[#](https://supabase.com/docs/guides/ai/concepts#using-embeddings) ----------------------------------------------------------------------------------- Compared to our 2-dimensional example above, most embedding models will output many more dimensions. For example the open source [`gte-small`](https://huggingface.co/Supabase/gte-small) model outputs 384 dimensions. Why is this useful? Once we have generated embeddings on multiple texts, it is trivial to calculate how similar they are using vector math operations like cosine distance. A common use case for this is search. Your process might look something like this: 1. Pre-process your knowledge base and generate embeddings for each page 2. Store your embeddings to be referenced later 3. Build a search page that prompts your user for input 4. Take user's input, generate a one-time embedding, then perform a similarity search against your pre-processed embeddings. 5. Return the most similar pages to the user See also[#](https://supabase.com/docs/guides/ai/concepts#see-also) ------------------------------------------------------------------- * [Structured and Unstructured embeddings](https://supabase.com/docs/guides/ai/structured-unstructured) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/ai/concepts%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/ai/concepts%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Enterprise Single Sign-On | Supabase Docs Auth Enterprise Single Sign-On ============================= * * * Supabase Auth supports building enterprise applications that require Single Sign-On (SSO) authentication [with SAML 2.0](https://supabase.com/docs/guides/auth/sso/auth-sso-saml) . ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/auth/enterprise-sso%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/auth/enterprise-sso%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Users | Supabase Docs Auth Users ========= * * * A **user** in Supabase Auth is someone with a user ID, stored in the Auth schema. Once someone is a user, they can be issued an Access Token, which can be used to access Supabase endpoints. The token is tied to the user, so you can restrict access to resources via [RLS policies](https://supabase.com/docs/guides/database/postgres/row-level-security) . Permanent and anonymous users[#](https://supabase.com/docs/guides/auth/users#permanent-and-anonymous-users) ------------------------------------------------------------------------------------------------------------ Supabase distinguishes between permanent and anonymous users. * **Permanent users** are tied to a piece of Personally Identifiable Information (PII), such as an email address, a phone number, or a third-party identity. They can use these identities to sign back into their account after signing out. * **Anonymous users** aren't tied to any identities. They have a user ID and a personalized Access Token, but they have no way of signing back in as the same user if they are signed out. Anonymous users are useful for: * E-commerce applications, to create shopping carts before checkout * Full-feature demos without collecting personal information * Temporary or throw-away accounts See the [Anonymous Signins guide](https://supabase.com/docs/guides/auth/auth-anonymous) to learn more about anonymous users. ##### Anonymous users do not use the anon role Just like permanent users, anonymous users use the **authenticated** role for database access. The **anon** role is for those who aren't signed in at all and are not tied to any user ID. We refer to these as unauthenticated or public users. The user object[#](https://supabase.com/docs/guides/auth/users#the-user-object) -------------------------------------------------------------------------------- The user object stores all the information related to a user in your application. The user object can be retrieved using one of these methods: 1. [`supabase.auth.getUser()`](https://supabase.com/docs/reference/javascript/auth-getuser) 2. Retrieve a user object as an admin using [`supabase.auth.admin.getUserById()`](https://supabase.com/docs/reference/javascript/auth-admin-listusers) A user can sign in with one of the following methods: * Password-based method (with email or phone) * Passwordless method (with email or phone) * OAuth * SAML SSO An identity describes the authentication method that a user can use to sign in. A user can have multiple identities. These are the types of identities supported: * Email * Phone * OAuth * SAML A user with an email or phone identity will be able to sign in with either a password or passwordless method (e.g. use a one-time password (OTP) or magic link). By default, a user with an unverified email or phone number will not be able to sign in. The user object contains the following attributes: | Attributes | Type | Description | | --- | --- | --- | | id | `string` | The unique id of the identity of the user. | | aud | `string` | The audience claim. | | role | `string` | The role claim used by Postgres to perform Row Level Security (RLS) checks. | | email | `string` | The user's email address. | | email\_confirmed\_at | `string` | The timestamp that the user's email was confirmed. If null, it means that the user's email is not confirmed. | | phone | `string` | The user's phone number. | | phone\_confirmed\_at | `string` | The timestamp that the user's phone was confirmed. If null, it means that the user's phone is not confirmed. | | confirmed\_at | `string` | The timestamp that either the user's email or phone was confirmed. If null, it means that the user does not have a confirmed email address and phone number. | | last\_sign\_in\_at | `string` | The timestamp that the user last signed in. | | app\_metadata | `object` | The `provider` attribute indicates the first provider that the user used to sign up with. The `providers` attribute indicates the list of providers that the user can use to login with. | | user\_metadata | `object` | Defaults to the first provider's identity data but can contain additional custom user metadata if specified. Refer to [**User Identity**](https://supabase.com/docs/guides/auth/auth-identity-linking#the-user-identity)
for more information about the identity object. Don't rely on the order of information in this field. Do not use it in security sensitive context (such as in RLS policies or authorization logic), as this value is editable by the user without any checks. | | identities | `UserIdentity[]` | Contains an object array of identities linked to the user. | | created\_at | `string` | The timestamp that the user was created. | | updated\_at | `string` | The timestamp that the user was last updated. | | is\_anonymous | `boolean` | Is true if the user is an anonymous user. | Resources[#](https://supabase.com/docs/guides/auth/users#resources) -------------------------------------------------------------------- * [User Management guide](https://supabase.com/docs/guides/auth/managing-user-data) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/auth/users%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/auth/users%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Control your costs | Supabase Docs Platform Control your costs ====================== * * * Spend Cap[#](https://supabase.com/docs/guides/platform/cost-control#spend-cap) ------------------------------------------------------------------------------- The Spend Cap determines whether your organization can exceed your subscription plan's quota for any usage item. Scenarios that could lead to high usage—and thus high costs—include system attacks or bugs in your software. The Spend Cap can protect you from these unexpected costs for certain usage items. This feature is available only with the Pro Plan. However, you will not be charged while using the Free Plan. ### What happens when the Spend Cap is on?[#](https://supabase.com/docs/guides/platform/cost-control#what-happens-when-the-spend-cap-is-on) After exceeding the quota for a usage item, further usage of that item is disallowed until the next billing cycle. You don't get charged for over-usage but your services will be restricted according to our [Fair Use Policy](https://supabase.com/docs/guides/platform/billing-faq#fair-use-policy) if you consistently exceed the quota. Note that only certain usage items are covered by the Spend Cap. ### What happens when the Spend Cap is off?[#](https://supabase.com/docs/guides/platform/cost-control#what-happens-when-the-spend-cap-is-off) Your projects will continue to operate after exceeding the quota for a usage item. Any additional usage will be charged based on the item's cost per unit, as outlined on the [pricing page](https://supabase.com/pricing) . When the Spend Cap is off, we recommend monitoring your usage and costs on the [organization's usage page](https://supabase.com/dashboard/org/_/usage) . ### Usage items covered by the Spend Cap[#](https://supabase.com/docs/guides/platform/cost-control#usage-items-covered-by-the-spend-cap) * [Disk Size](https://supabase.com/docs/guides/platform/manage-your-usage/disk-size) * [Egress](https://supabase.com/docs/guides/platform/manage-your-usage/egress) * [Edge Function Invocations](https://supabase.com/docs/guides/platform/manage-your-usage/edge-function-invocations) * [Monthly Active Users](https://supabase.com/docs/guides/platform/manage-your-usage/monthly-active-users) * [Monthly Active SSO Users](https://supabase.com/docs/guides/platform/manage-your-usage/monthly-active-users-sso) * [Monthly Active Third Party Users](https://supabase.com/docs/guides/platform/manage-your-usage/monthly-active-users-third-party) * [Realtime Messages](https://supabase.com/docs/guides/platform/manage-your-usage/realtime-messages) * [Realtime Peak Connections](https://supabase.com/docs/guides/platform/manage-your-usage/realtime-peak-connections) * [Storage Image Transformations](https://supabase.com/docs/guides/platform/manage-your-usage/storage-image-transformations) * [Storage Size](https://supabase.com/docs/guides/platform/manage-your-usage/storage-size) ### Usage items not covered by the Spend Cap[#](https://supabase.com/docs/guides/platform/cost-control#usage-items-not-covered-by-the-spend-cap) Usage items that are predictable and explicitly opted into by the user are excluded. * [Compute](https://supabase.com/docs/guides/platform/manage-your-usage/compute) * [Branching Compute](https://supabase.com/docs/guides/platform/manage-your-usage/branching) * [Read Replica Compute](https://supabase.com/docs/guides/platform/manage-your-usage/read-replicas) * [Custom Domain](https://supabase.com/docs/guides/platform/manage-your-usage/custom-domains) * Additionally provisioned [Disk IOPS](https://supabase.com/docs/guides/platform/manage-your-usage/disk-iops) * Additionally provisioned [Disk Throughput](https://supabase.com/docs/guides/platform/manage-your-usage/disk-throughput) * [IPv4 address](https://supabase.com/docs/guides/platform/manage-your-usage/ipv4) * [Log Drain Hours](https://supabase.com/docs/guides/platform/manage-your-usage/log-drains#log-drain-hours) * [Log Drain Events](https://supabase.com/docs/guides/platform/manage-your-usage/log-drains#log-drain-events) * [Multi-Factor Authentication Phone](https://supabase.com/docs/guides/platform/manage-your-usage/advanced-mfa-phone) * [Point-in-Time-Recovery](https://supabase.com/docs/guides/platform/manage-your-usage/point-in-time-recovery) ### What the Spend Cap is not[#](https://supabase.com/docs/guides/platform/cost-control#what-the-spend-cap-is-not) The Spend Cap doesn't allow for fine-grained cost control, such as setting budgets for specific usage item or receiving notifications when certain costs are reached. We plan to make cost control more flexible in the future. ### Configure the Spend Cap[#](https://supabase.com/docs/guides/platform/cost-control#configure-the-spend-cap) You can configure the Spend Cap when creating an organization on the Pro Plan or at any time in the Cost Control section of the [organization's billing page](https://supabase.com/dashboard/org/_/billing) . Keep track of your usage and costs[#](https://supabase.com/docs/guides/platform/cost-control#keep-track-of-your-usage-and-costs) --------------------------------------------------------------------------------------------------------------------------------- You can monitor your usage on the [organization's usage page](https://supabase.com/dashboard/org/_/usage) . The Upcoming Invoice section of the [organization's billing page](https://supabase.com/dashboard/org/_/billing) shows your current spending and provides an estimate of your total costs for the billing cycle based on your usage. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/platform/cost-control%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/platform/cost-control%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Manage your usage | Supabase Docs Platform Manage your usage ===================== * * * Each subpage breaks down a specific usage item and details what you're charged for, how costs are calculated, and how to optimize usage and reduce costs. * [Compute](https://supabase.com/docs/guides/platform/manage-your-usage/compute) * [Read Replicas](https://supabase.com/docs/guides/platform/manage-your-usage/read-replicas) * [Branching](https://supabase.com/docs/guides/platform/manage-your-usage/branching) * [Egress](https://supabase.com/docs/guides/platform/manage-your-usage/egress) * [Disk Size](https://supabase.com/docs/guides/platform/manage-your-usage/disk-size) * [Disk Throughput](https://supabase.com/docs/guides/platform/manage-your-usage/disk-throughput) * [Disk IOPS](https://supabase.com/docs/guides/platform/manage-your-usage/disk-iops) * [Monthly Active Users](https://supabase.com/docs/guides/platform/manage-your-usage/monthly-active-users) * [Monthly Active Third-Party Users](https://supabase.com/docs/guides/platform/manage-your-usage/monthly-active-users-third-party) * [Monthly Active SSO Users](https://supabase.com/docs/guides/platform/manage-your-usage/monthly-active-users-sso) * [Storage Size](https://supabase.com/docs/guides/platform/manage-your-usage/storage-size) * [Storage Image Transformations](https://supabase.com/docs/guides/platform/manage-your-usage/storage-image-transformations) * [Edge Function Invocations](https://supabase.com/docs/guides/platform/manage-your-usage/edge-function-invocations) * [Realtime Messages](https://supabase.com/docs/guides/platform/manage-your-usage/realtime-messages) * [Realtime Peak Connections](https://supabase.com/docs/guides/platform/manage-your-usage/realtime-peak-connections) * [Custom Domains](https://supabase.com/docs/guides/platform/manage-your-usage/custom-domains) * [Point-in-Time Recovery](https://supabase.com/docs/guides/platform/manage-your-usage/point-in-time-recovery) * [IPv4](https://supabase.com/docs/guides/platform/manage-your-usage/ipv4) * [MFA Phone](https://supabase.com/docs/guides/platform/manage-your-usage/advanced-mfa-phone) * [Log Drains](https://supabase.com/docs/guides/platform/manage-your-usage/log-drains) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/platform/manage-your-usage%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/platform/manage-your-usage%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Password security | Supabase Docs Auth Password security ===================== Help your users to protect their password security ------------------------------------------------------ * * * A password is more secure if it is harder to guess or brute-force. In theory, a password is harder to guess if it is longer. It is also harder to guess if it uses a larger set of characters (for example, digits, lowercase and uppercase letters, and symbols). This table shows the _minimum_ number of guesses that need to be tried to access a user's account: | Required characters | Length | Guesses | | --- | --- | --- | | Digits only | 8 | ~ 227 | | Digits and letters | 8 | ~ 241 | | Digits, lower and uppercase letters | 8 | ~ 248 | | Digits, lower and uppercase letters, symbols | 8 | ~ 252 | In reality though, passwords are not always generated at random. They often contain variations of names, words, dates, and common phrases. Malicious actors can use these properties to guess a password in fewer attempts. There are hundreds of millions (and growing!) known passwords out there. Malicious actors can use these lists of leaked passwords to automate login attempts (known as credential stuffing) and steal or access sensitive user data. Password strength and leaked password protection[#](https://supabase.com/docs/guides/auth/password-security#password-strength-and-leaked-password-protection) -------------------------------------------------------------------------------------------------------------------------------------------------------------- To help protect your users, Supabase Auth allows you fine-grained control over the strength of the passwords used on your project. You can configure these in your project's [Auth settings](https://supabase.com/dashboard/project/_/auth/providers?provider=Email) : * Set a large minimum password length. Anything less than 8 characters is not recommended. * Set the required characters that must appear at least once in a user's password. Use the strongest option of requiring digits, lowercase and uppercase letters, and symbols. The allowed symbols are: ``!@#$%^&*()_+-=[]{};'\:"|<>?,./`~`` * Prevent the use of leaked passwords. Supabase Auth uses the open-source [HaveIBeenPwned.org Pwned Passwords API](https://haveibeenpwned.com/Passwords) to reject passwords that have been leaked and are known by malicious actors. Leaked password protection is available on the Pro Plan and above. Require reauthentication when changing password[#](https://supabase.com/docs/guides/auth/password-security#require-reauthentication-when-changing-password) ------------------------------------------------------------------------------------------------------------------------------------------------------------ Users will need to be recently logged in to change their password without requiring reauthentication. (A user is considered recently logged in if the session was created within the last 24 hours.) If disabled, a user can change their password at any time. When enabled, a `nonce` will be sent to the user and this nonce must be validated before the a password change can occur. This can be triggered with the [reauthenticate()](https://supabase.com/docs/reference/javascript/auth-reauthentication) API call. 1const { error } = await supabase.auth.reauthenticate()2...3// send the nonce provided by the user with the password change4const { data, error } = await supabase.auth.updateUser({5 email: 'user@email.com',6 nonce: `${nonce}`,7 password: "new_super_strong_password"8}) Require current password when changing password[#](https://supabase.com/docs/guides/auth/password-security#require-current-password-when-changing-password) ------------------------------------------------------------------------------------------------------------------------------------------------------------ Enforce that users supply their current password when trying to change the password. When enabled, the password change request will validate that the current password is correct before updating the user's password. 1const { data, error } = await supabase.auth.updateUser({2 email: 'user@email.com',3 current_password: "correct_current_password",4 password: "new_super_strong_password"5}) Additional recommendations[#](https://supabase.com/docs/guides/auth/password-security#additional-recommendations) ------------------------------------------------------------------------------------------------------------------ In addition to choosing suitable password strength settings and preventing the use of leaked passwords, consider asking your users to: * Use a password manager to store and generate passwords. * Avoid password reuse across websites and apps. * Avoid using personal information in passwords. * Use [Multi-Factor Authentication](https://supabase.com/docs/guides/auth/auth-mfa) . Frequently asked questions[#](https://supabase.com/docs/guides/auth/password-security#frequently-asked-questions) ------------------------------------------------------------------------------------------------------------------ ### How are passwords stored?[#](https://supabase.com/docs/guides/auth/password-security#how-are-passwords-stored) Supabase Auth uses [bcrypt](https://en.wikipedia.org/wiki/Bcrypt) , a strong password hashing function, to store hashes of users' passwords. Only hashed passwords are stored. You cannot impersonate a user with the password hash. Each hash is accompanied by a randomly generated salt parameter for extra security. The hash is stored in the `encrypted_password` column of the `auth.users` table. The column's name is a misnomer (cryptographic hashing is not encryption), but is kept for backward compatibility. ### How will strengthened password requirements affect current users?[#](https://supabase.com/docs/guides/auth/password-security#how-will-strengthened-password-requirements-affect-current-users) Existing users can still sign in with their current password even if it doesn't meet the new, strengthened password requirements. However, if their password falls short of these updated standards, they will encounter a `WeakPasswordError` during the `signInWithPassword` process, explaining why it's considered weak. This change is also applicable to new users and existing users changing their passwords, ensuring everyone adheres to the enhanced security standards. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/auth/password-security%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/auth/password-security%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Shared Responsibility Model | Supabase Docs Home Shared Responsibility Model =============================== * * * Running databases is a shared responsibility between you and Supabase. There are some things that we can take care of for you, and some things that you are responsible for. This is by design: we want to give you the freedom to use your database however you want. While we _could_ put many more restrictions in place to ensure that you can’t do anything wrong, you will eventually find those restrictions prohibitive. ![Diagram showing the shared responsibility model between Supabase and the customer. The customer is responsible for Application architecture and implementation, information and data, the database schema and user management. The responsibility for API rate-limiting, Postgres security controls, upgrades, performance tuning and resource allocation is shared. Supabase is responsible for Postgres backups and observability, operating system maintenance, infrastructure and the monitoring and security thereof.](https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fplatform%2Fshared-responsibility-model--light.png&w=3840&q=75) To summarize, you are always responsible for: * Your Supabase account * Access management (Supabase account, database, tables, etc) * Data * Applying security controls Generally, we aim to reduce your burden of managing infrastructure and knowing about Postgres internals, minimizing configuration as much as we can. Here are a few things that you should know: You share the security responsibility[#](https://supabase.com/docs/guides/deployment/shared-responsibility-model#you-share-the-security-responsibility) -------------------------------------------------------------------------------------------------------------------------------------------------------- We give you full access to the database. If you share that access with other people (either people on your team, or the public in general) then it is your responsibility to ensure that the access levels you provide are correctly managed. If you have an inexperienced member on your team, then you probably shouldn’t give them access to Production. You should set internal workflows around what they should and should not be able to do, with restricted access to avoid anything that might be deemed dangerous. You are also responsible for ensuring that tables with sensitive data have the right level of access. You are also responsible for managing your database secrets and API keys, storing them safely in an encrypted store. Supabase provides controls for [securing your data](https://supabase.com/docs/guides/database/secure-data) , and it is recommended that you always apply [Row Level Security](https://supabase.com/docs/guides/database/postgres/row-level-security) (RLS). We will also provide you with security alerts through [Security Advisor](https://supabase.com/dashboard/project/_/database/security-advisor) and applying the recommendations are your responsibility. You decide your own workflow[#](https://supabase.com/docs/guides/deployment/shared-responsibility-model#you-decide-your-own-workflow) -------------------------------------------------------------------------------------------------------------------------------------- There are _many_ ways to work with Supabase. You can use our Dashboard, our client libraries, external tools like Prisma and Drizzle, or migration tools like our CLI, Flyway, Sqitch, and anything else that is Postgres-compatible. You can develop directly on your database while you're getting started, run migrations from [local to production](https://supabase.com/docs/guides/getting-started/local-development) , or you can use [multiple environments](https://supabase.com/docs/guides/cli/managing-environments) . None of these are right or wrong. It depends on the stage of your project. You _definitely_ shouldn’t be developing on your database directly when you’re in production - but that’s absolutely fine when you’re prototyping and don’t have users. You are responsible for your application architecture[#](https://supabase.com/docs/guides/deployment/shared-responsibility-model#you-are-responsible-for-your-application-architecture) ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Supabase isn't a silver-bullet for bad architectural decisions. A poorly designed database will run poorly, no matter where it’s hosted. You can get away with a poorly-designed database for a while by adding compute. After a while, things will start to break. The database schema is the area you want to spend _the most_ time thinking about. That’s the benefit of Supabase - you can spend more time designing a scalable database system and less time thinking about the mundane tasks like implementing CRUD APIs. If you don’t want to implement logic inside your database, that is 100% fine. You can use _any_ tools which work with Postgres. You are responsible for third-party services[#](https://supabase.com/docs/guides/deployment/shared-responsibility-model#you-are-responsible-for-third-party-services) ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- Supabase offers a lot of opportunities for flexibly integrating with third-party services, such as: * OAuth and SAML login providers * SMTP and SMS sending APIs * Calls to external APIs within Postgres functions or triggers * Calls to external APIs within Edge Functions You are free to use and integrate with any service, but you're also responsible for ensuring that the performance, availability, and security of the services you use match up with your application's requirements. We do not monitor for outages or performance issues within integrations with third-party services. Depending on the implementation, an issue with such an integration could also result in performance degradation or an outage for your Supabase project. If your application architecture relies on such integrations, you should monitor the relevant logs and metrics to ensure optimal performance. You choose your level of comfort with Postgres[#](https://supabase.com/docs/guides/deployment/shared-responsibility-model#you-choose-your-level-of-comfort-with-postgres) -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Our goal at Supabase is to make _all_ of Postgres easy to use. That doesn’t mean you have to use all of it. If you’re a Postgres veteran, you’ll probably love the tools that we offer. If you’ve never used Postgres before, then start smaller and grow into it. If you just want to treat Postgres like a simple table-store, that’s perfectly fine. You are in control of your database[#](https://supabase.com/docs/guides/deployment/shared-responsibility-model#you-are-in-control-of-your-database) ---------------------------------------------------------------------------------------------------------------------------------------------------- Supabase places very few guard-rails around your database. That gives you a lot of control, but it also means you can break things. ”Break” is used liberally here. It refers to any situation that affects your application because of the way you're using the database. You are responsible for using best-practices to optimize and manage your database: adding indexes, adding filters on large queries, using caching strategies, optimizing your database queries, and managing connections to the database. You are responsible of provisioning enough compute to run the workload that your application requires. The Supabase Dashboard provides [observability tooling](https://supabase.com/dashboard/project/_/observability/database) to help with this. Before going to production[#](https://supabase.com/docs/guides/deployment/shared-responsibility-model#before-going-to-production) ---------------------------------------------------------------------------------------------------------------------------------- We recommend reviewing and applying the recommendations offered in our [Production Checklist](https://supabase.com/docs/guides/platform/going-into-prod) . This checklist covers the responsibilities discussed here and a few additional general production readiness best practices. SOC 2 and compliance[#](https://supabase.com/docs/guides/deployment/shared-responsibility-model#soc-2-and-compliance) ---------------------------------------------------------------------------------------------------------------------- Supabase provides a SOC 2 compliant environment for hosting and managing sensitive data. We recommend reviewing the [SOC 2 compliance responsibilities document](https://supabase.com/docs/guides/security/soc-2-compliance) alongside the aforementioned production checklist. Managing healthcare data[#](https://supabase.com/docs/guides/deployment/shared-responsibility-model#managing-healthcare-data) ------------------------------------------------------------------------------------------------------------------------------ You can use Supabase to store and process Protected Health Information (PHI). You are responsible for the following * Signing a Business Associate Agreement (BAA) with Supabase. Submit a [HIPAA add-on request](https://forms.supabase.com/hipaa2) to get started. You will need to be at least on the [Team Plan](https://supabase.com/pricing) to sign a BAA with us. * [Marking specific projects as HIPAA projects](https://supabase.com/docs/guides/platform/hipaa-projects) and addressing security issues raised by the advisor. * Ensuring [MFA is enabled](https://supabase.com/docs/guides/platform/multi-factor-authentication) on all Supabase accounts. * [Enforce MFA](https://supabase.com/docs/guides/platform/mfa/org-mfa-enforcement) as a requirement to access the organization * Enabling [Point in Time Recovery](https://supabase.com/docs/guides/platform/backups#point-in-time-recovery) which requires at least a [small compute add-on](https://supabase.com/docs/guides/platform/compute-add-ons) . * Turning on [SSL Enforcement](https://supabase.com/docs/guides/platform/ssl-enforcement) . * Enabling [Network Restrictions](https://supabase.com/docs/guides/platform/network-restrictions) . * Complying with encryption requirements in the HIPAA Security Rule. Data is encrypted at rest and in transit by Supabase. You can consider encrypting the data at your application layer. * Not storing PHI in [public Storage buckets](https://supabase.com/docs/guides/storage/buckets/fundamentals#public-buckets) . * Not [transferring projects](https://supabase.com/docs/guides/platform/project-transfer) to a non-HIPAA organization. For more information on the shared responsibilities and rules under HIPAA, review the [HIPAA compliance responsibilities document](https://supabase.com/docs/guides/security/hipaa-compliance) . ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/deployment/shared-responsibility-model%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/deployment/shared-responsibility-model%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # AI & Vectors | Supabase Docs AI & Vectors AI & Vectors ================ The best vector database is the database you already have. -------------------------------------------------------------- * * * Supabase provides an open source toolkit for developing AI applications using Postgres and pgvector. Use the Supabase client libraries to store, index, and query your vector embeddings at scale. The toolkit includes: * A [vector store](https://supabase.com/docs/guides/ai/vector-columns) and embeddings support using Postgres and pgvector. * A [Python client](https://supabase.com/docs/guides/ai/vecs-python-client) for managing unstructured embeddings. * An [embedding generation](https://supabase.com/docs/guides/ai/quickstarts/generate-text-embeddings) process using open source models directly in Edge Functions. * [Database migrations](https://supabase.com/docs/guides/ai/examples/headless-vector-search#prepare-your-database) for managing structured embeddings. * Integrations with all popular AI providers, such as [OpenAI](https://supabase.com/docs/guides/ai/examples/openai) , [Hugging Face](https://supabase.com/docs/guides/ai/hugging-face) , [LangChain](https://supabase.com/docs/guides/ai/langchain) , and more. Search[#](https://supabase.com/docs/guides/ai#search) ------------------------------------------------------ You can use Supabase to build different types of search features for your app, including: * [Semantic search](https://supabase.com/docs/guides/ai/semantic-search) : search by meaning rather than exact keywords * [Keyword search](https://supabase.com/docs/guides/ai/keyword-search) : search by words or phrases * [Hybrid search](https://supabase.com/docs/guides/ai/hybrid-search) : combine semantic search with keyword search Examples[#](https://supabase.com/docs/guides/ai#examples) ---------------------------------------------------------- Check out all of the AI [templates and examples](https://github.com/supabase/supabase/tree/master/examples/ai) in our GitHub repository. [![Headless Vector Search](https://supabase.com/docs/img/icons/github-icon-light.svg)\ \ Headless Vector Search\ \ A toolkit to perform vector similarity search on your knowledge base embeddings.](https://supabase.com/docs/guides/ai/examples/headless-vector-search) [![Image Search with OpenAI CLIP](https://supabase.com/docs/img/icons/github-icon-light.svg)\ \ Image Search with OpenAI CLIP\ \ Implement image search with the OpenAI CLIP Model and Supabase Vector.](https://supabase.com/docs/guides/ai/examples/image-search-openai-clip) [![Hugging Face inference](https://supabase.com/docs/img/icons/github-icon-light.svg)\ \ Hugging Face inference\ \ Generate image captions using Hugging Face.](https://supabase.com/docs/guides/ai/examples/huggingface-image-captioning) [![OpenAI completions](https://supabase.com/docs/img/icons/github-icon-light.svg)\ \ OpenAI completions\ \ Generate GPT text completions using OpenAI in Edge Functions.](https://supabase.com/docs/guides/ai/examples/openai) [![Building ChatGPT Plugins](https://supabase.com/docs/img/icons/github-icon-light.svg)\ \ Building ChatGPT Plugins\ \ Use Supabase as a Retrieval Store for your ChatGPT plugin.](https://supabase.com/docs/guides/ai/examples/building-chatgpt-plugins) [![Vector search with Next.js and OpenAI](https://supabase.com/docs/img/icons/github-icon-light.svg)\ \ Vector search with Next.js and OpenAI\ \ Learn how to build a ChatGPT-style doc search powered by Next.js, OpenAI, and Supabase.](https://supabase.com/docs/guides/ai/examples/nextjs-vector-search) Integrations[#](https://supabase.com/docs/guides/ai#integrations) ------------------------------------------------------------------ [OpenAI\ \ OpenAI is an AI research and deployment company. Supabase provides a simple way to use OpenAI in your applications.](https://supabase.com/docs/guides/ai/examples/building-chatgpt-plugins) [Amazon Bedrock\ \ A fully managed service that offers a choice of high-performing foundation models from leading AI companies.](https://supabase.com/docs/guides/ai/integrations/amazon-bedrock) [Hugging Face\ \ Hugging Face is an open-source provider of NLP technologies. Supabase provides a simple way to use Hugging Face's models in your applications.](https://supabase.com/docs/guides/ai/hugging-face) [LangChain\ \ LangChain is a language-agnostic, open-source, and self-hosted API for text translation, summarization, and sentiment analysis.](https://supabase.com/docs/guides/ai/langchain) [LlamaIndex\ \ LlamaIndex is a data framework for your LLM applications.](https://supabase.com/docs/guides/ai/integrations/llamaindex) Case studies[#](https://supabase.com/docs/guides/ai#case-studies) ------------------------------------------------------------------ [Berri AI Boosts Productivity by Migrating from AWS RDS to Supabase with pgvector\ \ Learn how Berri AI overcame challenges with self-hosting their vector database on AWS RDS and successfully migrated to Supabase.](https://supabase.com/customers/berriai) [Firecrawl switches from Pinecone to Supabase for PostgreSQL vector embeddings\ \ How Firecrawl boosts efficiency and accuracy of chat powered search for documentation using Supabase with pgvector](https://supabase.com/customers/firecrawl) [Markprompt: GDPR-Compliant AI Chatbots for Docs and Websites\ \ AI-powered chatbot platform, Markprompt, empowers developers to deliver efficient and GDPR-compliant prompt experiences on top of their content, by leveraging Supabase's secure and privacy-focused database and authentication solutions](https://supabase.com/customers/markprompt) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/ai%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/ai%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Production Checklist | Supabase Docs Home Production Checklist ======================== * * * After developing your project and deciding it's production ready, you should run through this checklist to ensure that your project: * [Is secure](https://supabase.com/docs/guides/deployment/going-into-prod#security) * [Won't falter under the expected load](https://supabase.com/docs/guides/deployment/going-into-prod#performance) * [Remains available whilst in production](https://supabase.com/docs/guides/deployment/going-into-prod#availability) Security[#](https://supabase.com/docs/guides/deployment/going-into-prod#security) ---------------------------------------------------------------------------------- Check and review issues in your database using [Security Advisor](https://supabase.com/dashboard/project/_/database/security-advisor) . * Ensure you have enabled row level security (RLS) on all tables from the [**Database > Tables**](https://supabase.com/dashboard/project/_/database/tables) section of the Supabase Dashboard. * Tables that do not have RLS enabled with reasonable policies allow any client to access and modify their data. This is usually not what you want. * [Learn more about RLS](https://supabase.com/docs/guides/database/postgres/row-level-security) . * Enable replication on tables containing sensitive data by enabling RLS and setting row security policies: * Go to the [**Authentication > Policies**](https://supabase.com/dashboard/project/_/auth/policies) section of the Supabase Dashboard to enable RLS and create security policies. * Go to the [**Database > Publications**](https://supabase.com/dashboard/project/_/database/publications) section of the Supabase Dashboard to manage replication tables. * Turn on [SSL Enforcement](https://supabase.com/docs/guides/platform/ssl-enforcement) from the [**Database > Settings > SSL Configuration**](https://supabase.com/dashboard/project/_/database/settings#ssl-configuration) section of the dashboard. * Enable [Network Restrictions](https://supabase.com/docs/guides/platform/network-restrictions) for the database from the [**Database > Settings > Network Restrictions**](https://supabase.com/dashboard/project/_/database/settings#network-restrictions) section of the dashboard. * Ensure that you protect your Supabase Account with multi-factor authentication (MFA). * If using a GitHub sign-in, [enable 2FA on GitHub](https://docs.github.com/en/authentication/securing-your-account-with-two-factor-authentication-2fa/configuring-two-factor-authentication) . * Since your GitHub account gives you administrative rights to your Supabase org, you should protect it with a strong password and 2FA using a U2F key or a TOTP app. * If using email+password sign-in, set up [MFA for your Supabase account](https://supabase.com/docs/guides/platform/multi-factor-authentication#enable-mfa) . * Consider enabling [MFA enforcement on your organization](https://supabase.com/docs/guides/platform/mfa/org-mfa-enforcement) . This ensures all users must have a valid MFA-backed session to interact with organization and project resources. * Consider adding multiple owners on your Supabase org from [the **Organization > Team**](https://supabase.com/dashboard/org/_/team) section of the Supabase Dashboard. This ensures that if one of the owners is unreachable or loses access to their account, you still have Owner access to your org. * Enable email confirmations in the [**Authentication > Providers**](https://supabase.com/dashboard/project/_/auth/providers) section of the dashboard. * Set the expiry in the [**Authentication > Providers**](https://supabase.com/dashboard/project/_/auth/providers) section of the dashboard for one-time passwords (OTPs) to a reasonable value that you are comfortable with. * We recommend setting this to 3600 seconds (1 hour) or lower. * Increase the length of the OTP if you need a higher level of entropy. * If your application requires a higher level of security, consider setting up [multi-factor authentication](https://supabase.com/docs/guides/auth/auth-mfa) (MFA) for your users. * Use a custom SMTP server for auth emails so that your users can see that the mails are coming from a trusted domain (preferably the same domain that your app is hosted on). Grab SMTP credentials from any major email provider such as SendGrid, AWS SES, etc. * Consider how _you_ might abuse your service as an attacker, and take steps to mitigate it. * Review these [common cybersecurity threats](https://auth0.com/docs/security/prevent-threats) . Performance[#](https://supabase.com/docs/guides/deployment/going-into-prod#performance) ---------------------------------------------------------------------------------------- Check and review issues in your database using [Performance Advisor](https://supabase.com/dashboard/project/_/database/performance-advisor) . * Ensure that you have suitable indices to cater to your common query patterns * [Learn more about indexes in Postgres](https://www.enterprisedb.com/postgres-tutorials/overview-postgresql-indexes) . * `pg_stat_statements` can help you [identify hot or slow queries](https://www.virtual-dba.com/blog/postgresql-performance-identifying-hot-and-slow-queries/) . * Perform load testing (preferably on a staging env) * Tools like [k6](https://k6.io/) can simulate traffic from many different users. * Upgrade your database if you require more resources. If you need anything beyond what is listed in [the compute and disk table](https://supabase.com/docs/guides/platform/compute-and-disk) , contact [enterprise@supabase.io](mailto:enterprise@supabase.io) . * If you are expecting a surge in traffic (for a big launch) and are on a Team or Enterprise Plan, [contact support](https://supabase.com/dashboard/support/new) with more details about your launch and we'll help keep an eye on your project. * If you expect your database size to be > 4 GB, enable the Point in Time Recovery (PITR) add-on in the [**Settings > Add-ons**](https://supabase.com/dashboard/project/_/settings/addons?panel=pitr) section of the dashboard. Availability[#](https://supabase.com/docs/guides/deployment/going-into-prod#availability) ------------------------------------------------------------------------------------------ * Use your own SMTP credentials so that you have full control over the deliverability of your transactional auth emails in the [**Authentication > Emails > SMTP Settings**](https://supabase.com/dashboard/project/_/auth/smtp) section of the dashboard. * You can grab SMTP credentials from any major email provider such as SendGrid, AWS SES, etc. Read our [SMTP guide](https://supabase.com/docs/guides/auth/auth-smtp) for more setup details. * The default rate limit for auth emails when using a custom SMTP provider is _30 new users per hour_. If you are doing a major public announcement, you will likely require more than this. * We may pause applications on the Free Plan that exhibit low activity in a 7-day period to save on server resources. * You can restore paused projects from [the Supabase dashboard](https://supabase.com/dashboard/project/_) . * Upgrade to Pro to guarantee that we won't pause your project for inactivity. * Database backups are not available for download for Free Plan projects. * Read [the Database Backups guide](https://supabase.com/docs/guides/platform/backups) for more options and retention details. * If you need a lower recovery point objective (RPO), enable Point-in-Time Recovery (PITR). PITR allows you to back up a project at shorter intervals. This provides users an option to restore to any chosen point in time with second-level granularity. * Supabase Projects use disks that offer 99.8-99.9% durability by default. * Use [Read Replicas](https://supabase.com/docs/guides/platform/read-replicas) if you require availability resilience to a disk failure event * Use PITR if you require durability resilience to a disk failure event * Upgrading to the Supabase Pro Plan gives you [access to our support team](https://supabase.com/dashboard/support/new) . Rate limiting, resource allocation, & abuse prevention[#](https://supabase.com/docs/guides/deployment/going-into-prod#rate-limiting-resource-allocation--abuse-prevention) --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ##### Shared Responsibility Model Running databases is a shared responsibility between you and Supabase. There are some things that we can take care of for you, and some things that you are responsible for. Read more details in our [Shared Responsibility Model guide](https://supabase.com/docs/guides/platform/shared-responsibility-model) . * Supabase employs a number of safeguards against bursts of incoming traffic to prevent abuse and help maximize stability across the platform * If you're on a Team or Enterprise Plan and expect high load events, such as production launches, heavy load testing, or prolonged high resource usage, open a ticket via the [support form](https://supabase.help/) for help. Provide at least 2 weeks notice. ### Auth rate limits[#](https://supabase.com/docs/guides/deployment/going-into-prod#auth-rate-limits) * The table below shows the rate limit quotas on the following authentication endpoints. You can configure the authentication rate limits for your project in the [**Authentication > Rate Limits**](https://supabase.com/dashboard/project/_/auth/rate-limits) section of the dashboard. | Endpoint | Path | Limited By | Rate Limit | | --- | --- | --- | --- | | All endpoints that send emails | `/auth/v1/signup` `/auth/v1/recover` `/auth/v1/user`\[^1\] | Sum of combined requests | As of 3 Sep 2024, this has been updated to 2 emails per hour. You can only change this with your own [custom SMTP setup](https://supabase.com/docs/guides/auth/auth-smtp)
. | | All endpoints that send One-Time-Passwords (OTP) | `/auth/v1/otp` | Sum of combined requests | Defaults to 360 OTPs per hour. Is customizable. | | Send OTPs or magic links | `/auth/v1/otp` | Last request | Defaults to 60 seconds window before a new request is allowed. Is customizable. | | Signup confirmation request | `/auth/v1/signup` | Last request | Defaults to 60 seconds window before a new request is allowed. Is customizable. | | Password Reset Request | `/auth/v1/recover` | Last request | Defaults to 60 seconds window before a new request is allowed. Is customizable. | | Verification requests | `/auth/v1/verify` | IP Address | 360 requests per hour (with bursts up to 30 requests) | | Token refresh requests | `/auth/v1/token` | IP Address | 1800 requests per hour (with bursts up to 30 requests) | | Create or Verify an MFA challenge | `/auth/v1/factors/:id/challenge` `/auth/v1/factors/:id/verify` | IP Address | 15 requests per minute (with bursts up to 30 requests) | | Anonymous sign-ins | `/auth/v1/signup`\[^2\] | IP Address | 30 requests per hour (with bursts up to 30 requests) | ### Realtime limits[#](https://supabase.com/docs/guides/deployment/going-into-prod#realtime-limits) * Review the [Realtime limits](https://supabase.com/docs/guides/realtime/limits) . * If you need limits increased, [contact support](https://supabase.com/dashboard/support/new) . ### Abuse prevention[#](https://supabase.com/docs/guides/deployment/going-into-prod#abuse-prevention) * Supabase provides CAPTCHA protection on the signup, sign-in and password reset endpoints. Read [the Auth CAPTCHA guide](https://supabase.com/docs/guides/auth/auth-captcha) for more details on how to protect against abuse using this method. ### Email link validity[#](https://supabase.com/docs/guides/deployment/going-into-prod#email-link-validity) * When working with enterprise systems, email scanners may scan and make a `GET` request to the reset password link or sign-up link in your email. Since links in Supabase Auth are single-use, a user who opens an email post-scan to click on a link will receive an error. To get around this problem, consider altering the email template to replace the original magic link with a link to a domain you control. The domain can present the user with a "Sign-in" button, which redirects the user to the original magic link URL when clicked. * When using a custom SMTP service, some services might have link tracking enabled which may overwrite or deform the email confirmation links sent by Supabase Auth. To prevent this from happening, we recommend that you disable link tracking when using a custom SMTP service. ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/deployment/going-into-prod%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/deployment/going-into-prod%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Custom Claims & Role-based Access Control (RBAC) | Supabase Docs REST API Custom Claims & Role-based Access Control (RBAC) ==================================================== * * * Custom Claims are special attributes attached to a user that you can use to control access to portions of your application. For example: 1{2 "user_role": "admin",3 "plan": "TRIAL",4 "user_level": 100,5 "group_name": "Super Guild!",6 "joined_on": "2022-05-20T14:28:18.217Z",7 "group_manager": false,8 "items": ["toothpick", "string", "ring"]9} To implement Role-Based Access Control (RBAC) with `custom claims`, use a [Custom Access Token Auth Hook](https://supabase.com/docs/guides/auth/auth-hooks#hook-custom-access-token) . This hook runs before a token is issued. You can use it to add additional claims to the user's JWT. This guide uses the [Slack Clone example](https://github.com/supabase/supabase/tree/master/examples/slack-clone/nextjs-slack-clone) to demonstrate how to add a `user_role` claim and use it in your [Row Level Security (RLS) policies](https://supabase.com/docs/guides/database/postgres/row-level-security) . Create a table to track user roles and permissions[#](https://supabase.com/docs/guides/api/custom-claims-and-role-based-access-control-rbac#create-a-table-to-track-user-roles-and-permissions) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ In this example, you will implement two user roles with specific permissions: * `moderator`: A moderator can delete all messages but not channels. * `admin`: An admin can delete all messages and channels. 1-- Custom types2create type public.app_permission as enum ('channels.delete', 'messages.delete');3create type public.app_role as enum ('admin', 'moderator');45-- USER ROLES6create table public.user_roles (7 id bigint generated by default as identity primary key,8 user_id uuid references auth.users on delete cascade not null,9 role app_role not null,10 unique (user_id, role)11);12comment on table public.user_roles is 'Application roles for each user.';1314-- ROLE PERMISSIONS15create table public.role_permissions (16 id bigint generated by default as identity primary key,17 role app_role not null,18 permission app_permission not null,19 unique (role, permission)20);21comment on table public.role_permissions is 'Application permissions for each role.'; For the [full schema](https://github.com/supabase/supabase/blob/master/examples/slack-clone/nextjs-slack-clone/README.md) , see the example application on [GitHub](https://github.com/supabase/supabase/tree/master/examples/slack-clone/nextjs-slack-clone) . You can now manage your roles and permissions in SQL. For example, to add the mentioned roles and permissions from above, run: 1insert into public.role_permissions (role, permission)2values3 ('admin', 'channels.delete'),4 ('admin', 'messages.delete'),5 ('moderator', 'messages.delete'); Create Auth Hook to apply user role[#](https://supabase.com/docs/guides/api/custom-claims-and-role-based-access-control-rbac#create-auth-hook-to-apply-user-role) ------------------------------------------------------------------------------------------------------------------------------------------------------------------ The [Custom Access Token Auth Hook](https://supabase.com/docs/guides/auth/auth-hooks#hook-custom-access-token) runs before a token is issued. You can use it to edit the JWT. PL/pgSQL (best performance) 1-- Create the auth hook function2create or replace function public.custom_access_token_hook(event jsonb)3returns jsonb4language plpgsql5stable6as $$7 declare8 claims jsonb;9 user_role public.app_role;10 begin11 -- Fetch the user role in the user_roles table12 select role into user_role from public.user_roles where user_id = (event->>'user_id')::uuid;1314 claims := event->'claims';1516 if user_role is not null then17 -- Set the claim18 claims := jsonb_set(claims, '{user_role}', to_jsonb(user_role));19 else20 claims := jsonb_set(claims, '{user_role}', 'null');21 end if;2223 -- Update the 'claims' object in the original event24 event := jsonb_set(event, '{claims}', claims);2526 -- Return the modified or original event27 return event;28 end;29$$;3031grant usage on schema public to supabase_auth_admin;3233grant execute34 on function public.custom_access_token_hook35 to supabase_auth_admin;3637revoke execute38 on function public.custom_access_token_hook39 from authenticated, anon, public;4041grant all42 on table public.user_roles43to supabase_auth_admin;4445revoke all46 on table public.user_roles47 from authenticated, anon, public;4849create policy "Allow auth admin to read user roles" ON public.user_roles50as permissive for select51to supabase_auth_admin52using (true); ### Enable the hook[#](https://supabase.com/docs/guides/api/custom-claims-and-role-based-access-control-rbac#enable-the-hook) In the dashboard, navigate to [`Authentication > Hooks (Beta)`](https://supabase.com/dashboard/project/_/auth/hooks) and select the appropriate Postgres function from the dropdown menu. When developing locally, follow the [local development](https://supabase.com/docs/guides/auth/auth-hooks#local-development) instructions. To learn more about Auth Hooks, see the [Auth Hooks docs](https://supabase.com/docs/guides/auth/auth-hooks) . Accessing custom claims in RLS policies[#](https://supabase.com/docs/guides/api/custom-claims-and-role-based-access-control-rbac#accessing-custom-claims-in-rls-policies) -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- To utilize Role-Based Access Control (RBAC) in Row Level Security (RLS) policies, create an `authorize` method that reads the user's role from their JWT and checks the role's permissions: 1create or replace function public.authorize(2 requested_permission app_permission3)4returns boolean as $$5declare6 bind_permissions int;7 user_role public.app_role;8begin9 -- Fetch user role once and store it to reduce number of calls10 select (auth.jwt() ->> 'user_role')::public.app_role into user_role;1112 select count(*)13 into bind_permissions14 from public.role_permissions15 where role_permissions.permission = requested_permission16 and role_permissions.role = user_role;1718 return bind_permissions > 0;19end;20$$ language plpgsql stable security definer set search_path = ''; You can read more about using functions in RLS policies in the [RLS guide](https://supabase.com/docs/guides/database/postgres/row-level-security#using-functions) . You can then use the `authorize` method within your RLS policies. For example, to enable the desired delete access, you would add the following policies: 1create policy "Allow authorized delete access" on public.channels for delete to authenticated using ( (SELECT authorize('channels.delete')) );2create policy "Allow authorized delete access" on public.messages for delete to authenticated using ( (SELECT authorize('messages.delete')) ); Accessing custom claims in your application[#](https://supabase.com/docs/guides/api/custom-claims-and-role-based-access-control-rbac#accessing-custom-claims-in-your-application) ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- The auth hook will only modify the access token JWT but not the auth response. Therefore, to access the custom claims in your application, e.g. your browser client, or server-side middleware, you will need to decode the `access_token` JWT on the auth session. In a JavaScript client application you can for example use the [`jwt-decode` package](https://www.npmjs.com/package/jwt-decode) : 1import { jwtDecode } from 'jwt-decode'23const { subscription: authListener } = supabase.auth.onAuthStateChange(async (event, session) => {4 if (session) {5 const jwt = jwtDecode(session.access_token)6 const userRole = jwt.user_role7 }8}) For server-side logic you can use packages like [`express-jwt`](https://github.com/auth0/express-jwt) , [`koa-jwt`](https://github.com/stiang/koa-jwt) , [`PyJWT`](https://github.com/jpadilla/pyjwt) , [dart\_jsonwebtoken](https://pub.dev/packages/dart_jsonwebtoken) , [Microsoft.AspNetCore.Authentication.JwtBearer](https://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.JwtBearer) , etc. Conclusion[#](https://supabase.com/docs/guides/api/custom-claims-and-role-based-access-control-rbac#conclusion) ---------------------------------------------------------------------------------------------------------------- You now have a robust system in place to manage user roles and permissions within your database that automatically propagates to Supabase Auth. More resources[#](https://supabase.com/docs/guides/api/custom-claims-and-role-based-access-control-rbac#more-resources) ------------------------------------------------------------------------------------------------------------------------ * [Auth Hooks](https://supabase.com/docs/guides/auth/auth-hooks) * [Row Level Security](https://supabase.com/docs/guides/database/postgres/row-level-security) * [RLS Functions](https://supabase.com/docs/guides/database/postgres/row-level-security#using-functions) * [Next.js Slack Clone Example](https://github.com/supabase/supabase/tree/master/examples/slack-clone/nextjs-slack-clone) ### Is this helpful? No Yes ### AI Tools Copy as Markdown[Ask ChatGPT](https://chatgpt.com/?hint=search&q=Read%20from%20https://supabase.com/docs/guides/api/custom-claims-and-role-based-access-control-rbac%20so%20I%20can%20ask%20questions%20about%20its%20contents) [Ask Claude](https://claude.ai/new?q=Read%20from%20https://supabase.com/docs/guides/api/custom-claims-and-role-based-access-control-rbac%20so%20I%20can%20ask%20questions%20about%20its%20contents) --- # Custom Email Templates | Supabase Docs Self-Hosting Custom Email Templates ========================== Configure custom email templates with self-hosted Supabase instance ----------------------------------------------------------------------- * * * When running a self-hosted Supabase instance, you can fully customize emails sent by Supabase Auth. Overview[#](https://supabase.com/docs/guides/self-hosting/custom-email-templates#overview) ------------------------------------------------------------------------------------------- Supabase Auth does not read email templates from mounted Docker volumes. Instead, it expects each template to be available at a URL that returns a valid HTML template. This URL: * Does not need to be public * Must be reachable from `auth` service * Must return a valid Golang HTML template To provide templates to Supabase Auth, you need a service that serves static HTML files. This can be any server of your choice. You can even use `kong` service which is included with the default Supabase docker configuration. The only requirement is that the `auth` service must be able to reach it via a HTTP GET request. This guide uses [Caddy](https://github.com/caddyserver/caddy) for serving templates. If Supabase Auth cannot fetch the template or if the fetched template is invalid, it falls back to the default template. Authentication email templates[#](https://supabase.com/docs/guides/self-hosting/custom-email-templates#authentication-email-templates) --------------------------------------------------------------------------------------------------------------------------------------- Authentication email templates can be configured using the following environment variables: * `GOTRUE_MAILER_TEMPLATES_`: Provide a custom template URL. Falls back to the default template if not set. * `GOTRUE_MAILER_SUBJECTS_`: Customize the email subject. Falls back to the default subject if not set. | Auth flow | Sent | | --- | --- | | `CONFIRMATION` | When a user signs up and needs to verify their email address | | `RECOVERY` | When a user requests a password reset | | `MAGIC_LINK` | When a user requests a magic link for password-less authentication | | `INVITE` | When a user is invited to join your application via email invitation | | `EMAIL_CHANGE` | When a user requests to change their email address | | `REAUTHENTICATION` | When a user needs to re-authenticate for sensitive operations | For example: 1GOTRUE_MAILER_TEMPLATES_MAGIC_LINK=''2GOTRUE_MAILER_SUBJECTS_MAGIC_LINK='' ### Example[#](https://supabase.com/docs/guides/self-hosting/custom-email-templates#example) Below is an example configuration for setting up a custom invite template. ### Step 1: Create a templates directory[#](https://supabase.com/docs/guides/self-hosting/custom-email-templates#step-1-create-a-templates-directory) Create a `templates` directory inside the existing `volumes` directory and add your email templates to it. Your directory structure should look like this: 1volumes/2 templates/3 invite.html ### Step 2: Update `docker-compose.yml`[#](https://supabase.com/docs/guides/self-hosting/custom-email-templates#step-2-update-docker-composeyml) Update the `auth` service to depend on `templates-server`, and pass the email template environment variables. Then add a `templates-server` service to serve the templates from `./volumes/templates`. 1services:2 auth:3 depends_on:4 db:5 condition: service_healthy6 templates-server: # 👈 new dependency7 condition: service_started8 environment:9 GOTRUE_MAILER_TEMPLATES_INVITE: 'http://templates-server/invite.html'10 GOTRUE_MAILER_SUBJECTS_INVITE: 'You have been invited'1112 templates-server:13 image: caddy:2-alpine14 command: ['caddy', 'file-server', '-r', '/templates', '--listen', ':80']15 volumes:16 - ./volumes/templates:/templates #### What this configuration does[#](https://supabase.com/docs/guides/self-hosting/custom-email-templates#what-this-configuration-does) * Adds a `templates-server`service that runs alongside the Supabase services in the same docker network. * Serves your custom email template files from the `./volumes/templates` directory. * Keeps the templates-server private to the Docker network (no published ports), so it is not accessible from outside. * Allows the `auth` service to fetch templates via `http://templates-server/