diff --git a/apps/docs/content/_partials/ai/quickstart_hf_deployment.mdx b/apps/docs/content/_partials/ai/quickstart_hf_deployment.mdx index 595b1f8f25b..5cd2f61f7aa 100644 --- a/apps/docs/content/_partials/ai/quickstart_hf_deployment.mdx +++ b/apps/docs/content/_partials/ai/quickstart_hf_deployment.mdx @@ -2,4 +2,4 @@ If you have your own infrastructure for deploying Python apps, you can continue to use `vecs` as described in this guide. -Alternatively if you would like to quickly deploy using Supabase, check out our guide on using the [Hugging Face Inference API](/docs/guides/ai/hugging-face) in Edge Functions using TypeScript. +Alternatively if you would like to deploy using Supabase, check out our guide on using the [Hugging Face Inference API](/docs/guides/ai/hugging-face) in Edge Functions using TypeScript. diff --git a/apps/docs/content/_partials/db_pre_request_warning.mdx b/apps/docs/content/_partials/db_pre_request_warning.mdx index 0b61bc21917..5bf6a4fc56a 100644 --- a/apps/docs/content/_partials/db_pre_request_warning.mdx +++ b/apps/docs/content/_partials/db_pre_request_warning.mdx @@ -22,7 +22,7 @@ on todos for select using ( set_information() AND (select auth.uid()) = user_id ); ``` -This ensures the function is called when evaluating RLS policies for all products, not just Data API requests. +This ensures the function is called when evaluating RLS policies for all products, not only Data API requests. **Performance consideration:** diff --git a/apps/docs/content/_partials/kotlin_project_setup.mdx b/apps/docs/content/_partials/kotlin_project_setup.mdx index 91b95ad86ec..546c23d80bb 100644 --- a/apps/docs/content/_partials/kotlin_project_setup.mdx +++ b/apps/docs/content/_partials/kotlin_project_setup.mdx @@ -10,7 +10,7 @@ Before building, you must set up your Database and API with a new Project in Sup ### Set up the database schema -Now we are going to set up the database schema. You can just copy/paste the SQL from below and run it yourself. +Now we are going to set up the database schema. You can copy/paste the SQL from below and run it yourself. diff --git a/apps/docs/content/guides/ai/vector-columns.mdx b/apps/docs/content/guides/ai/vector-columns.mdx index 6ca1aa54955..d9797eed146 100644 --- a/apps/docs/content/guides/ai/vector-columns.mdx +++ b/apps/docs/content/guides/ai/vector-columns.mdx @@ -59,7 +59,7 @@ create table documents ( ); ``` -In the above SQL snippet, we create a `documents` table with a column called `embedding` (note this is just a regular Postgres column - you can name it whatever you like). We give the `embedding` column a `vector` data type with 384 dimensions. Change this to the number of dimensions produced by your embedding model. For example, if you are [generating embeddings](/docs/guides/ai/quickstarts/generate-text-embeddings) using the open source [`gte-small`](https://huggingface.co/Supabase/gte-small) model, you would set this number to 384 since that model produces 384 dimensions. +In the SQL snippet above, we create a `documents` table with an `embedding` column. This is a standard Postgres column, so you can name it anything you like. The `embedding` column uses the `vector` data type with 384 dimensions. Change this number to match the dimensions your embedding model produces. For example, if you're [generating embeddings](/docs/guides/ai/quickstarts/generate-text-embeddings) using the open source [`gte-small`](https://huggingface.co/Supabase/gte-small) model, set this to 384. @@ -73,6 +73,7 @@ In this example we'll generate a vector using Transformers.js, then store it in ```js import { pipeline } from '@huggingface/transformers' + const generateEmbedding = await pipeline('feature-extraction', 'Supabase/gte-small') const title = 'First post!' diff --git a/apps/docs/content/guides/ai/vector-indexes/hnsw-indexes.mdx b/apps/docs/content/guides/ai/vector-indexes/hnsw-indexes.mdx index 420b32fd48e..8ddcb7c0ab0 100644 --- a/apps/docs/content/guides/ai/vector-indexes/hnsw-indexes.mdx +++ b/apps/docs/content/guides/ai/vector-indexes/hnsw-indexes.mdx @@ -110,7 +110,7 @@ The “navigable” part of NSW specifically refers to the ability to logarithmi HNSW combines these two concepts. From the hierarchical perspective, the bottom layer consists of a NSW made up of short links between nodes. Each layer above “skips” elements and creates longer links between nodes further away from each other. -Just like skip lists, search starts at the top layer and works its way down until it finds the target element. However, instead of comparing a scalar value at each layer to determine whether or not to descend to the layer below, a multi-dimensional distance measure (such as Euclidean distance) is used. +Like skip lists, search starts at the top layer and works its way down until it finds the target element. However, instead of comparing a scalar value at each layer to determine whether or not to descend to the layer below, a multi-dimensional distance measure (such as Euclidean distance) is used. ## When should you create HNSW indexes? diff --git a/apps/docs/content/guides/api/handling-errors-in-supabase-js.mdx b/apps/docs/content/guides/api/handling-errors-in-supabase-js.mdx index 3e816f35b86..76c549d3e2c 100644 --- a/apps/docs/content/guides/api/handling-errors-in-supabase-js.mdx +++ b/apps/docs/content/guides/api/handling-errors-in-supabase-js.mdx @@ -4,7 +4,7 @@ title: 'Handling errors in `supabase-js`' subtitle: 'Read `error.hint` first — Postgres often tells you the exact fix. Log the full error so you actually see it.' --- -Every `supabase-js` call returns a `{ data, error }` pair instead of throwing. When something fails, the single most useful field on `error` is usually `hint` — Postgres returns the _fix_, not just a description of the problem. Logging only `error.message` hides it. +Every `supabase-js` call returns a `{ data, error }` pair instead of throwing. When something fails, the single most useful field on `error` is usually `hint` — Postgres returns the _fix_, not only a description of the problem. Logging only `error.message` hides it. ## Usage of `message` and `hint` properties @@ -19,7 +19,7 @@ The `message` exposes the error reason, and `hint` gives you the literal SQL sta The same pattern shows up across many Postgres errors — missing column? `hint` suggests the column name you probably meant. Type mismatch? `hint` shows the expected type. Whenever Postgres knows the fix, it puts it in `hint`. -Log the full `error` object, not just `error.message`. +Log the full `error` object, not only `error.message`. ## The recommended pattern diff --git a/apps/docs/content/guides/auth/auth-anonymous.mdx b/apps/docs/content/guides/auth/auth-anonymous.mdx index 8d1276750bb..0a284cc4c8e 100644 --- a/apps/docs/content/guides/auth/auth-anonymous.mdx +++ b/apps/docs/content/guides/auth/auth-anonymous.mdx @@ -8,7 +8,7 @@ subtitle: 'Create and use anonymous users to authenticate with Supabase' -Calling `signInAnonymously()` creates an anonymous user. It's just like a permanent user, except the user can't access their account if they sign out, clear browsing data, or use another device. +Calling `signInAnonymously()` creates an anonymous user. It behaves like a permanent user, except the user can't access their account if they sign out, clear browsing data, or use another device. Like permanent users, the `authenticated` Postgres role will be used when using the Data APIs to access your project. JWTs for these users will have an `is_anonymous` claim which you can use to distinguish in RLS policies. @@ -279,7 +279,7 @@ response = supabase.auth.link_identity({'provider': 'google'}) ## Access control -An anonymous user assumes the `authenticated` role just like a permanent user. You can use row-level security (RLS) policies to differentiate between an anonymous user and a permanent user by checking for the `is_anonymous` claim in the JWT returned by `auth.jwt()`: +An anonymous user assumes the `authenticated` role like a permanent user. You can use row-level security (RLS) policies to differentiate between an anonymous user and a permanent user by checking for the `is_anonymous` claim in the JWT returned by `auth.jwt()`: ```sql create policy "Only permanent users can post to the news feed" diff --git a/apps/docs/content/guides/auth/auth-hooks/before-user-created-hook.mdx b/apps/docs/content/guides/auth/auth-hooks/before-user-created-hook.mdx index df2b1199cda..c76f9deadf8 100644 --- a/apps/docs/content/guides/auth/auth-hooks/before-user-created-hook.mdx +++ b/apps/docs/content/guides/auth/auth-hooks/before-user-created-hook.mdx @@ -19,7 +19,7 @@ Supabase Auth will send a payload containing these fields to your hook: -Because the hook is ran just before the insertion into the database, this user will not be found in Postgres at the time the hook is called. +Because the hook runs immediately before insertion into the database, this user will not be found in Postgres at the time the hook is called. @@ -722,8 +722,8 @@ supabase functions new before-user-created-hook Add the following code to your edge function: ```ts -import { Webhook } from 'https://esm.sh/standardwebhooks@1.0.0' import { createClient } from 'https://esm.sh/@supabase/supabase-js' +import { Webhook } from 'https://esm.sh/standardwebhooks@1.0.0' const whSecret = Deno.env.get('BEFORE_USER_CREATED_HOOK_SECRET')?.replace('v1,whsec_', '') const supabaseUrl = Deno.env.get('SUPABASE_URL') diff --git a/apps/docs/content/guides/auth/auth-mfa.mdx b/apps/docs/content/guides/auth/auth-mfa.mdx index 542884c5aa8..0c55ea6265e 100644 --- a/apps/docs/content/guides/auth/auth-mfa.mdx +++ b/apps/docs/content/guides/auth/auth-mfa.mdx @@ -271,7 +271,7 @@ It is possible to enforce MFA on the Server-Side Rendering level. However, this You can use the `supabase.auth.mfa.getAuthenticatorAssuranceLevel()` and `supabase.auth.mfa.listFactors()` APIs to identify the AAL level of the session and any factors that are enabled for a user, similar to how you would use these on the browser. -However, encountering a different AAL level on the server may not actually be a security problem. Consider these likely scenarios: +However, encountering a different AAL level on the server may not be a security problem. Consider these likely scenarios: 1. User signed-in with a conventional method but closed their tab on the MFA flow. @@ -284,7 +284,7 @@ We thus recommend you redirect users to a page where they can authenticate using ### APIs -If your application uses the Supabase Database, Storage or Edge Functions, just using Row Level Security policies will give you sufficient protection. In the event that you have other APIs that you wish to protect, follow these general guidelines: +If your application uses the Supabase Database, Storage or Edge Functions, Row Level Security policies provide sufficient protection. In the event that you have other APIs that you wish to protect, follow these general guidelines: 1. **Use a good JWT verification and parsing library for your language.** This will let you securely parse JWTs and extract their claims. diff --git a/apps/docs/content/guides/auth/auth-mfa/phone.mdx b/apps/docs/content/guides/auth/auth-mfa/phone.mdx index 3a123e4a59e..2bf410157f7 100644 --- a/apps/docs/content/guides/auth/auth-mfa/phone.mdx +++ b/apps/docs/content/guides/auth/auth-mfa/phone.mdx @@ -41,7 +41,7 @@ In the **login flow**, the user signs in (upgrading the session to AAL1) and the An enrollment flow provides a UI for users to set up additional authentication factors. Most applications add the enrollment flow in two places within their app: 1. Right after login or sign up. - This allows users quickly set up Multi Factor Authentication (MFA) post login or account creation. Where possible, encourage all users to set up MFA. Many applications offer this as an opt-in step in an + This allows users to set up Multi Factor Authentication (MFA) post login or account creation. Where possible, encourage all users to set up MFA. Many applications offer this as an opt-in step in an effort to reduce onboarding friction. 2. From within a settings page. Allows users to set up, disable or modify their MFA settings. diff --git a/apps/docs/content/guides/auth/auth-mfa/totp.mdx b/apps/docs/content/guides/auth/auth-mfa/totp.mdx index dacae7becca..c45751d91e9 100644 --- a/apps/docs/content/guides/auth/auth-mfa/totp.mdx +++ b/apps/docs/content/guides/auth/auth-mfa/totp.mdx @@ -47,7 +47,7 @@ In the **login flow**, the user signs in (upgrading the session to AAL1) and the An enrollment flow provides a UI for users to set up additional authentication factors. Most applications add the enrollment flow in two places within their app: 1. Right after login or sign up. - This lets users quickly set up MFA immediately after they log in or create an + This lets users set up MFA immediately after they log in or create an account. We recommend encouraging all users to set up MFA if that makes sense for your application. Many applications offer this as an opt-in step in an effort to reduce onboarding friction. diff --git a/apps/docs/content/guides/auth/auth-smtp.mdx b/apps/docs/content/guides/auth/auth-smtp.mdx index b43e261bda7..7ff2e248828 100644 --- a/apps/docs/content/guides/auth/auth-smtp.mdx +++ b/apps/docs/content/guides/auth/auth-smtp.mdx @@ -118,7 +118,7 @@ This includes: **Have another SMTP service set up on stand-by.** -In case the primary SMTP service you're using is experiencing difficulty, or your account is under threat of being blocked due to spam, you have another service to quickly turn to. +In case the primary SMTP service you're using is experiencing difficulty, or your account is under threat of being blocked due to spam, you have another service to turn to. **Use consistent branding and focused content.** diff --git a/apps/docs/content/guides/auth/native-mobile-deep-linking.mdx b/apps/docs/content/guides/auth/native-mobile-deep-linking.mdx index 7b890e169b6..e08ddeb5567 100644 --- a/apps/docs/content/guides/auth/native-mobile-deep-linking.mdx +++ b/apps/docs/content/guides/auth/native-mobile-deep-linking.mdx @@ -120,7 +120,7 @@ With Deep Linking, you can configure this redirect to open a specific page. This - Go to your [auth settings](/dashboard/project/_/auth/url-configuration) page. - You need to enter your app redirect callback on `Additional Redirect URLs` field. - The redirect callback URL should have this format `[YOUR_SCHEME]://[YOUR_HOSTNAME]`. Here, `io.supabase.flutterquickstart://login-callback` is just an example, you can choose whatever you would like for `YOUR_SCHEME` and `YOUR_HOSTNAME` as long as the scheme is unique across the user's device. For this reason, typically a reverse domain of your website is used. + The redirect callback URL should have this format `[YOUR_SCHEME]://[YOUR_HOSTNAME]`. Here, `io.supabase.flutterquickstart://login-callback` is an example. You can choose whatever you would like for `YOUR_SCHEME` and `YOUR_HOSTNAME` as long as the scheme is unique across the user's device. For this reason, typically a reverse domain of your website is used. ![Supabase console deep link setting](/docs/img/deeplink-setting.png) @@ -314,7 +314,7 @@ With Deep Linking, you can configure this redirect to open a specific page. This 1. Go to your [auth settings](/dashboard/project/_/auth/url-configuration) page. 2. Enter your app redirect URL in the `Additional Redirect URLs` field. This is the URL that the user gets redirected to after clicking a magic link. - The redirect callback URL should have the format `[YOUR_SCHEME]://[YOUR_HOSTNAME]`. Here, `io.supabase.user-management://login-callback` is just an example. You can choose whatever you would like for `YOUR_SCHEME` and `YOUR_HOSTNAME` as long as the scheme is unique across the user's device. For this reason, typically a reverse domain of your website is used. + The redirect callback URL should have the format `[YOUR_SCHEME]://[YOUR_HOSTNAME]`. Here, `io.supabase.user-management://login-callback` is an example. You can choose whatever you would like for `YOUR_SCHEME` and `YOUR_HOSTNAME` as long as the scheme is unique across the user's device. For this reason, typically a reverse domain of your website is used. ![Supabase console deep link setting](/docs/img/deeplink-setting.png) @@ -356,7 +356,7 @@ With Deep Linking, you can configure this redirect to open a specific page. This 1. Go to your [auth settings](/dashboard/project/_/auth/url-configuration) page. 2. Enter your app redirect URL in the `Additional Redirect URLs` field. This is the URL that the user gets redirected to after clicking a magic link. - The redirect callback URL should have the format `[YOUR_SCHEME]://[YOUR_HOSTNAME]`. Here, `io.supabase.user-management://login-callback` is just an example. You can choose whatever you would like for `YOUR_SCHEME` and `YOUR_HOSTNAME` as long as the scheme is unique across the user's device. For this reason, typically a reverse domain of your website is used. + The redirect callback URL must have the format `[YOUR_SCHEME]://[YOUR_HOSTNAME]`. For example: `io.supabase.user-management://login-callback`. You can use any values for `YOUR_SCHEME` and `YOUR_HOSTNAME`, but the scheme must be unique across the user's device. For this reason, a reverse domain of your website is typically used. Now, edit the Android manifest to make sure the app opens when the user clicks on the magic link. diff --git a/apps/docs/content/guides/auth/oauth-server.mdx b/apps/docs/content/guides/auth/oauth-server.mdx index 31df7fae5fc..66c7790d320 100644 --- a/apps/docs/content/guides/auth/oauth-server.mdx +++ b/apps/docs/content/guides/auth/oauth-server.mdx @@ -3,7 +3,7 @@ title: 'OAuth 2.1 Server' description: 'Turn your Supabase project into an OAuth 2.1 and OpenID Connect identity provider' --- -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". +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, 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. diff --git a/apps/docs/content/guides/auth/oauth-server/mcp-authentication.mdx b/apps/docs/content/guides/auth/oauth-server/mcp-authentication.mdx index 051892f1ad5..7434553409f 100644 --- a/apps/docs/content/guides/auth/oauth-server/mcp-authentication.mdx +++ b/apps/docs/content/guides/auth/oauth-server/mcp-authentication.mdx @@ -79,13 +79,13 @@ When building your own MCP server, integrate with Supabase Auth to authenticate **Looking for an easier way to build MCP servers?** -[FastMCP](https://gofastmcp.com) provides a streamlined way to build MCP servers with built-in Supabase Auth integration. FastMCP handles OAuth configuration, token management, and authentication flows automatically, letting you focus on building your AI agent's functionality. Check out their [Supabase integration guide](https://gofastmcp.com/integrations/supabase#supabase-fastmcp) to get started quickly. +[FastMCP](https://gofastmcp.com) provides a streamlined way to build MCP servers with built-in Supabase Auth integration. FastMCP handles OAuth configuration, token management, and authentication flows automatically, letting you focus on building your AI agent's functionality. Check out their [Supabase integration guide](https://gofastmcp.com/integrations/supabase#supabase-fastmcp) to get started. ## Handling MCP tokens in your application -When your MCP server makes requests to your Supabase APIs on behalf of authenticated users, it will send access tokens issued by Supabase Auth, just like any other OAuth client. +When your MCP server makes requests to your Supabase APIs on behalf of authenticated users, it will send access tokens issued by Supabase Auth, like any other OAuth client. ### Validating MCP tokens diff --git a/apps/docs/content/guides/auth/signing-keys.mdx b/apps/docs/content/guides/auth/signing-keys.mdx index 771cc541fcc..97518c9618a 100644 --- a/apps/docs/content/guides/auth/signing-keys.mdx +++ b/apps/docs/content/guides/auth/signing-keys.mdx @@ -151,7 +151,7 @@ This guarantee provides your application with close alignment with security comp If you wish to make your own JWTs or have access to the private key or shared secret used by Supabase, you can create a new JWT signing key by importing a private key or setting a shared secret yourself. -Use the [Supabase CLI](/docs/reference/cli/introduction) to quickly and securely generate a private key ready for import: +Use the [Supabase CLI](/docs/reference/cli/introduction) to securely generate a private key ready for import: ```sh supabase gen signing-key --algorithm ES256 @@ -228,7 +228,7 @@ This is to ensure you have the ability, should you need it, to go back to the le ### Why does revoking the legacy JWT secret require disabling of `anon` and `service_role` API keys? -Unfortunately `anon` and `service_role` are not just API keys, but are also valid JSON Web Tokens, signed by the legacy JWT secret. Revoking the legacy JWT secret means that your application no longer trusts any JWT signed with it. Therefore before you revoke the legacy JWT secret, you must disable the `anon` and `service_role` to ensure a consistent security setup. +Unfortunately `anon` and `service_role` are not only API keys, but are also valid JSON Web Tokens, signed by the legacy JWT secret. Revoking the legacy JWT secret means that your application no longer trusts any JWT signed with it. Therefore before you revoke the legacy JWT secret, you must disable the `anon` and `service_role` to ensure a consistent security setup. ### Using JWT-based `anon` key in a mobile, desktop, or CLI application and need to rotate a `service_role` JWT secret? diff --git a/apps/docs/content/guides/auth/social-login/auth-azure.mdx b/apps/docs/content/guides/auth/social-login/auth-azure.mdx index 0189baaad42..7e2a09b236c 100644 --- a/apps/docs/content/guides/auth/social-login/auth-azure.mdx +++ b/apps/docs/content/guides/auth/social-login/auth-azure.mdx @@ -95,7 +95,7 @@ Configure this in the following way: - Select the _App registrations_ menu in Microsoft Entra ID on the Azure portal. - Select the OAuth app. - Select the _Manifest_ menu in the sidebar. -- Make a backup of the JSON just in case. +- Make a backup of the JSON in case you need it later. - Identify the `optionalClaims` key. - Edit it by specifying the following object: ```json diff --git a/apps/docs/content/guides/auth/users.mdx b/apps/docs/content/guides/auth/users.mdx index 52306d68b72..3157bbc88a1 100644 --- a/apps/docs/content/guides/auth/users.mdx +++ b/apps/docs/content/guides/auth/users.mdx @@ -21,7 +21,7 @@ See the [Anonymous Signins guide](/docs/guides/auth/auth-anonymous) to learn mor -Just like permanent users, anonymous users use the **authenticated** role for database access. +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. diff --git a/apps/docs/content/guides/database/extensions/hypopg.mdx b/apps/docs/content/guides/database/extensions/hypopg.mdx index 6bea2618227..6863634ff8b 100644 --- a/apps/docs/content/guides/database/extensions/hypopg.mdx +++ b/apps/docs/content/guides/database/extensions/hypopg.mdx @@ -6,7 +6,7 @@ description: 'Quickly check if an index can be used without creating it.' `HypoPG` is Postgres extension for creating hypothetical/virtual indexes. HypoPG allows users to rapidly create hypothetical/virtual indexes that have no resource cost (CPU, disk, memory) that are visible to the Postgres query planner. -The motivation for HypoPG is to allow users to quickly search for an index to improve a slow query without consuming server resources or waiting for them to build. +The motivation for HypoPG is to allow users to search for an index to improve a slow query without consuming server resources or waiting for them to build. ## Enable the extension diff --git a/apps/docs/content/guides/database/extensions/pgaudit.mdx b/apps/docs/content/guides/database/extensions/pgaudit.mdx index 48c482aa12b..1f6ff73921a 100644 --- a/apps/docs/content/guides/database/extensions/pgaudit.mdx +++ b/apps/docs/content/guides/database/extensions/pgaudit.mdx @@ -193,7 +193,7 @@ You can then assign the role to monitor only approved object events, such as `se grant select on random_table to "some_audit_role"; ``` -With this privilege granted, PGAudit will record all select statements that reference the `random_table`, regardless of _who_ or _what_ actually initiated the event. All assignable privileges can be viewed in the [Postgres documentation](https://www.postgresql.org/docs/current/ddl-priv.html). +With this privilege granted, PGAudit will record all select statements that reference the `random_table`, regardless of _who_ or _what_ initiated the event. All assignable privileges can be viewed in the [Postgres documentation](https://www.postgresql.org/docs/current/ddl-priv.html). If you would no longer like to use object logging, you will need to unassign the `pgaudit.role` variable: diff --git a/apps/docs/content/guides/database/extensions/pgroonga.mdx b/apps/docs/content/guides/database/extensions/pgroonga.mdx index 68bdb78ea77..3e8f135c000 100644 --- a/apps/docs/content/guides/database/extensions/pgroonga.mdx +++ b/apps/docs/content/guides/database/extensions/pgroonga.mdx @@ -124,7 +124,7 @@ id | content ### Match all search words -To find all memos where content contains BOTH of the words `postgres` and `pgroonga`, we can just use space to separate each words: +To find all memos where content contains BOTH of the words `postgres` and `pgroonga`, we can use space to separate each words: {/* prettier-ignore */} ```sql diff --git a/apps/docs/content/guides/database/extensions/plv8.mdx b/apps/docs/content/guides/database/extensions/plv8.mdx index 190cdcf6d24..219f98acc81 100644 --- a/apps/docs/content/guides/database/extensions/plv8.mdx +++ b/apps/docs/content/guides/database/extensions/plv8.mdx @@ -55,7 +55,7 @@ Procedural languages are automatically installed within `pg_catalog`, so you don ## Create `plv8` functions -Functions written in `plv8` are written just like any other Postgres functions, only +Functions written in `plv8` are written like any other Postgres functions, only with the `language` identifier set to `plv8`. ```sql diff --git a/apps/docs/content/guides/database/extensions/postgis.mdx b/apps/docs/content/guides/database/extensions/postgis.mdx index 1e45230f2cf..c02e5f9c9ae 100644 --- a/apps/docs/content/guides/database/extensions/postgis.mdx +++ b/apps/docs/content/guides/database/extensions/postgis.mdx @@ -192,7 +192,7 @@ val data = supabase.from("restaurants").insert(listOf( -Notice the order in which you pass the latitude and longitude. Longitude comes first, and is because longitude represents the x-axis of the location. Another thing to watch for is when inserting data from the client library, there is no comma between the two values, just a single space. +Notice the order in which you pass the latitude and longitude. Longitude comes first, and is because longitude represents the x-axis of the location. Another thing to watch for is when inserting data from the client library, there is no comma between the two values, only a single space. At this point, if you go into your Supabase dashboard and look at the data, you will notice that the value of the `location` column looks something like this. diff --git a/apps/docs/content/guides/database/extensions/wrappers/overview.mdx b/apps/docs/content/guides/database/extensions/wrappers/overview.mdx index 5695f1aa007..867129be896 100644 --- a/apps/docs/content/guides/database/extensions/wrappers/overview.mdx +++ b/apps/docs/content/guides/database/extensions/wrappers/overview.mdx @@ -65,7 +65,7 @@ where ts > (now() - interval '1 DAY'); This approach provides several benefits: -1. **Simplicity:** the Wrappers API is just SQL, so data engineers don't need to learn new tools and languages. +1. **Simplicity:** the Wrappers API is SQL, so data engineers don't need to learn new tools and languages. 1. **Save on time:** avoid setting up additional data pipelines. 1. **Save on Data Engineering costs:** less infrastructure to be managed. diff --git a/apps/docs/content/guides/database/import-data.mdx b/apps/docs/content/guides/database/import-data.mdx index ca2e330b508..0b0262bdc7a 100644 --- a/apps/docs/content/guides/database/import-data.mdx +++ b/apps/docs/content/guides/database/import-data.mdx @@ -5,7 +5,7 @@ title: 'Import data into Supabase' You can import data into Supabase in multiple ways. The best method depends on your data size and app requirements. -If you're working with small datasets in development, you can experiment quickly using CSV import in the Supabase dashboard. If you're working with a large dataset in production, you should plan your data import to minimize app latency and ensure data integrity. +If you're working with small datasets in development, you can experiment with CSV import in the Supabase dashboard. If you're working with a large dataset in production, you should plan your data import to minimize app latency and ensure data integrity. ## How to import data into Supabase diff --git a/apps/docs/content/guides/database/inspect.mdx b/apps/docs/content/guides/database/inspect.mdx index 965e83912a2..490d2f3a3f7 100644 --- a/apps/docs/content/guides/database/inspect.mdx +++ b/apps/docs/content/guides/database/inspect.mdx @@ -250,9 +250,9 @@ Postgres has built in tooling to help you optimize poorly performing queries. Yo explain analyze ; ``` -When you include `analyze` in the explain statement, the database attempts to execute the query and provides a detailed query plan along with actual execution times. So, be careful using `explain analyze` with `insert`/`update`/`delete` queries, because the query will actually run, and could have unintended side-effects. +When you include `analyze` in the explain statement, the database attempts to execute the query and provides a detailed query plan along with actual execution times. So, be careful using `explain analyze` with `insert`/`update`/`delete` queries, because the query will run, and could have unintended side-effects. -If you run just `explain` without the `analyze` keyword, the database will only perform query planning without actually executing the query. This approach can be beneficial when you want to inspect the query plan without affecting the database or if you encounter timeouts in your queries. +If you run `explain` without the `analyze` keyword, the database will only perform query planning without executing the query. This approach can be beneficial when you want to inspect the query plan without affecting the database or if you encounter timeouts in your queries. Using the query plan analyzer to optimize your queries is a large topic, with a number of online resources available: diff --git a/apps/docs/content/guides/database/json.mdx b/apps/docs/content/guides/database/json.mdx index 9d90a37ab70..e4191087163 100644 --- a/apps/docs/content/guides/database/json.mdx +++ b/apps/docs/content/guides/database/json.mdx @@ -23,7 +23,7 @@ Don't go overboard with `json/jsonb` columns. They are a useful tool, but most o ## Create JSONB columns -`json/jsonb` is just another "data type" for Postgres columns. You can create a `jsonb` column in the same way you would create a `text` or `int` column: +`json/jsonb` is another "data type" for Postgres columns. You can create a `jsonb` column in the same way you would create a `text` or `int` column: @@ -31,7 +31,7 @@ For example, assume you have a `posts` table with the following columns: - `created_at` - `updated_at` -You can restrict updates to just the user who created it using [RLS](/docs/guides/auth#row-level-security), with the following policy: +You can restrict updates to the user who created it using [RLS](/docs/guides/auth#row-level-security), with the following policy: ```sql create policy "Allow update for owners" on posts for @@ -66,7 +66,7 @@ update (title, content) on table public.posts to authenticated; ``` -In the above example, we are revoking the table-level `UPDATE` privilege from the `authenticated` role and granting a column-level `UPDATE` privilege on just the `title` and `content` columns. +In the above example, we are revoking the table-level `UPDATE` privilege from the `authenticated` role and granting a column-level `UPDATE` privilege on the `title` and `content` columns. If we want to restrict access to updating the `title` column: diff --git a/apps/docs/content/guides/database/postgres/data-deletion.mdx b/apps/docs/content/guides/database/postgres/data-deletion.mdx index a27ac37074c..eecfd8f66cb 100644 --- a/apps/docs/content/guides/database/postgres/data-deletion.mdx +++ b/apps/docs/content/guides/database/postgres/data-deletion.mdx @@ -47,7 +47,7 @@ delete from logs where created_at < now() - interval '90 days'; ``` -This acquires a `ROW EXCLUSIVE` lock on the table, which still allows other `SELECT`, `INSERT`, `UPDATE`, and `DELETE` statements to run concurrently. For small row counts, the operation completes quickly and has minimal impact. +This acquires a `ROW EXCLUSIVE` lock on the table, which still allows other `SELECT`, `INSERT`, `UPDATE`, and `DELETE` statements to run concurrently. For small row counts, the operation completes with minimal impact. ### Large deletes @@ -188,7 +188,7 @@ If autovacuum is not keeping up, you can trigger a manual vacuum: vacuum (verbose) logs; ``` -For reclaiming disk space (not just marking tuples as reusable), use `VACUUM FULL` — but be aware this rewrites the entire table and takes an `ACCESS EXCLUSIVE` lock: +To reclaim disk space rather than only marking tuples as reusable, use `VACUUM FULL`. Note that this rewrites the entire table and takes an `ACCESS EXCLUSIVE` lock: ```sql -- This locks the table for the duration — use during maintenance windows only diff --git a/apps/docs/content/guides/database/postgres/event-triggers.mdx b/apps/docs/content/guides/database/postgres/event-triggers.mdx index 78da36e91e9..682b7d042a5 100644 --- a/apps/docs/content/guides/database/postgres/event-triggers.mdx +++ b/apps/docs/content/guides/database/postgres/event-triggers.mdx @@ -61,10 +61,10 @@ See how to [auto enable RLS for new tables](/docs/guides/database/postgres/row-l Event triggers can be triggered on: -- `ddl_command_start` - occurs just before a DDL command for almost all objects within a schema -- `ddl_command_end` - occurs just after a DDL command for almost all objects within a schema -- `sql_drop` - occurs just before `ddl_command_end` for any DDL commands that `DROP` a database object (note that altering a table can cause it to be dropped) -- `table_rewrite` - occurs just before a table is rewritten using the `ALTER TABLE` command +- `ddl_command_start` - occurs before a DDL command for almost all objects within a schema +- `ddl_command_end` - occurs after a DDL command for almost all objects within a schema +- `sql_drop` - occurs before `ddl_command_end` for any DDL commands that `DROP` a database object (note that altering a table can cause it to be dropped) +- `table_rewrite` - occurs before a table is rewritten using the `ALTER TABLE` command diff --git a/apps/docs/content/guides/database/postgres/indexes.mdx b/apps/docs/content/guides/database/postgres/indexes.mdx index 3263e5a6e6a..ec1c5a24724 100644 --- a/apps/docs/content/guides/database/postgres/indexes.mdx +++ b/apps/docs/content/guides/database/postgres/indexes.mdx @@ -5,7 +5,7 @@ footerHelpType: 'postgres' tocVideo: 'bBu_V8CfWgM' --- -An index makes your Postgres queries faster. The index is like a "table of contents" for your data - a reference list which allows queries to quickly locate a row in a given table without needing to scan the entire table (which in large tables can take a long time). +An index makes your Postgres queries faster. The index is like a "table of contents" for your data - a reference list which allows queries to locate a row in a given table without needing to scan the entire table (which in large tables can take a long time). Indexes can be structured in a few different ways. The type of index chosen depends on the values you are indexing. By far the most common index type, and the default in Postgres, is the B-Tree. A B-Tree is the generalized form of a binary search tree, where nodes can have more than two children. @@ -67,7 +67,7 @@ Luckily Postgres provides us with `create index concurrently` which prevents blo -Here is a simplified diagram of the index we just created (note that in practice, nodes actually have more than two children). +Here is a simplified diagram of the index we created (note that in practice, nodes have more than two children). B-Tree index example in Postgres diff --git a/apps/docs/content/guides/database/prisma/prisma-troubleshooting.mdx b/apps/docs/content/guides/database/prisma/prisma-troubleshooting.mdx index 4918a182eb2..b9e9ff75b14 100644 --- a/apps/docs/content/guides/database/prisma/prisma-troubleshooting.mdx +++ b/apps/docs/content/guides/database/prisma/prisma-troubleshooting.mdx @@ -72,7 +72,7 @@ Prisma is unable to allocate connections to pending queries fast enough to meet #### Possible causes: [#possible-causes-timed-out-fetching-a-new-connection] - **Overwhelmed server**: The server hosting Prisma is under heavy load, limiting its ability to manage connections. By default, Prisma will create the default `num_cpus * 2 + 1` worth of connections. A common cause for server strain is increasing the `connection_limit` significantly past the default. -- **Insufficient pool size**: The Supavisor pooler does not have enough connections available to quickly satisfy Prisma's requests. +- **Insufficient pool size**: The Supavisor pooler does not have enough connections available to satisfy Prisma's requests. - **Slow queries**: Prisma's queries are taking too long to execute, preventing it from releasing connections for reuse. #### Solutions: [#solution-timed-out-fetching-a-new-connection] @@ -124,7 +124,7 @@ Postgres or Supavisor rejected a request for more connections #### Solutions [#solutions-causes-max-client-connections-reached] - **Transaction Mode for serverless apps**: If you are using serverless functions (Supabase Edge, Vercel, AWS Lambda), switch to transaction mode (port 6543). It handles more connections than session mode or direct connections. -- **Reduce the number of Prisma connections**: A single client-server can establish multiple connections with a pooler. Typically, serverless setups do not need many connections. Starting with fewer, like five or three, or even just one, is often sufficient. In serverless setups, begin with `connection_limit=1`, increasing cautiously if needed to avoid maxing out connections. +- **Reduce the number of Prisma connections**: A single client-server can establish multiple connections with a pooler. Typically, serverless setups do not need many connections. Starting with fewer, like five or three, or even one, is often sufficient. In serverless setups, begin with `connection_limit=1`, increasing cautiously if needed to avoid maxing out connections. - **Increase pool size**: If you are connecting with Supavisor, try increasing the pool size in the [Database Settings](/dashboard/project/_/database/settings). - **Disconnect appropriately**: Close Prisma connections when they are no longer needed. - **Decrease query time**: Reduce query complexity or add [strategic indexes](/docs/guides/database/postgres/indexes) to your tables to speed up queries. diff --git a/apps/docs/content/guides/database/tables.mdx b/apps/docs/content/guides/database/tables.mdx index 2a210617936..f5c20bc080e 100644 --- a/apps/docs/content/guides/database/tables.mdx +++ b/apps/docs/content/guides/database/tables.mdx @@ -579,7 +579,7 @@ from where courses.code != 'PG101'; ``` -Without a view, we would need to go into every dependent query to add the new rule. This would increase in the likelihood of errors and inconsistencies, as well as introducing a lot of effort for a developer. With views, we can alter just the underlying query in the view **transcripts**. The change will be applied to all applications using this view. +Without a view, we would need to go into every dependent query to add the new rule. This would increase in the likelihood of errors and inconsistencies, as well as introducing a lot of effort for a developer. With views, we can alter the underlying query in the view **transcripts**. The change will be applied to all applications using this view. #### Logical organization diff --git a/apps/docs/content/guides/database/vault.mdx b/apps/docs/content/guides/database/vault.mdx index 2a6f0788973..8d703a5d509 100644 --- a/apps/docs/content/guides/database/vault.mdx +++ b/apps/docs/content/guides/database/vault.mdx @@ -127,7 +127,7 @@ You should ensure that you protect access to this view with the appropriate SQL ### Updating secrets -A secret can be updated with the `vault.update_secret()` function, this function makes updating secrets easy, just provide the secret UUID as the first argument, and then an updated secret, updated optional unique name, or updated description: +To update a secret, use the `vault.update_secret()` function. Provide the secret UUID as the first argument, followed by an updated secret, name, or description: ```sql select diff --git a/apps/docs/content/guides/database/webhooks.mdx b/apps/docs/content/guides/database/webhooks.mdx index 3e6a27af497..47496c0c868 100644 --- a/apps/docs/content/guides/database/webhooks.mdx +++ b/apps/docs/content/guides/database/webhooks.mdx @@ -12,7 +12,7 @@ You can hook into three table events: `INSERT`, `UPDATE`, and `DELETE`. All even ## Webhooks vs triggers -Database Webhooks are very similar to triggers, and that's because Database Webhooks are just a convenience wrapper around triggers using the [pg_net](/docs/guides/database/extensions/pgnet) extension. This extension is asynchronous, and therefore will not block your database changes for long-running network requests. +Database Webhooks are very similar to triggers, and that's because Database Webhooks are a convenience wrapper around triggers using the [pg_net](/docs/guides/database/extensions/pgnet) extension. This extension is asynchronous, and therefore will not block your database changes for long-running network requests. This video demonstrates how you can create a new customer in Stripe each time a row is inserted into a `profiles` table: @@ -32,7 +32,7 @@ This video demonstrates how you can create a new customer in Stripe each time a 1. Select the table you want to hook into. 1. Select one or more events (table inserts, updates, or deletes) you want to hook into. -Since webhooks are just database triggers, you can also create one from SQL statement directly. +Since webhooks are database triggers, you can also create one from SQL statement directly. ```sql create trigger "my_webhook" after insert diff --git a/apps/docs/content/guides/deployment/database-migrations.mdx b/apps/docs/content/guides/deployment/database-migrations.mdx index cc2333d0cbe..d50618060c2 100644 --- a/apps/docs/content/guides/deployment/database-migrations.mdx +++ b/apps/docs/content/guides/deployment/database-migrations.mdx @@ -475,13 +475,13 @@ This creates a new migration file capturing the current remote schema. Commit it ### Step 3: If the migration history table is wrong -If a migration shows as missing in the remote history table but the schema change is actually already there (for example, it was applied manually), you can mark it as applied without re-running it: +If a migration shows as missing in the remote history table but the schema change is already there (for example, it was applied manually), you can mark it as applied without re-running it: ```bash name=Terminal supabase migration repair --status applied ``` -Or if a migration is recorded as applied but was never actually run: +Or if a migration is recorded as applied but was never run: ```bash name=Terminal supabase migration repair --status reverted diff --git a/apps/docs/content/guides/functions/background-tasks.mdx b/apps/docs/content/guides/functions/background-tasks.mdx index c893c8227b6..607da02b5b0 100644 --- a/apps/docs/content/guides/functions/background-tasks.mdx +++ b/apps/docs/content/guides/functions/background-tasks.mdx @@ -9,7 +9,7 @@ Edge Function instances can process background tasks outside of the request hand This allows you to: -- Respond quickly to users while processing continues +- Respond to users while processing continues - Handle async operations without blocking the response --- diff --git a/apps/docs/content/guides/functions/deploy.mdx b/apps/docs/content/guides/functions/deploy.mdx index e5ccb12e30d..d1a05e34bf1 100644 --- a/apps/docs/content/guides/functions/deploy.mdx +++ b/apps/docs/content/guides/functions/deploy.mdx @@ -40,7 +40,7 @@ If you haven't yet created a Supabase project, you can do so by visiting [databa -[Link](/docs/reference/cli/usage#supabase-link) your local project to your remote Supabase project using the ID you just retrieved: +[Link](/docs/reference/cli/usage#supabase-link) your local project to your remote Supabase project using the ID you retrieved: ```bash supabase link --project-ref your-project-id diff --git a/apps/docs/content/guides/functions/examples/semantic-search.mdx b/apps/docs/content/guides/functions/examples/semantic-search.mdx index b278fc12503..e2a29dfa470 100644 --- a/apps/docs/content/guides/functions/examples/semantic-search.mdx +++ b/apps/docs/content/guides/functions/examples/semantic-search.mdx @@ -136,4 +136,4 @@ export default { } ``` -You now have AI powered semantic search set up without any external dependencies! Just you, pgvector, and Supabase Edge Functions! +You now have AI powered semantic search set up without any external dependencies! All you need: you, pgvector, and Supabase Edge Functions! diff --git a/apps/docs/content/guides/getting-started/quickstarts/kotlin.mdx b/apps/docs/content/guides/getting-started/quickstarts/kotlin.mdx index bf300112b3f..c1684011415 100644 --- a/apps/docs/content/guides/getting-started/quickstarts/kotlin.mdx +++ b/apps/docs/content/guides/getting-started/quickstarts/kotlin.mdx @@ -74,7 +74,7 @@ hideToc: true You can create a Supabase client whenever you need to perform an API call. - For the sake of simplicity, we will create a client in the `MainActivity.kt` file at the top just below the imports. + For the sake of simplicity, we will create a client in the `MainActivity.kt` file at the top below the imports. Replace the `supabaseUrl` and `supabaseKey` with your own: diff --git a/apps/docs/content/guides/getting-started/quickstarts/redwoodjs.mdx b/apps/docs/content/guides/getting-started/quickstarts/redwoodjs.mdx index 661521fefbc..151e655d6ac 100644 --- a/apps/docs/content/guides/getting-started/quickstarts/redwoodjs.mdx +++ b/apps/docs/content/guides/getting-started/quickstarts/redwoodjs.mdx @@ -178,7 +178,7 @@ hideToc: true - Run the seed database command to populate the `Instrument` table with the instruments you just created. + Run the seed database command to populate the `Instrument` table with the instruments you created. diff --git a/apps/docs/content/guides/getting-started/tutorials/with-flutter.mdx b/apps/docs/content/guides/getting-started/tutorials/with-flutter.mdx index 9f9d8b943f5..19ea149237c 100644 --- a/apps/docs/content/guides/getting-started/tutorials/with-flutter.mdx +++ b/apps/docs/content/guides/getting-started/tutorials/with-flutter.mdx @@ -43,7 +43,7 @@ Run `flutter pub get` to install the dependencies. With dependencies installed, set up deep links. Setting up deep links is required to bring back the user to the app when they click on the magic link to sign in. -We can setup deep links with just a minor tweak on our Flutter application. +We can setup deep links with a minor tweak on our Flutter application. We have to use `io.supabase.flutterquickstart` as the scheme. In this example, we will use `login-callback` as the host for our deep link, but you can change it to whatever you would like. diff --git a/apps/docs/content/guides/getting-started/tutorials/with-nextjs.mdx b/apps/docs/content/guides/getting-started/tutorials/with-nextjs.mdx index f7fd26e7894..bc3467a8f54 100644 --- a/apps/docs/content/guides/getting-started/tutorials/with-nextjs.mdx +++ b/apps/docs/content/guides/getting-started/tutorials/with-nextjs.mdx @@ -53,7 +53,7 @@ You can find the full contents of this file [in the example repository](https:// Next.js is a versatile framework offering pre-rendering at build time (SSG), server-side rendering at request time (SSR), API routes, and proxy edge-functions. -To better integrate with the framework, we've created the `@supabase/ssr` package for Server-Side Auth. It has all the functionalities to quickly configure your Supabase project to use cookies for storing user sessions. Read the [Next.js Server-Side Auth guide](/docs/guides/auth/server-side/creating-a-client?queryGroups=package-manager&package-manager=npm&queryGroups=framework&framework=nextjs) for more information. +To better integrate with the framework, we've created the `@supabase/ssr` package for Server-Side Auth. It has all the functionalities to configure your Supabase project to use cookies for storing user sessions. Read the [Next.js Server-Side Auth guide](/docs/guides/auth/server-side/creating-a-client?queryGroups=package-manager&package-manager=npm&queryGroups=framework&framework=nextjs) for more information. Install the package for Next.js. @@ -216,7 +216,7 @@ lines={[[1, 4], [7, 78], [88, 89], [99, -1]]} meta="name=app/account/account-form.tsx" /> -Create an account page for the `AccountForm` component you just created +Create an account page for the `AccountForm` component you created <$CodeSample path="/user-management/nextjs-user-management/app/account/page.tsx" diff --git a/apps/docs/content/guides/getting-started/tutorials/with-redwoodjs.mdx b/apps/docs/content/guides/getting-started/tutorials/with-redwoodjs.mdx index 7ff85870f22..cb0774b4cd2 100644 --- a/apps/docs/content/guides/getting-started/tutorials/with-redwoodjs.mdx +++ b/apps/docs/content/guides/getting-started/tutorials/with-redwoodjs.mdx @@ -115,7 +115,7 @@ SUPABASE_JWT_SECRET=YOUR_SUPABASE_JWT_SECRET -And finally, you will also need to save **just** the `web side` environment variables to the `redwood.toml`. +And finally, you will also need to save **only** the `web side` environment variables to the `redwood.toml`. <$CodeTabs> @@ -207,7 +207,7 @@ The `/` is important here as it creates a root level route. -You can stop the `dev` server if you want; to see your changes, just be sure to run `yarn rw dev` again. +You can stop the `dev` server if you want; to see your changes, run `yarn rw dev` again. You should see the `Home` page route in `web/src/Routes.js`: diff --git a/apps/docs/content/guides/integrations/vercel-marketplace.mdx b/apps/docs/content/guides/integrations/vercel-marketplace.mdx index 35c554d1695..ac3c21bbf61 100644 --- a/apps/docs/content/guides/integrations/vercel-marketplace.mdx +++ b/apps/docs/content/guides/integrations/vercel-marketplace.mdx @@ -8,7 +8,7 @@ description: 'Manage your Supabase projects directly through Vercel' 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. +When you create an organization and projects through Vercel Marketplace, they function 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. diff --git a/apps/docs/content/guides/local-development/cli/getting-started.mdx b/apps/docs/content/guides/local-development/cli/getting-started.mdx index 8b531f49e4b..c6005edb3c6 100644 --- a/apps/docs/content/guides/local-development/cli/getting-started.mdx +++ b/apps/docs/content/guides/local-development/cli/getting-started.mdx @@ -4,7 +4,7 @@ description: 'The Supabase CLI provides tools to develop your project locally, d subtitle: 'Develop locally, deploy to the Supabase Platform, and set up CI/CD workflows' --- -The Supabase CLI enables you to run the entire Supabase stack locally, on your machine or in a CI environment. With just two commands, you can set up and start a new local project: +The Supabase CLI enables you to run the entire Supabase stack locally, on your machine or in a CI environment. With two commands, you can set up and start a new local project: 1. `supabase init` to create a new local project 2. `supabase start` to launch the Supabase services diff --git a/apps/docs/content/guides/local-development/overview.mdx b/apps/docs/content/guides/local-development/overview.mdx index 708a4d065c0..0c2b6f00169 100644 --- a/apps/docs/content/guides/local-development/overview.mdx +++ b/apps/docs/content/guides/local-development/overview.mdx @@ -7,7 +7,7 @@ video: 'https://www.youtube-nocookie.com/v/vyHyYpvjaks' tocVideo: 'vyHyYpvjaks' --- -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/). +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, 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. diff --git a/apps/docs/content/guides/platform/custom-domains.mdx b/apps/docs/content/guides/platform/custom-domains.mdx index 66f65eb63fb..42173a3fbc9 100644 --- a/apps/docs/content/guides/platform/custom-domains.mdx +++ b/apps/docs/content/guides/platform/custom-domains.mdx @@ -53,7 +53,7 @@ You need to add a CNAME record to your domain's DNS settings to ensure your cust 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. +- Use a low TTL value to propagate changes in case you make a mistake. ### Verify ownership of the domain @@ -73,7 +73,7 @@ Required outstanding validation records: _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. +Add the record to your domains' DNS settings. Make sure to trim surrounding whitespace. Use a low TTL value so you can 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`. diff --git a/apps/docs/content/guides/platform/manage-your-usage/branching.mdx b/apps/docs/content/guides/platform/manage-your-usage/branching.mdx index 774214977f3..64c6f18a4bd 100644 --- a/apps/docs/content/guides/platform/manage-your-usage/branching.mdx +++ b/apps/docs/content/guides/platform/manage-your-usage/branching.mdx @@ -5,7 +5,7 @@ title: 'Manage Branching usage' ## What you are charged for -Each [Preview branch](/docs/guides/deployment/branching) is a separate environment with all Supabase services (Database, Auth, Storage, etc.). You're charged for usage within that environment—such as [Compute](/docs/guides/platform/manage-your-usage/compute), [Disk Size](/docs/guides/platform/manage-your-usage/disk-size), [Egress](/docs/guides/platform/manage-your-usage/egress), and [Storage](/docs/guides/platform/manage-your-usage/storage-size)—just like the project you branched from. +Each [Preview branch](/docs/guides/deployment/branching) is a separate environment with all Supabase services (Database, Auth, Storage, etc.). You're charged for usage within that environment—such as [Compute](/docs/guides/platform/manage-your-usage/compute), [Disk Size](/docs/guides/platform/manage-your-usage/disk-size), [Egress](/docs/guides/platform/manage-your-usage/egress), and [Storage](/docs/guides/platform/manage-your-usage/storage-size)—the same as the project you branched from. diff --git a/apps/docs/content/guides/platform/manage-your-usage/ipv4.mdx b/apps/docs/content/guides/platform/manage-your-usage/ipv4.mdx index a43266ac178..8c004f63755 100644 --- a/apps/docs/content/guides/platform/manage-your-usage/ipv4.mdx +++ b/apps/docs/content/guides/platform/manage-your-usage/ipv4.mdx @@ -117,4 +117,4 @@ If you remove the IPv4 add-on, you are no longer billed from the time of removal ## Optimize usage -To see whether your database actually needs a dedicated IPv4 address, refer to [When you need the IPv4 add-on](/docs/guides/platform/ipv4-address#when-you-need-the-ipv4-add-on). +To see whether your database needs a dedicated IPv4 address, refer to [When you need the IPv4 add-on](/docs/guides/platform/ipv4-address#when-you-need-the-ipv4-add-on). diff --git a/apps/docs/content/guides/platform/manage-your-usage/logs-ingest.mdx b/apps/docs/content/guides/platform/manage-your-usage/logs-ingest.mdx index af40d0e9678..7c26bbc978c 100644 --- a/apps/docs/content/guides/platform/manage-your-usage/logs-ingest.mdx +++ b/apps/docs/content/guides/platform/manage-your-usage/logs-ingest.mdx @@ -65,7 +65,7 @@ Every service in your Supabase project automatically generates Logs — you don' - **Reduce log-level verbosity** in your Edge Functions and server-side code (for example, `info` → `warn` in production). - **Audit verbose logging in your application code.** Application-level logs forwarded to Supabase services count toward ingest. -- **Cap log payload size.** Large structured payloads inflate GB-billed volume quickly. +- **Cap log payload size.** Large structured payloads can inflate GB-billed volume. - **Investigate spikes.** Use the [**Logs Explorer**](/dashboard/project/_/logs-explorer) section of the Dashboard to find services or endpoints producing unusually high volume. ## Exceeding Quotas diff --git a/apps/docs/content/guides/platform/migrating-to-supabase/firestore-data.mdx b/apps/docs/content/guides/platform/migrating-to-supabase/firestore-data.mdx index de95b7aee8b..aafd172a0b4 100644 --- a/apps/docs/content/guides/platform/migrating-to-supabase/firestore-data.mdx +++ b/apps/docs/content/guides/platform/migrating-to-supabase/firestore-data.mdx @@ -124,7 +124,7 @@ module.exports = (collectionName, doc, recordCounters, writeRecord) => { - `writeRecord`: This function automatically handles the process of writing data to other JSON files (useful for "flatting" your document into separate JSON files to be written to separate database tables). `writeRecord` takes the following parameters: - `name`: Name of the JSON file to write to. - `doc`: The document to write to the file. - - `recordCounters`: The same `recordCounters` object that was passed to this hook (just passes it on). + - `recordCounters`: The same `recordCounters` object that was passed to this hook (passes it on). ### Examples diff --git a/apps/docs/content/guides/platform/migrating-to-supabase/heroku.mdx b/apps/docs/content/guides/platform/migrating-to-supabase/heroku.mdx index f361f224f8d..036416e8746 100644 --- a/apps/docs/content/guides/platform/migrating-to-supabase/heroku.mdx +++ b/apps/docs/content/guides/platform/migrating-to-supabase/heroku.mdx @@ -8,7 +8,7 @@ tocVideo: 'xsRhPMphtZ4' Supabase is one of the best [free alternatives to Heroku Postgres](/alternatives/supabase-vs-heroku-postgres). This guide shows how to migrate your Heroku Postgres database to Supabase. This migration requires the [pg_dump](https://www.postgresql.org/docs/current/app-pgdump.html) and [psql](https://www.postgresql.org/docs/current/app-psql.html) CLI tools, which are installed automatically as part of the complete Postgres installation package. -Alternatively, use the [Heroku to Supabase migration tool](https://migrate.supabase.com/) to migrate in just a few clicks. +Alternatively, use the [Heroku to Supabase migration tool](https://migrate.supabase.com/) to migrate in a few clicks. ## Quick demo diff --git a/apps/docs/content/guides/platform/performance.mdx b/apps/docs/content/guides/platform/performance.mdx index 0c75a8d30fb..b95198471ff 100644 --- a/apps/docs/content/guides/platform/performance.mdx +++ b/apps/docs/content/guides/platform/performance.mdx @@ -31,7 +31,7 @@ In such a scenario, you can consider: 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](../telemetry/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](/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. +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](/docs/guides/database/connecting-to-postgres#connection-pooler) instead. Transient workflows, which can scale up and down rapidly 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 diff --git a/apps/docs/content/guides/platform/privatelink.mdx b/apps/docs/content/guides/platform/privatelink.mdx index 4e602ed56cc..d3417eb68a5 100644 --- a/apps/docs/content/guides/platform/privatelink.mdx +++ b/apps/docs/content/guides/platform/privatelink.mdx @@ -26,7 +26,7 @@ Supabase PrivateLink is an organisation level configuration. It works by sharing 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. +Supabase PrivateLink currently supports 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 diff --git a/apps/docs/content/guides/platform/read-replicas.mdx b/apps/docs/content/guides/platform/read-replicas.mdx index 12133addca9..c70ecea0044 100644 --- a/apps/docs/content/guides/platform/read-replicas.mdx +++ b/apps/docs/content/guides/platform/read-replicas.mdx @@ -43,7 +43,7 @@ You can only read data from a Read Replica. This is in contrast to a Primary dat id="rr-flow" > - When your database starts slowing down, you face a choice: make your existing database bigger (scale vertically), or spread the load across multiple databases (scale horizontally). Both approaches work. Neither is universally correct. The right answer depends on your workload, your budget, and where the bottleneck actually is. + When your database starts slowing down, you face a choice: make your existing database bigger (scale vertically), or spread the load across multiple databases (scale horizontally). Both approaches work. Neither is universally correct. The right answer depends on your workload, your budget, and where the bottleneck is. ```mermaid flowchart TD diff --git a/apps/docs/content/guides/platform/sso.mdx b/apps/docs/content/guides/platform/sso.mdx index 9a690a703e7..2349a28d27c 100644 --- a/apps/docs/content/guides/platform/sso.mdx +++ b/apps/docs/content/guides/platform/sso.mdx @@ -74,7 +74,7 @@ Users start their login at supabase.com by entering their email address, then ar - **Login flows** - Choose between IdP-initiated (users start from identity provider), SP-initiated (users start at supabase.com), or both. IdP-initiated is recommended for most organizations and requires no domain configuration. See [Choosing the Right Login Flow](/docs/guides/platform/sso/choosing-login-flow) for guidance. - **Email domains** - Required only if you enable SP-initiated login. You can associate one or more email domains with your SSO provider. Users with matching email addresses can sign in via SSO at supabase.com. Not required for IdP-initiated flow. -- **Auto-join** - Optionally allow users with a matching domain to be added to your organization automatically when they sign in via SSO. Auto-join applies on every login, not just first signup, making it easy to test before enabling. +- **Auto-join** - Optionally allow users with a matching domain to join your organization automatically when they sign in via SSO. This applies on every login, not only on first signup. - **Default role for auto-joined users** - Choose the role (e.g., `Read-only`, `Developer`, `Administrator`, `Owner`) that automatically joined users receive. We recommend using `Developer` as the default (principle of least privilege) and promoting users individually as needed. Refer to [access control](/docs/guides/platform/access-control) for more information about roles. - **Invitation types** - When inviting users to your organization, you can explicitly choose whether the invitation requires SSO authentication or allows non-SSO login (password/social). This enables mixed authentication organizations with both SSO and non-SSO users. diff --git a/apps/docs/content/guides/platform/sso/azure.mdx b/apps/docs/content/guides/platform/sso/azure.mdx index 62d0a7ef3eb..6daa75a6f94 100644 --- a/apps/docs/content/guides/platform/sso/azure.mdx +++ b/apps/docs/content/guides/platform/sso/azure.mdx @@ -64,7 +64,7 @@ First you need to download Supabase's SAML metadata file. Click the button below Alternatively, visit this page to initiate a download: `https://alt.supabase.io/auth/v1/sso/saml/metadata?download=true` -Click on the _Upload metadata file_ option in the toolbar and select the file you just downloaded. +Click on the _Upload metadata file_ option in the toolbar and select the file you downloaded. ![Azure AD console: Supabase application, SAML-based Sign-on screen, selected Upload metadata file button](/docs/img/sso-azure-step-06-1.png) @@ -134,7 +134,7 @@ By default this setting is disabled, users logging in via SSO will not be added ![Auto-join disabled](/docs/img/sso-dashboard-configure-autojoin-disabled.png) -Toggle this on if you want SSO-authenticated users to be **automatically added to your organization** when they log in via SSO. Auto-join applies on **every login**, not just first signup - this makes it safe to test SSO before enabling this feature. +Toggle this on if you want SSO-authenticated users to be **automatically added to your organization** when they log in via SSO. Auto-join applies on **every login**, not only on first signup - this makes it safe to test SSO before enabling this feature. ![Auto-join enable](/docs/img/sso-dashboard-configure-autojoin-enabled.png) diff --git a/apps/docs/content/guides/platform/sso/gsuite.mdx b/apps/docs/content/guides/platform/sso/gsuite.mdx index 4babba24020..608d8f03d0c 100644 --- a/apps/docs/content/guides/platform/sso/gsuite.mdx +++ b/apps/docs/content/guides/platform/sso/gsuite.mdx @@ -144,7 +144,7 @@ By default this setting is disabled, users logging in via SSO will not be added ![Auto-join disabled](/docs/img/sso-dashboard-configure-autojoin-disabled.png) -Toggle this on if you want SSO-authenticated users to be **automatically added to your organization** when they log in via SSO. Auto-join applies on **every login**, not just first signup - this makes it safe to test SSO before enabling this feature. +Toggle this on if you want SSO-authenticated users to be **automatically added to your organization** when they log in via SSO. Auto-join applies on **every login**, not only on first signup - this makes it safe to test SSO before enabling this feature. ![Auto-join enable](/docs/img/sso-dashboard-configure-autojoin-enabled.png) diff --git a/apps/docs/content/guides/platform/sso/okta.mdx b/apps/docs/content/guides/platform/sso/okta.mdx index 370b410872a..b62cd6588ab 100644 --- a/apps/docs/content/guides/platform/sso/okta.mdx +++ b/apps/docs/content/guides/platform/sso/okta.mdx @@ -130,7 +130,7 @@ By default this setting is disabled, users logging in via SSO will not be added ![Auto-join disabled](/docs/img/sso-dashboard-configure-autojoin-disabled.png) -Toggle this on if you want SSO-authenticated users to be **automatically added to your organization** when they log in via SSO. Auto-join applies on **every login**, not just first signup - this makes it safe to test SSO before enabling this feature. +Toggle this on if you want SSO-authenticated users to be **automatically added to your organization** when they log in via SSO. Auto-join applies on **every login**, not only on first signup - this makes it safe to test SSO before enabling this feature. ![Auto-join enable](/docs/img/sso-dashboard-configure-autojoin-enabled.png) diff --git a/apps/docs/content/guides/platform/sso/testing-best-practices.mdx b/apps/docs/content/guides/platform/sso/testing-best-practices.mdx index f9c4a5de033..a85c237a688 100644 --- a/apps/docs/content/guides/platform/sso/testing-best-practices.mdx +++ b/apps/docs/content/guides/platform/sso/testing-best-practices.mdx @@ -180,7 +180,7 @@ Test with 2-3 additional users to verify: -**Recent improvement:** Auto-join now applies on EVERY login, not just first signup. This resolves a common issue where org owners would test with auto-join disabled, enable it, then log in again expecting to auto-join. +**Recent improvement:** Auto-join now applies on EVERY login, not only on first signup. This resolves a common issue where org owners would test with auto-join disabled, enable it, then log in again expecting to auto-join. @@ -253,7 +253,7 @@ Test with 2-3 additional users to verify: - Auto-join works when enabled - Users receive correct default role - Non-matching domains are excluded (if using SP-initiated with domains) -- Existing users auto-join on their next login (not just new signups) +- Existing users auto-join on their next login (not only on new signups) - Auto-join can be disabled and re-enabled as needed - Auto-join is idempotent (no duplicate memberships) - Auto-join works with IdP-initiated only (no domains) @@ -369,7 +369,7 @@ SSO accounts have specific restrictions to prevent accidental organization locko - SSO accounts CAN disable SSO providers - Non-SSO owners CAN delete SSO providers - Error messages clearly explain the restriction -- Restriction applies to all SSO accounts (not just certain roles) +- Restriction applies to all SSO accounts (not only certain roles) ## Common issues and troubleshooting @@ -387,7 +387,7 @@ Based on customer pain points that previously required support intervention: **Solution:** -- Auto-join now applies on **every login**, not just first signup +- Auto-join now applies on **every login**, not only on first signup - To test: Enable auto-join, log out completely, log back in via SSO - If still not working, verify domain configuration matches user email exactly @@ -795,7 +795,7 @@ Before rolling out SSO to your organization: - Auto-join adds users to correct organization (if enabled) - Auto-joined users receive correct default role -- Auto-join works on first login (not just signup) +- Auto-join works on first login (not only on signup) - Existing users auto-join when feature enabled - Auto-join is idempotent (no duplicate memberships) - Auto-join works with IdP-initiated (no domains required) diff --git a/apps/docs/content/guides/queues/pgmq.mdx b/apps/docs/content/guides/queues/pgmq.mdx index 6b7f85d8cb5..caca4f8a191 100644 --- a/apps/docs/content/guides/queues/pgmq.mdx +++ b/apps/docs/content/guides/queues/pgmq.mdx @@ -6,7 +6,7 @@ pgmq is a lightweight message queue built on Postgres. ## Features -- Lightweight - No background worker or external dependencies, just Postgres functions packaged in an extension +- Lightweight - No background worker or external dependencies, only Postgres functions packaged in an extension - "exactly once" delivery of messages to a consumer within a visibility timeout - API parity with AWS SQS and RSMQ - Messages stay in the queue until explicitly removed diff --git a/apps/docs/content/guides/realtime/architecture.mdx b/apps/docs/content/guides/realtime/architecture.mdx index cbf6b59737f..0d0b0aee9b6 100644 --- a/apps/docs/content/guides/realtime/architecture.mdx +++ b/apps/docs/content/guides/realtime/architecture.mdx @@ -44,7 +44,7 @@ Broadcast lets you send a message from any connected client to a Channel. Any ot 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. +Broadcast is useful for getting messages to users in the same location rapidly. 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. diff --git a/apps/docs/content/guides/realtime/presence.mdx b/apps/docs/content/guides/realtime/presence.mdx index 5618cce8863..2cecc485a81 100644 --- a/apps/docs/content/guides/realtime/presence.mdx +++ b/apps/docs/content/guides/realtime/presence.mdx @@ -30,7 +30,7 @@ For high-frequency or fire-and-forget updates, use [Broadcast](/docs/guides/real -During a `sync` event, you may receive `join` and `leave` events simultaneously, even though no users are actually joining or leaving. This is expected behavior—Presence reconciles its local state with the server state, which can trigger these events as part of the synchronization process. This reflects state reconciliation, not real user movement. +During a `sync` event, you may receive `join` and `leave` events simultaneously, even though no users are joining or leaving. This is expected behavior—Presence reconciles its local state with the server state, which can trigger these events as part of the synchronization process. This reflects state reconciliation, not real user movement. diff --git a/apps/docs/content/guides/realtime/protocol.mdx b/apps/docs/content/guides/realtime/protocol.mdx index 05c524e642b..d934f32a45e 100644 --- a/apps/docs/content/guides/realtime/protocol.mdx +++ b/apps/docs/content/guides/realtime/protocol.mdx @@ -413,7 +413,7 @@ user-event // User Event } ``` -The payload encoding is just a hint for the client to know if the payload should be treated as JSON or not. +The payload encoding is a hint for the client to know if the payload should be treated as JSON or not. {/* supa-mdx-lint-disable-next-line Rule001HeadingCase */} @@ -667,7 +667,7 @@ message // User Event } ``` -The metadata field is JSON encoded. The payload encoding is just a hint for the client to know if the payload should be treated as JSON or not. +The metadata field is JSON encoded. The payload encoding is a hint for the client to know if the payload should be treated as JSON or not. {/* supa-mdx-lint-disable-next-line Rule001HeadingCase */} @@ -962,7 +962,7 @@ When `ack` is `true`, the server replies on error with `response.error` (an atom { "status": "error", "response": { "error": "payload_size_exceeded" } } ``` -Note that the JS client (`send()`) resolves to just the string `'error'` and does not expose the specific `error` atom to callers. +Note that the JS client (`send()`) resolves to the string `'error'` and does not expose the specific `error` atom to callers. ### Presence errors diff --git a/apps/docs/content/guides/realtime/reports.mdx b/apps/docs/content/guides/realtime/reports.mdx index b17d012ecf2..23b10880524 100644 --- a/apps/docs/content/guides/realtime/reports.mdx +++ b/apps/docs/content/guides/realtime/reports.mdx @@ -157,7 +157,7 @@ height={625} ## Rate of Channel Joins -The Rate of Channel Joins report helps you monitor how quickly clients are joining Realtime channels over time. This metric is essential for understanding your application's channel subscription patterns and identifying when you're approaching your plan's channel join rate limits. +The Rate of Channel Joins report helps you monitor how fast clients are joining Realtime channels over time. This metric is essential for understanding your application's channel subscription patterns and identifying when you're approaching your plan's channel join rate limits. The report displays the rate of channel joins per second, showing how frequently clients subscribe to channels throughout the selected time period. A channel join occurs whenever a client subscribes to a channel topic to receive real-time updates. Each client connection can join multiple channels (up to 100 per connection for most plans), and the join rate measures how many of these subscriptions happen per second across your entire project. @@ -377,7 +377,7 @@ height={645} The Response Speed report helps you monitor the average response time for HTTP requests to the Realtime service over time. This metric is essential for understanding API performance, identifying latency issues, and ensuring your real-time features meet performance expectations. -The report displays the average response time in milliseconds, showing how quickly the Realtime service responds to HTTP requests throughout the selected time period. This includes response times for REST API requests such as broadcast messages, WebSocket upgrade requests, and other HTTP-based interactions. Higher response times can indicate performance bottlenecks, database load issues, or network problems that may impact the real-time responsiveness of your application. +The report displays the average response time in milliseconds, showing how fast the Realtime service responds to HTTP requests throughout the selected time period. This includes response times for REST API requests such as broadcast messages, WebSocket upgrade requests, and other HTTP-based interactions. Higher response times can indicate performance bottlenecks, database load issues, or network problems that may impact the real-time responsiveness of your application. Response Speed chart @@ -38,7 +38,7 @@ A committed lockfile is the floor, not the ceiling. - Commit `package-lock.json`, `pnpm-lock.yaml`, `yarn.lock`, or `bun.lock`. - In CI, install with `npm ci` / `pnpm install --frozen-lockfile` / `yarn install --immutable` / `bun install --frozen-lockfile`. These fail if `package.json` and the lockfile disagree, which is what you want. -- Caret ranges (`^1.2.3`) in `package.json` are fine **if** you also have a lockfile and the rest of the guidance below — the lockfile is what actually gets installed. +- Caret ranges (`^1.2.3`) in `package.json` are fine **if** you also have a lockfile and the rest of the guidance below — the lockfile is what gets installed. **Pin transitive risk with overrides.** If you don't trust a particular transitive dep version, force a known-good version via: @@ -102,7 +102,7 @@ npmPreapprovedPackages: # opt specific packages out of all package gates - '@your-org/*' ``` -Versions newer than the gate are excluded from resolution. Yarn's docs also note this guards against the npm registry's 72-hour unpublish window — a package you just installed could vanish, breaking your build, if you don't wait it out. +Versions newer than the gate are excluded from resolution. Yarn's docs also note this guards against the npm registry's 72-hour unpublish window — a package you recently installed could vanish, breaking your build, if you don't wait it out. Two related yarn settings worth knowing about while you're in `.yarnrc.yml`: @@ -141,7 +141,7 @@ Or per-command: bun add @supabase/supabase-js --minimum-release-age 604800 ``` -Bun's age gate only affects new resolutions — existing entries in `bun.lock` are unchanged. It also runs a stability check: if multiple versions were published close together just outside your gate, Bun extends the filter to skip those (likely unstable) versions and picks an older, more mature one. Exact-version requests (`pkg@1.1.1`) respect the gate but bypass the stability extension. +Bun's age gate only affects new resolutions — existing entries in `bun.lock` are unchanged. It also runs a stability check: if multiple versions were published close together outside your gate, Bun extends the filter to skip those (likely unstable) versions and picks an older, more mature one. Exact-version requests (`pkg@1.1.1`) respect the gate but bypass the stability extension. For Deno-based Edge Functions, see the [Edge Functions specifics](#edge-functions-specifics) section below. @@ -230,7 +230,7 @@ Corepack (bundled with modern Node) and `pnpm/action-setup@v6+` both read this f ## Prune unused dependencies -Every dependency you don't actually need is attack surface you don't actually need. Two cheap habits: +Every dependency you don't need is attack surface you don't need. Two cheap habits: - Periodically run `npx depcheck` (or the equivalent for your stack) and remove dependencies that aren't imported anywhere. - Look at your direct dependencies when a CVE lands. Is the dep doing something you could do in 20 lines yourself? Some of the most-exploited packages are tiny utilities that became transitive footguns. @@ -267,7 +267,7 @@ Talk to the Supabase Functions team if your security posture depends on a featur ## If you suspect you installed a compromised version -Move quickly. Order of operations: +Act promptly. Order of operations: 1. **Treat the install host as potentially compromised.** Anything readable by the user that ran the install — env vars, files, secrets in memory — should be assumed stolen. 2. **Rotate credentials reachable from that host**: cloud provider keys (AWS, GCP, Azure), Kubernetes / Vault tokens, GitHub tokens, npm tokens, SSH keys, and any Supabase service-role keys or anon keys that touched the box. diff --git a/apps/docs/content/guides/self-hosting/docker.mdx b/apps/docs/content/guides/self-hosting/docker.mdx index 348cc44558e..aede885d840 100644 --- a/apps/docs/content/guides/self-hosting/docker.mdx +++ b/apps/docs/content/guides/self-hosting/docker.mdx @@ -336,7 +336,7 @@ For transaction-mode connections: psql 'postgres://postgres.[POOLER_TENANT_ID]:[POSTGRES_PASSWORD]@[your-domain]:6543/postgres' ``` -When using `psql` with command-line parameters instead of a connection string to connect to Supavisor, the `-U` parameter should also be `postgres.[POOLER_TENANT_ID]`, and not just `postgres`. +When using `psql` with command-line parameters instead of a connection string to connect to Supavisor, the `-U` parameter should also be `postgres.[POOLER_TENANT_ID]`. If you need to configure Postgres to be directly accessible from the Internet, read [Exposing your Postgres database](#exposing-your-postgres-database). diff --git a/apps/docs/content/guides/self-hosting/self-hosted-functions.mdx b/apps/docs/content/guides/self-hosting/self-hosted-functions.mdx index cfec33dc403..7ab4da3df8b 100644 --- a/apps/docs/content/guides/self-hosting/self-hosted-functions.mdx +++ b/apps/docs/content/guides/self-hosting/self-hosted-functions.mdx @@ -199,7 +199,7 @@ For more details, see: ### 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/`. +The request URL must include the function name after `/functions/v1/`. For example, `/functions/v1/hello`. ### 500 error on invocation @@ -230,7 +230,7 @@ docker compose restart functions --no-deps - 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`: +Use the following command to recreate the container: ```sh docker compose up -d --force-recreate --no-deps functions diff --git a/apps/docs/content/guides/self-hosting/self-hosted-phone-mfa.mdx b/apps/docs/content/guides/self-hosting/self-hosted-phone-mfa.mdx index 6f140fb0565..5e2d658cd42 100644 --- a/apps/docs/content/guides/self-hosting/self-hosted-phone-mfa.mdx +++ b/apps/docs/content/guides/self-hosting/self-hosted-phone-mfa.mdx @@ -170,7 +170,7 @@ MFA_MAX_ENROLLED_FACTORS=5 ## Troubleshooting -### OTP expires too quickly +### OTP expires too soon The default `SMS_OTP_EXP` is 60 seconds. Increase it in `.env`: diff --git a/apps/docs/content/guides/storage/cdn/smart-cdn.mdx b/apps/docs/content/guides/storage/cdn/smart-cdn.mdx index df408ce497e..802b481d9e7 100644 --- a/apps/docs/content/guides/storage/cdn/smart-cdn.mdx +++ b/apps/docs/content/guides/storage/cdn/smart-cdn.mdx @@ -39,7 +39,7 @@ For instance, you can use a URL like `/storage/v1/object/sign/profile-pictures/c ## Signed URLs and CDN caching -Signed URLs are the primary way to serve assets from private buckets to end users. With Smart CDN enabled, signed URL responses are cached at the CDN edge, just like any other storage request. +Signed URLs are the primary way to serve assets from private buckets to end users. With Smart CDN enabled, signed URL responses are cached at the CDN edge, like any other storage request. Unlike public bucket URLs, each signed URL contains a unique token query parameter (`?token=...`). Smart CDN treats each unique token as a separate cache key, meaning the first request with any given signed URL results in a cache miss, and only subsequent requests using that exact same URL will receive a cache hit. Two different signed URLs for the same object, even if generated seconds apart, each maintain their own independent cache entry. diff --git a/apps/docs/content/guides/storage/quickstart.mdx b/apps/docs/content/guides/storage/quickstart.mdx index 8a8f781e640..18175bee714 100644 --- a/apps/docs/content/guides/storage/quickstart.mdx +++ b/apps/docs/content/guides/storage/quickstart.mdx @@ -19,7 +19,7 @@ Files can be any sort of media file. This includes images, GIFs, and videos. It ### 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. +Folders are a way to organize your files (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 diff --git a/apps/docs/content/guides/storage/schema/custom-roles.mdx b/apps/docs/content/guides/storage/schema/custom-roles.mdx index 5edc3802f40..889e257d4bb 100644 --- a/apps/docs/content/guides/storage/schema/custom-roles.mdx +++ b/apps/docs/content/guides/storage/schema/custom-roles.mdx @@ -39,7 +39,7 @@ using ( ## Test the policy To impersonate the `manager` role, you will need a valid JWT token with the `manager` role. -You can quickly create one using the `jsonwebtoken` library in Node.js. +You can create one using the `jsonwebtoken` library in Node.js. diff --git a/apps/docs/content/guides/storage/security/ownership.mdx b/apps/docs/content/guides/storage/security/ownership.mdx index 10f724d6841..dd0d6aa8ae2 100644 --- a/apps/docs/content/guides/storage/security/ownership.mdx +++ b/apps/docs/content/guides/storage/security/ownership.mdx @@ -36,4 +36,4 @@ using ( ); ``` -The use of RLS policies is just one way to enforce access control. You can also implement access control in your server code by following the same pattern. +The use of RLS policies is one way to enforce access control. You can also implement access control in your server code by following the same pattern. diff --git a/apps/docs/content/troubleshooting/disabling-prepared-statements-qL8lEL.mdx b/apps/docs/content/troubleshooting/disabling-prepared-statements-qL8lEL.mdx index bddc58bf5f7..c9741c78913 100644 --- a/apps/docs/content/troubleshooting/disabling-prepared-statements-qL8lEL.mdx +++ b/apps/docs/content/troubleshooting/disabling-prepared-statements-qL8lEL.mdx @@ -31,7 +31,7 @@ export const client = postgres(connectionString, { prepare: false }) ## Node Postgres -[Just omit the "name" value in a query definition](https://node-postgres.com/features/queries#prepared-statements): +[Omit the "name" value in a query definition](https://node-postgres.com/features/queries#prepared-statements): ```ts const query = { diff --git a/apps/docs/content/troubleshooting/edge-function-500-error-response.mdx b/apps/docs/content/troubleshooting/edge-function-500-error-response.mdx index c28c5761e0f..2351c1cb1e0 100644 --- a/apps/docs/content/troubleshooting/edge-function-500-error-response.mdx +++ b/apps/docs/content/troubleshooting/edge-function-500-error-response.mdx @@ -123,7 +123,7 @@ const some_num = 5 some_num() // TypeError: some_num is not a function ``` -This issue often appears when working with returned objects from external APIs. One may assume a response has a certain shape, but if the value is actually `null` or `undefined`, using it without checking can lead to a `TypeError`. +This issue often appears when working with returned objects from external APIs. One may assume a response has a certain shape, but if the value is `null` or `undefined`, using it without checking can lead to a `TypeError`. ```js const data = await req.json() // returns undefined if request body is empty @@ -277,7 +277,7 @@ if (req.method === 'OPTIONS') { } ``` -So, when encountering these errors, it is still important to check the logs or run the request outside the browser to make sure it is actually the primary factor and not a side-effect of a larger issue. +So, when encountering these errors, it is still important to check the logs or run the request outside the browser to make sure it is the primary factor and not a side-effect of a larger issue. ## Still stuck? diff --git a/apps/docs/content/troubleshooting/edge-function-546-error-response.mdx b/apps/docs/content/troubleshooting/edge-function-546-error-response.mdx index cc869fa405a..9f4b12e25d0 100644 --- a/apps/docs/content/troubleshooting/edge-function-546-error-response.mdx +++ b/apps/docs/content/troubleshooting/edge-function-546-error-response.mdx @@ -252,7 +252,7 @@ If you believe a portion of your function is overly aggressive, try testing loca Common culprits: -**CPU intensive recursions**: intensive loops or recursion can quickly exhaust CPU +**CPU intensive recursions**: intensive loops or recursion can exhaust CPU ```js // This will exhaust CPU allocation when called repeatedly @@ -288,7 +288,7 @@ If you are performing logic to process data from Supabase Postgres, you may be a ### 4. Offload operations to an external API: -Instead of managing all operations within the function itself, there may be an external API that can execute CPU or memory intensive jobs on its behalf. One [example](/docs/guides/functions/examples/screenshots) would be using an external API for orchestrating a headless browser and then just using the edge function to manage the output of the activity instead of everything all in place. +Instead of managing all operations within the function itself, there may be an external API that can execute CPU or memory intensive jobs on its behalf. One [example](/docs/guides/functions/examples/screenshots) would be using an external API for orchestrating a headless browser and then using the edge function to manage the output of the activity instead of everything all in place. ### 5. Split operations into individual functions: @@ -312,7 +312,7 @@ Performing edits against images or other large files can be both CPU and Memory ### AI embedding generation and inference -AI models process data into embeddings (large arrays), that they can more understand. Edge Functions are capable of managing [some small models directly](/blog/ai-inference-now-available-in-supabase-edge-functions); however, some require more processing power than what the edge function can support directly. In these cases, the solution is to manage the embeddings via an external source, such as OpenAI, Anthropic, etc. and to just use the edge function for light processing and coordination. +AI models process data into embeddings (large arrays), that they can more understand. Edge Functions are capable of managing [some small models directly](/blog/ai-inference-now-available-in-supabase-edge-functions); however, some require more processing power than what the edge function can support directly. In these cases, the solution is to manage the embeddings via an external source, such as OpenAI, Anthropic, etc. and to use the edge function for light processing and coordination. ### Web scraping diff --git a/apps/docs/content/troubleshooting/edge-function-dependency-analysis.mdx b/apps/docs/content/troubleshooting/edge-function-dependency-analysis.mdx index 9d1f742018b..b1b764d3d78 100644 --- a/apps/docs/content/troubleshooting/edge-function-dependency-analysis.mdx +++ b/apps/docs/content/troubleshooting/edge-function-dependency-analysis.mdx @@ -26,7 +26,7 @@ Review the output for: - **Large dependencies:** Packages that contribute significantly to bundle size - **Redundant imports:** Multiple packages providing similar functionality - **Outdated versions:** Dependencies that can be updated to more efficient versions -- **Unused imports:** Dependencies imported but not actually used in your code +- **Unused imports:** Dependencies imported but not used in your code ## Optimizing NPM dependencies @@ -39,18 +39,17 @@ Import specific submodules to minimize overhead: ```tsx // Good: Import specific submodules import { Sheets } from 'npm:@googleapis/sheets' +import * as googleAuth from 'npm:google-auth-library' import { JWT } from 'npm:google-auth-library/build/src/auth/jwtclient' - // Avoid: Import entire package import * as googleapis from 'npm:googleapis' -import * as googleAuth from 'npm:google-auth-library' ``` ## Best practices ### Tree-shake aggressively -Only import what you actually use. Avoid wildcard imports (`import *`) when possible. +Only import what you use. Avoid wildcard imports (`import *`) when possible. ### Choose lightweight alternatives diff --git a/apps/docs/content/troubleshooting/edge-function-shutdown-reasons-explained.mdx b/apps/docs/content/troubleshooting/edge-function-shutdown-reasons-explained.mdx index e1900cefcfc..eca96448772 100644 --- a/apps/docs/content/troubleshooting/edge-function-shutdown-reasons-explained.mdx +++ b/apps/docs/content/troubleshooting/edge-function-shutdown-reasons-explained.mdx @@ -80,11 +80,11 @@ These events are surfaced through logs and observability tools, allowing you to ### EarlyDrop -**What it means:** The runtime detected that the function has completed all its work and can be shut down early, before reaching any resource limits. This is actually the most common shutdown reason and typically indicates efficient function execution. +**What it means:** The runtime detected that the function has completed all its work and can be shut down early, before reaching any resource limits. This is the most common shutdown reason and typically indicates efficient function execution. **When it happens:** Your function has finished processing the request, sent the response, and has no remaining async work (pending promises, timers, or callbacks). The runtime recognizes that the worker can be safely terminated without waiting for timeouts or other limits. -**Why this is good:** `EarlyDrop` means your function is running efficiently. It completed quickly, didn't exhaust resources, and the runtime could reclaim the worker for other requests. Most well-designed functions should end with `EarlyDrop`. +**Why this is good:** `EarlyDrop` means your function is running efficiently. It completed without exhausting resources, and the runtime could reclaim the worker for other requests. Most well-designed functions should end with `EarlyDrop`. **What to do:** diff --git a/apps/docs/content/troubleshooting/error-index-row-size-exceeds-btree-version-4-maximum-for-index-LMmoeU.mdx b/apps/docs/content/troubleshooting/error-index-row-size-exceeds-btree-version-4-maximum-for-index-LMmoeU.mdx index dc9439700af..5d9df4a6c53 100644 --- a/apps/docs/content/troubleshooting/error-index-row-size-exceeds-btree-version-4-maximum-for-index-LMmoeU.mdx +++ b/apps/docs/content/troubleshooting/error-index-row-size-exceeds-btree-version-4-maximum-for-index-LMmoeU.mdx @@ -62,6 +62,6 @@ select * from table_name where column_name = 'search_value'; [More on building index by expression](https://www.postgresql.org/docs/current/sql-createindex.html) -For some datatypes other than text that allows queries by partial inclusion (i.e. that the pair key-value is includes in a JSON or for implementing tsvector phrase search) you'd just use GIST/GIN indexes that inherently have values space much narrower that the whole to be indexed. +For some non-text datatypes that support queries by partial inclusion—such as checking whether a key-value pair exists in JSON, or implementing `tsvector` phrase search—use GiST or GIN indexes. These index types operate on a narrower value space than the full content being indexed. [More on GIN/GiST indexes](https://www.postgresql.org/docs/15/textsearch-indexes.html) diff --git a/apps/docs/content/troubleshooting/high-cpu-and-slow-queries-with-error-must-be-a-superuser-to-terminate-superuser-process.mdx b/apps/docs/content/troubleshooting/high-cpu-and-slow-queries-with-error-must-be-a-superuser-to-terminate-superuser-process.mdx index b676cdf8c54..22d1be7e136 100644 --- a/apps/docs/content/troubleshooting/high-cpu-and-slow-queries-with-error-must-be-a-superuser-to-terminate-superuser-process.mdx +++ b/apps/docs/content/troubleshooting/high-cpu-and-slow-queries-with-error-must-be-a-superuser-to-terminate-superuser-process.mdx @@ -40,7 +40,7 @@ This situation often arises in large, high-write tables (e.g., `your_table`, whi ### **Mitigating performance impact during a critical autovacuum** -Since the wraparound prevention autovacuum cannot be stopped, the best approach is to provide the database with sufficient resources to complete the operation as quickly and efficiently as possible. +Since the wraparound prevention autovacuum cannot be stopped, the best approach is to provide the database with sufficient resources to complete the operation as efficiently as possible. 1. **Upgrade your Database Compute Instance:** - **Action:** Temporarily scale up your instance's CPU (e.g., from `m6g.4xlarge` to `m6g.8xlarge` or higher). diff --git a/apps/docs/content/troubleshooting/high-latency-with-supabase-client-z0pZzR.mdx b/apps/docs/content/troubleshooting/high-latency-with-supabase-client-z0pZzR.mdx index 13ab6fdba1f..5f84bbb234d 100644 --- a/apps/docs/content/troubleshooting/high-latency-with-supabase-client-z0pZzR.mdx +++ b/apps/docs/content/troubleshooting/high-latency-with-supabase-client-z0pZzR.mdx @@ -92,8 +92,8 @@ if __name__ == "__main__": print(f"postgres: {ref}, supabase: {sup}, ratio: {sup/ref}") ``` -3. You will see that the Supabase client takes longer to execute the same query, especially for smaller tables or queries returning just one row. +3. You will see that the Supabase client takes longer to execute the same query, especially for smaller tables or queries returning only one row. ## Expected behavior -The overhead from PostgREST shouldn't be higher than a few milliseconds at max. 60-70 ms is way too high. This is particular deceiving because one can run the query on the SQL Editor page and it reports the same time as the direct Postgres query, which is not what actually happens. +The overhead from PostgREST shouldn't be higher than a few milliseconds at max. 60-70 ms is way too high. This is particular deceiving because one can run the query on the SQL Editor page and it reports the same time as the direct Postgres query, which is not what happens. diff --git a/apps/docs/content/troubleshooting/how-postgres-chooses-which-index-to-use-_JHrf4.mdx b/apps/docs/content/troubleshooting/how-postgres-chooses-which-index-to-use-_JHrf4.mdx index 914c5b6cc4c..ac3880bae98 100644 --- a/apps/docs/content/troubleshooting/how-postgres-chooses-which-index-to-use-_JHrf4.mdx +++ b/apps/docs/content/troubleshooting/how-postgres-chooses-which-index-to-use-_JHrf4.mdx @@ -77,7 +77,7 @@ In most cases, developers work with the default BTREE index. It is the most prac An operator's functional equivalents, such as `IN`, `BETWEEN`, and `ANY`, are also valid. -However, just because the base requirements (relevant column, filter, and operators) are present, doesn't mean that an index will be used. +However, an index isn't guaranteed to be used, even when the base requirements (relevant column, filter, and operators) are present. Indexes have a startup cost, so for small tables, Postgres might use a sequential scan if it believes that it will take less time. The database keeps statistics about each table that it uses to inform these choices. @@ -141,7 +141,7 @@ select * from test1 where lower(col1) = 'value'; #### Covering indexes -Indexes contain pointers to a specific row, but you could instruct an index to actually hold a copy of a column's value for even faster retrieval. These are known as `covering` indexes. Because maintaining a copy is storage intensive, you should avoid using it for values with large data footprints.[ FULL VIDEO ON TOPIC](https://www.youtube.com/watch?v=bBu_V8CfWgM) +Indexes contain pointers to a specific row, but you could instruct an index to hold a copy of a column's value for even faster retrieval. These are known as `covering` indexes. Because maintaining a copy is storage intensive, you should avoid using it for values with large data footprints.[ FULL VIDEO ON TOPIC](https://www.youtube.com/watch?v=bBu_V8CfWgM) ```sql CREATE INDEX a_b_idx ON x (a,b) INCLUDE (c); @@ -149,7 +149,7 @@ CREATE INDEX a_b_idx ON x (a,b) INCLUDE (c); #### Indexes on JSONB -Although a GIN/GIST index can be used to index entire JSONB bodies, you can also target just specific Key-values with standard BTREE indexes: +Although a GIN/GIST index can be used to index entire JSONB bodies, you can also target only specific Key-values with standard BTREE indexes: ```sql -- Example table diff --git a/apps/docs/content/troubleshooting/how-to-change-max-database-connections-_BQ8P5.mdx b/apps/docs/content/troubleshooting/how-to-change-max-database-connections-_BQ8P5.mdx index e1c69e3ee29..4682d7ed2dd 100644 --- a/apps/docs/content/troubleshooting/how-to-change-max-database-connections-_BQ8P5.mdx +++ b/apps/docs/content/troubleshooting/how-to-change-max-database-connections-_BQ8P5.mdx @@ -71,7 +71,7 @@ This is a Grafana Chart of unhealthy memory usage: ![image](/docs/img/troubleshooting/47685206-7914-440e-a010-da62f5c38186.png) - Yellow: represents active memory -- Red: represents SWAP, which is disk storage that the system treats as if it were actually memory +- Red: represents SWAP, which is disk storage that the system treats as if it were memory - Green: it is unclaimed (the system will always leave some memory unclaimed) - Blue: it is cached data and a buffer diff --git a/apps/docs/content/troubleshooting/how-to-interpret-and-explore-the-postgres-logs-OuCIOj.mdx b/apps/docs/content/troubleshooting/how-to-interpret-and-explore-the-postgres-logs-OuCIOj.mdx index 811abe5dc63..c0ece19c525 100644 --- a/apps/docs/content/troubleshooting/how-to-interpret-and-explore-the-postgres-logs-OuCIOj.mdx +++ b/apps/docs/content/troubleshooting/how-to-interpret-and-explore-the-postgres-logs-OuCIOj.mdx @@ -263,7 +263,7 @@ limit 100; When recording what is accessed and by whom, logging based on database roles and objects is the most reliable way to ensure a proper trail of activity. -You can use the [pg_audit](/docs/guides/database/extensions/pgaudit) extension to selectively log relevant queries (not just errors) by certain roles, against specific database objects. +You can use the [pg_audit](/docs/guides/database/extensions/pgaudit) extension to selectively log relevant queries, not only errors, by certain roles, against specific database objects. You should take care when using the extension to not log all database events, but only what is absolutely necessary. Over-logging can strain the database and create log noise that makes it difficult to filter for relevant events. diff --git a/apps/docs/content/troubleshooting/inserting-into-sequenceserial-table-causes-duplicate-key-violates-unique-constraint-error-pi6DnC.mdx b/apps/docs/content/troubleshooting/inserting-into-sequenceserial-table-causes-duplicate-key-violates-unique-constraint-error-pi6DnC.mdx index c09d6d28ae7..bb30ac7b402 100644 --- a/apps/docs/content/troubleshooting/inserting-into-sequenceserial-table-causes-duplicate-key-violates-unique-constraint-error-pi6DnC.mdx +++ b/apps/docs/content/troubleshooting/inserting-into-sequenceserial-table-causes-duplicate-key-violates-unique-constraint-error-pi6DnC.mdx @@ -28,7 +28,7 @@ SELECT nextval(pg_get_serial_sequence('', ' npx supabase secrets list ``` -For security reasons, it is not advised to log secrets, but you can log a truncated version just for the reassurance that they're being updated: +For security reasons, it is not advised to log secrets, but you can log a truncated version for the reassurance that they're being updated: ```typescript //logs the function call and the secrets diff --git a/apps/docs/content/troubleshooting/interpreting-supabase-grafana-io-charts-MUynDR.mdx b/apps/docs/content/troubleshooting/interpreting-supabase-grafana-io-charts-MUynDR.mdx index bb66f23d10a..cdfc1ed59a0 100644 --- a/apps/docs/content/troubleshooting/interpreting-supabase-grafana-io-charts-MUynDR.mdx +++ b/apps/docs/content/troubleshooting/interpreting-supabase-grafana-io-charts-MUynDR.mdx @@ -64,7 +64,7 @@ Other useful Supabase Grafana guides: ### Esoteric factors **Webhooks**: -Supabase webhooks use the pg_net extension to handle requests. The `net.http_request_queue` table isn't indexed to keep write costs low. However, if you upload millions of rows to a webhook-enabled table too quickly, it can significantly increase the read costs for the extension. +Supabase webhooks use the pg_net extension to handle requests. The `net.http_request_queue` table isn't indexed to keep write costs low. However, if you upload millions of rows to a webhook-enabled table in rapid succession, it can significantly increase the read costs for the extension. To check if reads are becoming expensive, run: diff --git a/apps/docs/content/troubleshooting/keeping-free-projects-after-pro-upgrade-Kf9Xm2.mdx b/apps/docs/content/troubleshooting/keeping-free-projects-after-pro-upgrade-Kf9Xm2.mdx index 642457a9adc..1ded427c860 100644 --- a/apps/docs/content/troubleshooting/keeping-free-projects-after-pro-upgrade-Kf9Xm2.mdx +++ b/apps/docs/content/troubleshooting/keeping-free-projects-after-pro-upgrade-Kf9Xm2.mdx @@ -8,7 +8,7 @@ database_id = "449482fb-6e21-4a25-99ee-1ce6fffbc975" ## Can you keep your 2 free projects after upgrading to pro? -Yes! You still get 2 free projects after you upgrade to Pro. They just need to be in a **separate** Free Plan organization. +Yes. After upgrading to Pro, you still get 2 free projects. They must be in a separate Free Plan organization. ## Why do free projects need to be in a separate organization? diff --git a/apps/docs/content/troubleshooting/not-receiving-auth-emails-from-the-supabase-project-OFSNzw.mdx b/apps/docs/content/troubleshooting/not-receiving-auth-emails-from-the-supabase-project-OFSNzw.mdx index eb6a4880fce..6b5ae533118 100644 --- a/apps/docs/content/troubleshooting/not-receiving-auth-emails-from-the-supabase-project-OFSNzw.mdx +++ b/apps/docs/content/troubleshooting/not-receiving-auth-emails-from-the-supabase-project-OFSNzw.mdx @@ -9,7 +9,7 @@ database_id = "98e3b318-ad9a-41f5-ada0-44b61970ab4f" **We strongly recommend configuring your own custom SMTP provider** in your projects to avoid running into issues with sending emails from your project. The built-in email provider is for demonstration purposes only and offers a very low rate limit. You can read more details about the rate limits [here](/docs/guides/platform/going-into-prod#auth-rate-limits). -If you're testing your Supabase projects, consider configuring an email testing tool like [Mailtrap](https://mailtrap.io/) to test your emails. It's an email sandbox tool that helps debug emails without actually sending an email to an end user. +If you're testing your Supabase projects, consider configuring an email testing tool like [Mailtrap](https://mailtrap.io/) to test your emails. It's an email sandbox tool that helps debug emails without sending an email to an end user. As the initial step in debugging not-delivered emails, check your project's [Auth logs](/dashboard/project/_/logs/auth-logs) for errors that can occur when handing over to the email providers. In general, handover issues can occur due to misconfiguration of the custom SMTP provider. diff --git a/apps/docs/content/troubleshooting/pausing-pro-projects-vNL-2a.mdx b/apps/docs/content/troubleshooting/pausing-pro-projects-vNL-2a.mdx index f783efb49a7..0dbb540a781 100644 --- a/apps/docs/content/troubleshooting/pausing-pro-projects-vNL-2a.mdx +++ b/apps/docs/content/troubleshooting/pausing-pro-projects-vNL-2a.mdx @@ -14,7 +14,7 @@ Pro-Projects at the moment cannot be paused. However, [You are allowed to have t If a project is under 500MB, you can [transfer it to be under a free organization](/docs/guides/platform/project-transfer). Afterwards, you can initiate a pause. -Alternatively, you can download a [daily backup](/dashboard/project/_/database/backups/scheduled) of just your database for archiving. You can also manually download a .SQL file of your database and storage buckets by following this [guide](/docs/guides/platform/migrating-within-supabase/backup-restore). +Alternatively, you can download a [daily backup](/dashboard/project/_/database/backups/scheduled) of only your database for archiving. You can also manually download a .SQL file of your database and storage buckets by following this [guide](/docs/guides/platform/migrating-within-supabase/backup-restore). You can also download your storage buckets with the [Supabase CLI:](/docs/guides/cli/getting-started?queryGroups=platform&platform=npx) diff --git a/apps/docs/content/troubleshooting/postgrest-error-400-column-example_tableexample_column-does-not-exist-when-using-or-operators-46ff23.mdx b/apps/docs/content/troubleshooting/postgrest-error-400-column-example_tableexample_column-does-not-exist-when-using-or-operators-46ff23.mdx index 27d6f72b96a..e132244871a 100644 --- a/apps/docs/content/troubleshooting/postgrest-error-400-column-example_tableexample_column-does-not-exist-when-using-or-operators-46ff23.mdx +++ b/apps/docs/content/troubleshooting/postgrest-error-400-column-example_tableexample_column-does-not-exist-when-using-or-operators-46ff23.mdx @@ -17,7 +17,7 @@ The bug is triggered when an `or()` filter is included in a mutation request. Po ## How to confirm 1. **Reproduce the asymmetry** — run the same filter as a `GET` request. If it succeeds but the `PATCH`/`POST`/`DELETE` fails with the same column reference, the bug is the likely cause. -2. **Check your PostgREST version** — go to [Project Settings > Infrastructure](/dashboard/project/_/settings/infrastructure) and note the PostgreSQL version. PostgREST 14.1 and earlier are affected; 14.4+ includes the fix. +2. **Check your PostgREST version** — go to [Project Settings > Infrastructure](/dashboard/project/_/settings/infrastructure) and note the Postgres version. PostgREST 14.1 and earlier are affected; 14.4+ includes the fix. 3. **Check Postgres logs** — if you have logging enabled, you should see `column "example_column" does not exist` errors correlating with the timestamps of the failed mutation requests. ## Resolution diff --git a/apps/docs/content/troubleshooting/realtime-warn-sending-broadcast-message.mdx b/apps/docs/content/troubleshooting/realtime-warn-sending-broadcast-message.mdx index bbdf7013e0a..6188422ac4f 100644 --- a/apps/docs/content/troubleshooting/realtime-warn-sending-broadcast-message.mdx +++ b/apps/docs/content/troubleshooting/realtime-warn-sending-broadcast-message.mdx @@ -44,7 +44,7 @@ Calling `realtime.send` / `realtime.send_binary`, the broadcast REST endpoint, a ## How to avoid it -- Connect a client before broadcasting from the database. A live WebSocket connection both creates the partitions and starts the consumer that actually receives the message. +- Connect a client before broadcasting from the database. A live WebSocket connection both creates the partitions and starts the consumer that receives the message. - If you broadcast from the database on a schedule, make sure at least one subscriber is connected when you send. Otherwise the messages have no destination. ## When it is a real problem diff --git a/apps/docs/content/troubleshooting/resolving-42p01-relation-does-not-exist-error-W4_9-V.mdx b/apps/docs/content/troubleshooting/resolving-42p01-relation-does-not-exist-error-W4_9-V.mdx index 1d983d900bb..7954a056dfb 100644 --- a/apps/docs/content/troubleshooting/resolving-42p01-relation-does-not-exist-error-W4_9-V.mdx +++ b/apps/docs/content/troubleshooting/resolving-42p01-relation-does-not-exist-error-W4_9-V.mdx @@ -48,9 +48,9 @@ rename to table_name; --- -### Cause 3: Table or function actually does not exist +### Cause 3: Table or function does not exist -One may have never made the table or dropped it deliberately or accidentally. This can be quickly checked with the following query: +One may have never made the table or dropped it deliberately or accidentally. This can be checked with the following query: ```sql -- For tables diff --git a/apps/docs/content/troubleshooting/resolving-500-status-authentication-errors-7bU5U8.mdx b/apps/docs/content/troubleshooting/resolving-500-status-authentication-errors-7bU5U8.mdx index b9b532be608..344f13d04ab 100644 --- a/apps/docs/content/troubleshooting/resolving-500-status-authentication-errors-7bU5U8.mdx +++ b/apps/docs/content/troubleshooting/resolving-500-status-authentication-errors-7bU5U8.mdx @@ -106,7 +106,7 @@ Alternatively, you can run the SQL script in this [GitHub Gist](https://gist.git #### Trigger related: -If errors reference a database function, this indicates a trigger error on one of the auth tables (likely auth.users). If you do not want to keep the trigger/function, you can just quickly drop it, otherwise, continue reading to know how to fix the issue: +If errors reference a database function, this indicates a trigger error on one of the auth tables (likely auth.users). If you do not want to keep the trigger/function, you can drop it, otherwise, continue reading to know how to fix the issue: ```sql -- delete the trigger with the following SQL: diff --git a/apps/docs/content/troubleshooting/rls-performance-and-best-practices-Z5Jjwv.mdx b/apps/docs/content/troubleshooting/rls-performance-and-best-practices-Z5Jjwv.mdx index ec8820dff09..b1661baa9f7 100644 --- a/apps/docs/content/troubleshooting/rls-performance-and-best-practices-Z5Jjwv.mdx +++ b/apps/docs/content/troubleshooting/rls-performance-and-best-practices-Z5Jjwv.mdx @@ -11,7 +11,7 @@ database_id = "bb06ff88-e0a9-41bc-b00b-9afde10468a5" Although most of the time spent on thinking about RLS is to get it to handle security needs, the impact of it on performance of your queries can be massive. This is especially true on queries that look at every row in a table like for many select operations and updates. -Note that queries that use limit and offset will usually have to query all rows to determine order, not just the limit amount so they are impacted too. +Note that queries that use limit and offset will usually have to query all rows to determine order, not only the limit amount so they are impacted too. See the last section for ways to measure the performance of your queries as you test RLS improvements. @@ -107,7 +107,7 @@ Note that if the `in` list gets to be over 10K items, then extra analysis is lik #### 6. Use role in TO option or roles dropdown in the dashboard. -Never just use RLS involving `auth.uid()` or `auth.jwt()` as your way to rule out 'anon' role. +Never use RLS involving `auth.uid()` or `auth.jwt()` as your only way to rule out 'anon' role. Always add 'authenticated' to the approved roles instead of nothing or public. Although this does not improve the query performance for the signed in user it does eliminate 'anon' users without taxing the database to process the rest of the RLS. diff --git a/apps/docs/content/troubleshooting/rotating-anon-service-and-jwt-secrets-1Jq6yd.mdx b/apps/docs/content/troubleshooting/rotating-anon-service-and-jwt-secrets-1Jq6yd.mdx index 4d62b30e58d..d7b954f2de1 100644 --- a/apps/docs/content/troubleshooting/rotating-anon-service-and-jwt-secrets-1Jq6yd.mdx +++ b/apps/docs/content/troubleshooting/rotating-anon-service-and-jwt-secrets-1Jq6yd.mdx @@ -19,7 +19,7 @@ Once the JWT secret is regenerated, all current API secrets will be immediately -Have you ever accidentally committed a service key to a public repo? Or maybe rotating keys is just something you regularly do for security compliance. +Have you ever accidentally committed a service key to a public repo? Or maybe rotating keys is something you regularly do for security compliance. Whatever the reason, here's how to rotate the keys for your Supabase project. If you haven’t migrated to asymmetric JWT signing keys: diff --git a/apps/docs/content/troubleshooting/running-explain-analyze-on-functions.mdx b/apps/docs/content/troubleshooting/running-explain-analyze-on-functions.mdx index 8aa25f3420a..35ec1fc84e9 100644 --- a/apps/docs/content/troubleshooting/running-explain-analyze-on-functions.mdx +++ b/apps/docs/content/troubleshooting/running-explain-analyze-on-functions.mdx @@ -8,7 +8,7 @@ database_id = "1d62cace-c0f6-47a0-8690-002a797da33b" sdk = [ "rpc" ] --- -Sometimes it can help to look at Postgres query plans inside a function. The problem is that running [`EXPLAIN ANALYZE`](https://www.depesz.com/2013/04/16/explaining-the-unexplainable/) on a function usually just shows a [function scan](https://pganalyze.com/docs/explain/scan-nodes/function-scan) or result node, which gives little insight into how the queries actually perform. +Sometimes it can help to look at Postgres query plans inside a function. The problem is that running [`EXPLAIN ANALYZE`](https://www.depesz.com/2013/04/16/explaining-the-unexplainable/) on a function usually shows a [function scan](https://pganalyze.com/docs/explain/scan-nodes/function-scan) or result node, which gives little insight into how the queries perform. [`auto_explain`](https://www.postgresql.org/docs/current/auto-explain.html) is a pre-installed module that is able to log query plans for queries within functions. diff --git a/apps/docs/content/troubleshooting/security-of-anonymous-sign-ins-iOrGCL.mdx b/apps/docs/content/troubleshooting/security-of-anonymous-sign-ins-iOrGCL.mdx index d524a22352c..ba1a957e518 100644 --- a/apps/docs/content/troubleshooting/security-of-anonymous-sign-ins-iOrGCL.mdx +++ b/apps/docs/content/troubleshooting/security-of-anonymous-sign-ins-iOrGCL.mdx @@ -13,7 +13,7 @@ We want to clarify and provide reassurance on this topic. Enabling anonymous sign-ins on your project does not reduce its security. Here's why: -- Same as Regular Users: Anonymous users function just like regular users within your project. They have unique user IDs and their own records in the authentication tables. +- Same as Regular Users: Anonymous users function like regular users within your project. They have unique user IDs and their own records in the authentication tables. - Security Policies: All role-based security policies (RLS) applicable to regular users also apply to anonymous users. - Identity Verification Measures: Even though anonymous users do not initially provide an email or phone number, the security of your project remains robust. But to prevent misuse, we recommend implementing additional security measure such as [CAPTCHA](/docs/guides/auth/auth-captcha): to ensure that interactions are genuinely human. diff --git a/apps/docs/content/troubleshooting/soft-deletes-with-supabase-js.mdx b/apps/docs/content/troubleshooting/soft-deletes-with-supabase-js.mdx index 915c6f9339d..21610977255 100644 --- a/apps/docs/content/troubleshooting/soft-deletes-with-supabase-js.mdx +++ b/apps/docs/content/troubleshooting/soft-deletes-with-supabase-js.mdx @@ -75,7 +75,7 @@ This effectively un-deletes the record. ## Benefits of using views for soft deletes -- **Cleaner Queries:** No need to add `WHERE deleted_at IS NULL` to every query. Just query the view (`active_items`). +- **Cleaner Queries:** No need to add `WHERE deleted_at IS NULL` to every query. Query the view (`active_items`) instead. - **Separation of Concerns:** Views abstract the logic of filtering deleted records from your application code. - **Efficiency:** Postgres handles the filtering in the view, reducing the complexity in your app. diff --git a/apps/docs/content/troubleshooting/steps-to-improve-query-performance-with-indexes-q8PoC9.mdx b/apps/docs/content/troubleshooting/steps-to-improve-query-performance-with-indexes-q8PoC9.mdx index d159b35512b..e724c1893a9 100644 --- a/apps/docs/content/troubleshooting/steps-to-improve-query-performance-with-indexes-q8PoC9.mdx +++ b/apps/docs/content/troubleshooting/steps-to-improve-query-performance-with-indexes-q8PoC9.mdx @@ -43,7 +43,7 @@ select from pg_statio_user_tables; ``` -If the cache hit rate is relatively low, it often means that you need to increase your memory capacity. The second metric that is often inspected is index usage. Indexes are data structures that allow Postgres to search for information quickly - think of them like you would think of an index at the back of a book. Instead of scanning every page (or row), you can use an index to find the contents you need quickly. For a better understanding of how Postgres decides on whether to use an index or not, check out this [explainer](https://github.com/orgs/supabase/discussions/26959). +If the cache hit rate is relatively low, it often means that you need to increase your memory capacity. The second metric that is often inspected is index usage. Indexes are data structures that allow Postgres to search for information efficiently - think of them like you would think of an index at the back of a book. Instead of scanning every page (or row), you can use an index to find the contents you need efficiently. For a better understanding of how Postgres decides on whether to use an index or not, check out this [explainer](https://github.com/orgs/supabase/discussions/26959). The index hit rate (how often an index is used) can usually be improved moderately. @@ -59,7 +59,7 @@ where seq_scan + idx_scan > 0 order by n_live_tup desc; ``` -A lot of the [queries for inspecting performance](/docs/reference/cli/supabase-inspect-db) are actually pre-bundled as part of the [Supabase CLI](/docs/guides/cli/getting-started). For instance, there is a command for testing which indexes of yours are unnecessary and are needlessly taking up space: +A lot of the [queries for inspecting performance](/docs/reference/cli/supabase-inspect-db) are pre-bundled as part of the [Supabase CLI](/docs/guides/cli/getting-started). For instance, there is a command for testing which indexes of yours are unnecessary and are needlessly taking up space: ```bash npx supabase login diff --git a/apps/docs/content/troubleshooting/supabase-grafana-memory-charts.mdx b/apps/docs/content/troubleshooting/supabase-grafana-memory-charts.mdx index 3f7239eeeb5..4106f66cfba 100644 --- a/apps/docs/content/troubleshooting/supabase-grafana-memory-charts.mdx +++ b/apps/docs/content/troubleshooting/supabase-grafana-memory-charts.mdx @@ -14,7 +14,7 @@ Here are examples of unhealthy memory usage: ![image](https://github.com/supabase/supabase/assets/91111415/b95c83cf-aa98-4b50-8e07-29f57aaa676c) - **Yellow**: represents active memory -- **Red**: represents SWAP, which is disk storage that the system treats as if it were actually memory +- **Red**: represents SWAP, which is disk storage that the system treats as if it were memory - **Green**: it is unclaimed (the system will always leave some memory unclaimed) - **Blue**: it is cached data and a buffer diff --git a/apps/docs/content/troubleshooting/supavisor-and-connection-terminology-explained-9pr_ZO.mdx b/apps/docs/content/troubleshooting/supavisor-and-connection-terminology-explained-9pr_ZO.mdx index 04a60dc9c16..ad0f4472c28 100644 --- a/apps/docs/content/troubleshooting/supavisor-and-connection-terminology-explained-9pr_ZO.mdx +++ b/apps/docs/content/troubleshooting/supavisor-and-connection-terminology-explained-9pr_ZO.mdx @@ -7,7 +7,7 @@ keywords = [ "connections", "pooler", "transaction", "session", "pgbouncer" ] database_id = "e008e056-453d-44b5-8a8a-27c2d70681fe" --- -I'll be the first to admit that the official naming conventions in the Postgres community can be a bit confusing, so here's a basic rundown. It's a bit long, so feel free to just jump to the portion relevant to you: +I'll be the first to admit that the official naming conventions in the Postgres community can be a bit confusing, so here's a basic rundown. It's a bit long, so feel free to jump to the portion relevant to you: ## Clients: diff --git a/apps/docs/content/troubleshooting/supavisor-faq-YyP5tI.mdx b/apps/docs/content/troubleshooting/supavisor-faq-YyP5tI.mdx index 5680737403d..0bf72e502c8 100644 --- a/apps/docs/content/troubleshooting/supavisor-faq-YyP5tI.mdx +++ b/apps/docs/content/troubleshooting/supavisor-faq-YyP5tI.mdx @@ -81,11 +81,11 @@ When clients connect to either Postgres or Supavisor, they do so with the Postgr ### What are "client connections"? In summary, they have nothing to do with front-end clients. They are the amount of backend-server connections that can connect to a serverside pooler. -Imagine a chess tournament with 60 boards. Each board represents a connection in a database. When a player sits down at a board, it's like a client connecting to the database. They can take their time with their moves or just sit there, not making any. +Imagine a chess tournament with 60 boards. Each board represents a connection in a database. When a player sits down at a board, it's like a client connecting to the database. They can take their time with their moves or sit there, not making any. But when the tournament fills up and all the boards are taken, new players are turned away, and told to check back at a later time to see if a table becomes available. -Now, imagine the tournament organizers decide to expand the venue to house 200 people without adding more tables. Even when all boards are occupied, players don't have to leave. They can wait in the wings, and the moment a board opens up, someone from the waiting area can take their place. Likewise, if someone ends their game, but wants to play again, they can just go back to the waiting area. The waiting area represents the "Max Client Connections". Ultimately, the additional capacity provided by the pooler ensures fewer people are turned away from the "tournament". +Now, imagine the tournament organizers decide to expand the venue to house 200 people without adding more tables. Even when all boards are occupied, players don't have to leave. They can wait in the wings, and the moment a board opens up, someone from the waiting area can take their place. Likewise, if someone ends their game, but wants to play again, they can go back to the waiting area. The waiting area represents the "Max Client Connections". Ultimately, the additional capacity provided by the pooler ensures fewer people are turned away from the "tournament". ### In the context of Supavisor, what does "pool size" mean? @@ -93,14 +93,14 @@ Now, imagine the tournament organizers decide to expand the venue to house 200 p ### What is the "user+db+mode" combination? -Postgres is not actually a database. It is a Relational Database Management System (RDMS). Within it, you can spawn Postgres databases. In Supabase, it is a common pattern to just use the default database called `postgres`, but you could create more: +Postgres is not a database. It is a Relational Database Management System (RDMS). Within it, you can spawn Postgres databases. In Supabase, it is a common pattern to use the default database called `postgres`, but you could create more: ```sql CREATE DATABASE postgres; CREATE DATABASE another_database; ``` -Similarly, a database can have many database users, but most people just rely on the default user `postgres`. +Similarly, a database can have many database users, but most people rely on the default user `postgres`. ```sql CREATE USER postgres WITH PASSWORD 'super-secret-password'; diff --git a/apps/docs/content/troubleshooting/tracking-postgres-role-activity-to-specific-dashboard-users-8d3715.mdx b/apps/docs/content/troubleshooting/tracking-postgres-role-activity-to-specific-dashboard-users-8d3715.mdx index 325b647cac5..f679efeeaab 100644 --- a/apps/docs/content/troubleshooting/tracking-postgres-role-activity-to-specific-dashboard-users-8d3715.mdx +++ b/apps/docs/content/troubleshooting/tracking-postgres-role-activity-to-specific-dashboard-users-8d3715.mdx @@ -37,10 +37,10 @@ Notice that the log includes: - The full statement - The timestamp -- A `user` field, which is actually the Supabase user UUID +- A `user` field, which is the Supabase user UUID - The source (dashboard) -That UUID corresponds to the team member who logged in via the Supabase Dashboard and executed queries in the [SQL Editor](/dashboard/project/_/sql/new). But at this point, it's just an ID - not yet a name or email. +That UUID corresponds to the team member who logged in via the Supabase Dashboard and executed queries in the [SQL Editor](/dashboard/project/_/sql/new). But at this point, it's only an ID - not yet a name or email. ### **Mapping UUIDs to team members** diff --git a/apps/docs/content/troubleshooting/understanding-postgresql-explain-output-Un9dqX.mdx b/apps/docs/content/troubleshooting/understanding-postgresql-explain-output-Un9dqX.mdx index 45c7760eca4..97cbe55b88e 100644 --- a/apps/docs/content/troubleshooting/understanding-postgresql-explain-output-Un9dqX.mdx +++ b/apps/docs/content/troubleshooting/understanding-postgresql-explain-output-Un9dqX.mdx @@ -45,9 +45,9 @@ const { data, error } = await supabase **- Seq Scan:** A sequential scan that reads all rows from a table. This is often seen in the absence of indexes that can be used for the query. -**- Index Scan:** Uses an index to find rows quickly. This indicates that the query is able to use an index to efficiently locate data. +**- Index Scan:** Uses an index to find rows efficiently. This indicates that the query is able to use an index to efficiently locate data. -**- Bitmap Heap Scan:** Uses a bitmap index to find rows quickly and then retrieves the actual rows from the table. This type of scan is efficient when retrieving a moderate number of rows. +**- Bitmap Heap Scan:** Uses a bitmap index to find rows efficiently and then retrieves the actual rows from the table. This type of scan is efficient when retrieving a moderate number of rows. ### 2. Cost @@ -70,7 +70,7 @@ const { data, error } = await supabase ### 6. Execution time -**Execution Time: 0.069 ms:** measures how long it took to actually execute the query, including retrieving the data, performing any sorts, joins, or other operations defined in the execution plan, and returning the final results. This time is measured in milliseconds. +**Execution Time: 0.069 ms:** measures how long it took to execute the query, including retrieving the data, performing any sorts, joins, or other operations defined in the execution plan, and returning the final results. This time is measured in milliseconds. ![image](/docs/img/troubleshooting/10950be3-264b-4a41-bc71-3d431c2756b2.png) @@ -78,7 +78,7 @@ const { data, error } = await supabase When running EXPLAIN ANALYZE, additional information is provided, including: -- **Actual time:** Shows the time actually spent executing the scan and retrieving rows. This is split into the time to retrieve the first row (first) and the time to retrieve all rows (last). +- **Actual time:** Shows the time spent executing the scan and retrieving rows. This is split into the time to retrieve the first row (first) and the time to retrieve all rows (last). - **Rows removed by filter:** Indicates how many rows were excluded due to not meeting the filter conditions. @@ -135,25 +135,25 @@ On top of that, you have to multiply the cost and the time with the number of ### Common nodes in Postgres explain output -| Node Type | Description | -| --------------------- | ---------------------------------------------------------------------------- | -| **Seq Scan** | Scans each row of a table sequentially, often used without suitable indexes. | -| **Index Scan** | Uses an index to quickly find rows, efficient for small fractions of rows. | -| **Index Only Scan** | Retrieves all needed data from the index itself, without visiting the table. | -| **Bitmap Heap Scan** | Uses a bitmap of row locations to efficiently retrieve rows from the table. | -| **Bitmap Index Scan** | Builds a bitmap by scanning the index to efficiently locate rows. | -| **`Tid` Scan** | Fetches rows directly using tuple identifiers, used in sub-selects. | -| **Nested Loop** | Joins two tables by scanning the first and then the second for each row. | -| **Merge Join** | Joins two pre-sorted tables, efficient for large datasets. | -| **Hash Join** | Uses a hash table to perform joins, often faster for larger datasets. | -| **Aggregate** | Performs aggregation calculations like `SUM`, `COUNT`, etc. | -| **Sort** | Sorts rows based on specified criteria, required for certain operations. | -| **Limit** | Returns a specified number of rows quickly, used with `LIMIT` clause. | -| **CTE Scan** | Scans a Common Table Expression, used for WITH clauses. | -| **Materialize** | Materializes the result of a subquery or node to reuse without re-running. | -| **Subquery Scan** | Executes and provides the results of a subquery to the outer query. | -| **Foreign Scan** | Fetches data from foreign data sources outside the local database. | -| **Function Scan** | Retrieves results from a set-returning function. | +| Node Type | Description | +| --------------------- | ------------------------------------------------------------------------------ | +| **Seq Scan** | Scans each row of a table sequentially, often used without suitable indexes. | +| **Index Scan** | Uses an index to efficiently find rows, efficient for small fractions of rows. | +| **Index Only Scan** | Retrieves all needed data from the index itself, without visiting the table. | +| **Bitmap Heap Scan** | Uses a bitmap of row locations to efficiently retrieve rows from the table. | +| **Bitmap Index Scan** | Builds a bitmap by scanning the index to efficiently locate rows. | +| **`Tid` Scan** | Fetches rows directly using tuple identifiers, used in sub-selects. | +| **Nested Loop** | Joins two tables by scanning the first and then the second for each row. | +| **Merge Join** | Joins two pre-sorted tables, efficient for large datasets. | +| **Hash Join** | Uses a hash table to perform joins, often faster for larger datasets. | +| **Aggregate** | Performs aggregation calculations like `SUM`, `COUNT`, etc. | +| **Sort** | Sorts rows based on specified criteria, required for certain operations. | +| **Limit** | Returns a specified number of rows efficiently, used with `LIMIT` clause. | +| **CTE Scan** | Scans a Common Table Expression, used for WITH clauses. | +| **Materialize** | Materializes the result of a subquery or node to reuse without re-running. | +| **Subquery Scan** | Executes and provides the results of a subquery to the outer query. | +| **Foreign Scan** | Fetches data from foreign data sources outside the local database. | +| **Function Scan** | Retrieves results from a set-returning function. | ### What to focus on in explain analyze output @@ -182,11 +182,11 @@ Determining whether 100 milliseconds for e.g is noteworthy in the context of ide **Overall Query Execution Time:** -If the total execution time of a query significantly exceeds 100 milliseconds, then this particular step may not represent the main bottleneck. For instance, in queries that take several seconds to execute, a component that consumes just 100 milliseconds may not be the critical target for optimization efforts. +If the total execution time of a query significantly exceeds 100 milliseconds, then this particular step may not represent the main bottleneck. For instance, in queries that take several seconds to execute, a component that consumes only 100 milliseconds may not be the critical target for optimization efforts. **Complexity and Scale of the Query:** -For complex queries that involve multiple joins, subqueries, or aggregation functions, an operation that takes 100 milliseconds might actually reflect good efficiency. Conversely, for simpler queries or operations expected to be quick (such as fetching a few rows from a well-indexed table), 100 milliseconds could suggest a lack of efficiency. +For complex queries that involve multiple joins, subqueries, or aggregation functions, an operation that takes 100 milliseconds might reflect good efficiency. Conversely, for simpler queries or operations expected to be quick (such as fetching a few rows from a well-indexed table), 100 milliseconds could suggest a lack of efficiency. So, the acceptable performance threshold can vary by application. For real-time systems or high-frequency trading platforms, even a few milliseconds can be critical, whereas for batch processing or data warehousing, longer execution times might be acceptable. diff --git a/apps/docs/content/troubleshooting/understanding-postgresql-logging-levels-and-how-they-impact-your-project-KXiJRm.mdx b/apps/docs/content/troubleshooting/understanding-postgresql-logging-levels-and-how-they-impact-your-project-KXiJRm.mdx index d162dd29360..a88e2e726b2 100644 --- a/apps/docs/content/troubleshooting/understanding-postgresql-logging-levels-and-how-they-impact-your-project-KXiJRm.mdx +++ b/apps/docs/content/troubleshooting/understanding-postgresql-logging-levels-and-how-they-impact-your-project-KXiJRm.mdx @@ -7,7 +7,7 @@ keywords = [ "logging", "disk", "i/o", "lockups" ] database_id = "10186830-8cce-4f10-8cb9-7cbf39310763" --- -Since each Supabase project uses Postgres as its underlying database engine, it’s common to adjust logging settings for various reasons—whether for debugging issues, monitoring database performance, or auditing actions. However, modifying logging levels improperly can lead to an excessive amount of log data being generated, which can quickly fill up your disk space and cause significant performance degradation or even system failure. +Since each Supabase project uses Postgres as its underlying database engine, it’s common to adjust logging settings for various reasons—whether for debugging issues, monitoring database performance, or auditing actions. However, modifying logging levels improperly can lead to an excessive amount of log data being generated, which can fill up your disk space and cause significant performance degradation or even system failure. ### 1. Overview of Postgres logging levels @@ -41,7 +41,7 @@ The default log level is set to **WARNING** through the log_min_messages setting ### 2. How high log levels can affect your database -When users alter a high level of log settings, the database can start generating an overwhelming number of log entries. This can quickly escalate to issues such as: +When users alter a high level of log settings, the database can start generating an overwhelming number of log entries. This can escalate to issues such as: - Disk Space Exhaustion: Log files can grow exponentially if verbose levels like DEBUG, INFO, or NOTICE are enabled for long periods. And running out of disk space due to log bloat can cause your database to stop accepting writes and slow down query performance. diff --git a/apps/docs/content/troubleshooting/understanding-the-usage-summary-on-the-dashboard-D7Gnle.mdx b/apps/docs/content/troubleshooting/understanding-the-usage-summary-on-the-dashboard-D7Gnle.mdx index 6a49c389fe4..5457e9280aa 100644 --- a/apps/docs/content/troubleshooting/understanding-the-usage-summary-on-the-dashboard-D7Gnle.mdx +++ b/apps/docs/content/troubleshooting/understanding-the-usage-summary-on-the-dashboard-D7Gnle.mdx @@ -30,7 +30,7 @@ Using the database size as an example, suppose we have the following projects un If the user decides to delete Projects A and B during the current billing cycle, the average database usage will be 2 GB for the current billing cycle, even though only a 0.5 GB database is currently active. -As of now, even if your project was just active for a few days, we take the average database size for those active days, which may lead to high usage when creating and deleting many projects within a billing cycle. We're working on a better billing model to cover these cases. +As of now, even if your project was only active for a few days, we take the average database size for those active days, which may lead to high usage when creating and deleting many projects within a billing cycle. We're working on a better billing model to cover these cases. ## Edge Functions example diff --git a/apps/docs/content/troubleshooting/webhook-debugging-guide-M8sk47.mdx b/apps/docs/content/troubleshooting/webhook-debugging-guide-M8sk47.mdx index bfa806ef67f..bf32e5ee9b0 100644 --- a/apps/docs/content/troubleshooting/webhook-debugging-guide-M8sk47.mdx +++ b/apps/docs/content/troubleshooting/webhook-debugging-guide-M8sk47.mdx @@ -30,7 +30,7 @@ Otherwise, it is necessary to fast reboot your instance in the [Dashboard's Sett Using `pg_net` in triggers on most tables is fine; however, do not add triggers to the `net._http_response` or `net.http_request_queue` tables. -The `net` tables are special and if triggers on them fail or call a pg_net function (`http_get`, `http_post`, `http_delete`), it can lead to an infinite loop. This warning is irrelevant to most projects, but it's worth specifying just in case. +The `net` tables are special and if triggers on them fail or call a pg_net function (`http_get`, `http_post`, `http_delete`), it can lead to an infinite loop. This warning is irrelevant to most projects, but it's worth specifying in case. **3. Check for timeout errors** @@ -56,7 +56,7 @@ body := '{"key1": "value", "key2": 5}'::jsonb ) as request_id; ``` -Postman will then respond with the same payload. This is just a test to confirm that requests are being properly formatted and going through. +Postman will then respond with the same payload. This is a test to confirm that requests are being properly formatted and going through. You can then view the request in the `net._http_response table` in the [Table Editor](/dashboard/project/_/editor) or with the following SQL: diff --git a/apps/docs/content/troubleshooting/why-is-my-select-returning-an-empty-data-array-and-i-have-data-in-the-table-xvOPgx.mdx b/apps/docs/content/troubleshooting/why-is-my-select-returning-an-empty-data-array-and-i-have-data-in-the-table-xvOPgx.mdx index 6191835cbca..5e2c4be8278 100644 --- a/apps/docs/content/troubleshooting/why-is-my-select-returning-an-empty-data-array-and-i-have-data-in-the-table-xvOPgx.mdx +++ b/apps/docs/content/troubleshooting/why-is-my-select-returning-an-empty-data-array-and-i-have-data-in-the-table-xvOPgx.mdx @@ -9,9 +9,9 @@ database_id = "6fa68831-6db8-4836-a1b4-e9e51296d529" Usually this means you have RLS (row level security) enabled and no policy, or do not meet the policy. It can also mean you have a filter and have no rows matching that. -If you have RLS enabled you can test quickly by disable RLS on the table. If your query works then you have no policies or do not meet them. +If you have RLS enabled you can test by disabling RLS on the table. If your query works then you have no policies or do not meet them. -If you have policies that depend on having a signed in user (TO set to `authenticated` or using `auth.uid()`) then you can check by setting TO as `anon` and setting your policy to just `TRUE`. If that works then you don't have a signed in user (with a JWT in the authorization header) when you make the call. +If you have policies that depend on having a signed in user (TO set to `authenticated` or using `auth.uid()`) then you can check by setting TO as `anon` and setting your policy to `TRUE`. If that works then you don't have a signed in user (with a JWT in the authorization header) when you make the call. For more information on RLS see https://supabase.com/docs/guides/auth/row-level-security