From 0c86c269f5540bf8ef9c581e6405fd79d30ac3a5 Mon Sep 17 00:00:00 2001 From: kaghni Date: Mon, 19 Jan 2026 17:03:45 -0800 Subject: [PATCH 1/8] divided into smaller parts --- docs/docs/llms-supabase-cli.txt | 1466 + docs/docs/llms-supabase-csharp.txt | 1603 + docs/docs/llms-supabase-dart.txt | 2907 + docs/docs/llms-supabase-guides.txt | 106228 ++++++++++++++++++++++++++ docs/docs/llms-supabase-js.txt | 3940 + docs/docs/llms-supabase-kotlin.txt | 3173 + docs/docs/llms-supabase-main.txt | 10 + docs/docs/llms-supabase-python.txt | 3657 + docs/docs/llms-supabase-swift.txt | 3399 + docs/docs/llms.txt | 199 +- docs/docs/llms/python.txt | 646 + docs/docs/llms/tql.txt | 593 + docs/hooks/custom_hooks.py | 15 +- 13 files changed, 127639 insertions(+), 197 deletions(-) create mode 100644 docs/docs/llms-supabase-cli.txt create mode 100644 docs/docs/llms-supabase-csharp.txt create mode 100644 docs/docs/llms-supabase-dart.txt create mode 100644 docs/docs/llms-supabase-guides.txt create mode 100644 docs/docs/llms-supabase-js.txt create mode 100644 docs/docs/llms-supabase-kotlin.txt create mode 100644 docs/docs/llms-supabase-main.txt create mode 100644 docs/docs/llms-supabase-python.txt create mode 100644 docs/docs/llms-supabase-swift.txt create mode 100644 docs/docs/llms/python.txt create mode 100644 docs/docs/llms/tql.txt diff --git a/docs/docs/llms-supabase-cli.txt b/docs/docs/llms-supabase-cli.txt new file mode 100644 index 0000000000..39b8e8c187 --- /dev/null +++ b/docs/docs/llms-supabase-cli.txt @@ -0,0 +1,1466 @@ +Supabase CLI Reference + +# CLI Reference + +Bootstrap a Supabase project from a starter template + + + +supabase bootstrap [template] [flags] + +# CLI Reference + +Initialize a local project + + +Initialize configurations for Supabase local development. + +A `supabase/config.toml` file is created in your current working directory. This configuration is specific to each local project. + +> You may override the directory path by specifying the `SUPABASE_WORKDIR` environment variable or `--workdir` flag. + +In addition to `config.toml`, the `supabase` directory may also contain other Supabase objects, such as `migrations`, `functions`, `tests`, etc. + + +supabase init [flags] + +# CLI Reference + +Authenticate using an access token + + +Connect the Supabase CLI to your Supabase account by logging in with your [personal access token](https://supabase.com/dashboard/account/tokens). + +Your access token is stored securely in [native credentials storage](https://github.com/zalando/go-keyring#dependencies). If native credentials storage is unavailable, it will be written to a plain text file at `~/.supabase/access-token`. + +> If this behavior is not desired, such as in a CI environment, you may skip login by specifying the `SUPABASE_ACCESS_TOKEN` environment variable in other commands. + +The Supabase CLI uses the stored token to access Management APIs for projects, functions, secrets, etc. + + +supabase login [flags] + +# CLI Reference + +Link to a Supabase project + + +Link your local development project to a hosted Supabase project. + +PostgREST configurations are fetched from the Supabase platform and validated against your local configuration file. + +Optionally, database settings can be validated if you provide a password. Your database password is saved in native credentials storage if available. + +> If you do not want to be prompted for the database password, such as in a CI environment, you may specify it explicitly via the `SUPABASE_DB_PASSWORD` environment variable. + +Some commands like `db dump`, `db push`, and `db pull` require your project to be linked first. + + +supabase link [flags] + +# CLI Reference + +Start containers for Supabase local development + + +Starts the Supabase local development stack. + +Requires `supabase/config.toml` to be created in your current working directory by running `supabase init`. + +All service containers are started by default. You can exclude those not needed by passing in `-x` flag. To exclude multiple containers, either pass in a comma separated string, such as `-x gotrue,imgproxy`, or specify `-x` flag multiple times. + +> It is recommended to have at least 7GB of RAM to start all services. + +Health checks are automatically added to verify the started containers. Use `--ignore-health-check` flag to ignore these errors. + + +supabase start [flags] + +# CLI Reference + +Stop all local Supabase containers + + +Stops the Supabase local development stack. + +Requires `supabase/config.toml` to be created in your current working directory by running `supabase init`. + +All Docker resources are maintained across restarts. Use `--no-backup` flag to reset your local development data between restarts. + +Use the `--all` flag to stop all local Supabase projects instances on the machine. Use with caution with `--no-backup` as it will delete all supabase local projects data. + +supabase stop [flags] + +# CLI Reference + +Show status of local Supabase containers + + +Shows status of the Supabase local development stack. + +Requires the local development stack to be started by running `supabase start` or `supabase db start`. + +You can export the connection parameters for [initializing supabase-js](https://supabase.com/docs/reference/javascript/initializing) locally by specifying the `-o env` flag. Supported parameters include `JWT_SECRET`, `ANON_KEY`, and `SERVICE_ROLE_KEY`. + + +supabase status [flags] + +# CLI Reference + +Run tests on local Supabase containers + + + + + +# CLI Reference + +Tests local database with pgTAP + + +Executes pgTAP tests against the local database. + +Requires the local development stack to be started by running `supabase start`. + +Runs `pg_prove` in a container with unit test files volume mounted from `supabase/tests` directory. The test file can be suffixed by either `.sql` or `.pg` extension. + +Since each test is wrapped in its own transaction, it will be individually rolled back regardless of success or failure. + + +supabase test db [path] ... [flags] + +# CLI Reference + +Create a new test file + + + +supabase test new [flags] + +# CLI Reference + +Run code generation tools + + +Automatically generates type definitions based on your Postgres database schema. + +This command connects to your database (local or remote) and generates typed definitions that match your database tables, views, and stored procedures. By default, it generates TypeScript definitions, but also supports Go and Swift. + +Generated types give you type safety and autocompletion when working with your database in code, helping prevent runtime errors and improving developer experience. + +The types respect relationships, constraints, and custom types defined in your database schema. + + + + +# CLI Reference + +Generate a JWT signing key + +Securely generate a private JWT signing key for use in the CLI or to import in the dashboard. + +Supported algorithms: + ES256 - ECDSA with P-256 curve and SHA-256 (recommended) + RS256 - RSA with SHA-256 + + +supabase gen signing-key [flags] + +# CLI Reference + +Generate types from Postgres schema + + + +supabase gen types [flags] + +# CLI Reference + +Manage Postgres databases + + + + + +# CLI Reference + +Pull schema from the remote database + + +Pulls schema changes from a remote database. A new migration file will be created under `supabase/migrations` directory. + +Requires your local project to be linked to a remote database by running `supabase link`. For self-hosted databases, you can pass in the connection parameters using `--db-url` flag. + +> Note this command requires Docker Desktop (or a running Docker daemon), as it starts a local Postgres container to diff your remote schema. + +Optionally, a new row can be inserted into the migration history table to reflect the current state of the remote database. + +If no entries exist in the migration history table, `pg_dump` will be used to capture all contents of the remote schemas you have created. Otherwise, this command will only diff schema changes against the remote database, similar to running `db diff --linked`. + + +supabase db pull [migration name] [flags] + +# CLI Reference + +Push new migrations to the remote database + + +Pushes all local migrations to a remote database. + +Requires your local project to be linked to a remote database by running `supabase link`. For self-hosted databases, you can pass in the connection parameters using `--db-url` flag. + +The first time this command is run, a migration history table will be created under `supabase_migrations.schema_migrations`. After successfully applying a migration, a new row will be inserted into the migration history table with timestamp as its unique id. Subsequent pushes will skip migrations that have already been applied. + +If you need to mutate the migration history table, such as deleting existing entries or inserting new entries without actually running the migration, use the `migration repair` command. + +Use the `--dry-run` flag to view the list of changes before applying. + + +supabase db push [flags] + +# CLI Reference + +Resets the local database to current migrations + + +Resets the local database to a clean state. + +Requires the local development stack to be started by running `supabase start`. + +Recreates the local Postgres container and applies all local migrations found in `supabase/migrations` directory. If test data is defined in `supabase/seed.sql`, it will be seeded after the migrations are run. Any other data or schema changes made during local development will be discarded. + +When running db reset with `--linked` or `--db-url` flag, a SQL script is executed to identify and drop all user created entities in the remote database. Since Postgres roles are cluster level entities, any custom roles created through the dashboard or `supabase/roles.sql` will not be deleted by remote reset. + + +supabase db reset [flags] + +# CLI Reference + +Dumps data or schemas from the remote database + + +Dumps contents from a remote database. + +Requires your local project to be linked to a remote database by running `supabase link`. For self-hosted databases, you can pass in the connection parameters using `--db-url` flag. + +Runs `pg_dump` in a container with additional flags to exclude Supabase managed schemas. The ignored schemas include auth, storage, and those created by extensions. + +The default dump does not contain any data or custom roles. To dump those contents explicitly, specify either the `--data-only` and `--role-only` flag. + + +supabase db dump [flags] + +# CLI Reference + +Diffs the local database for schema changes + + +Diffs schema changes made to the local or remote database. + +Requires the local development stack to be running when diffing against the local database. To diff against a remote or self-hosted database, specify the `--linked` or `--db-url` flag respectively. + +Runs [djrobstep/migra](https://github.com/djrobstep/migra) in a container to compare schema differences between the target database and a shadow database. The shadow database is created by applying migrations in local `supabase/migrations` directory in a separate container. Output is written to stdout by default. For convenience, you can also save the schema diff as a new migration file by passing in `-f` flag. + +By default, all schemas in the target database are diffed. Use the `--schema public,extensions` flag to restrict diffing to a subset of schemas. + +While the diff command is able to capture most schema changes, there are cases where it is known to fail. Currently, this could happen if you schema contains: + +- Changes to publication +- Changes to storage buckets +- Views with `security_invoker` attributes + + +supabase db diff [flags] + +# CLI Reference + +Checks local database for typing error + + +Lints local database for schema errors. + +Requires the local development stack to be running when linting against the local database. To lint against a remote or self-hosted database, specify the `--linked` or `--db-url` flag respectively. + +Runs `plpgsql_check` extension in the local Postgres container to check for errors in all schemas. The default lint level is `warning` and can be raised to error via the `--level` flag. + +To lint against specific schemas only, pass in the `--schema` flag. + +The `--fail-on` flag can be used to control when the command should exit with a non-zero status code. The possible values are: + +- `none` (default): Always exit with a zero status code, regardless of lint results. +- `warning`: Exit with a non-zero status code if any warnings or errors are found. +- `error`: Exit with a non-zero status code only if errors are found. + +This flag is particularly useful in CI/CD pipelines where you want to fail the build based on certain lint conditions. + +supabase db lint [flags] + +# CLI Reference + +Starts local Postgres database + + + +supabase db start [flags] + +# CLI Reference + +Manage database migration scripts + + + + + +# CLI Reference + +Create an empty migration script + + +Creates a new migration file locally. + +A `supabase/migrations` directory will be created if it does not already exist in your current `workdir`. All schema migration files must be created in this directory following the pattern `_.sql`. + +Outputs from other commands like `db diff` may be piped to `migration new ` via stdin. + + +supabase migration new + +# CLI Reference + +List local and remote migrations + + +Lists migration history in both local and remote databases. + +Requires your local project to be linked to a remote database by running `supabase link`. For self-hosted databases, you can pass in the connection parameters using `--db-url` flag. + +> Note that URL strings must be escaped according to [RFC 3986](https://www.rfc-editor.org/rfc/rfc3986). + +Local migrations are stored in `supabase/migrations` directory while remote migrations are tracked in `supabase_migrations.schema_migrations` table. Only the timestamps are compared to identify any differences. + +In case of discrepancies between the local and remote migration history, you can resolve them using the `migration repair` command. + + +supabase migration list [flags] + +# CLI Reference + +Fetch migration files from history table + + + +supabase migration fetch [flags] + +# CLI Reference + +Repair the migration history table + + +Repairs the remote migration history table. + +Requires your local project to be linked to a remote database by running `supabase link`. + +If your local and remote migration history goes out of sync, you can repair the remote history by marking specific migrations as `--status applied` or `--status reverted`. Marking as `reverted` will delete an existing record from the migration history table while marking as `applied` will insert a new record. + +For example, your migration history may look like the table below, with missing entries in either local or remote. + +```bash +$ supabase migration list + LOCAL │ REMOTE │ TIME (UTC) + ─────────────────┼────────────────┼────────────────────── + │ 20230103054303 │ 2023-01-03 05:43:03 + 20230103054315 │ │ 2023-01-03 05:43:15 +``` + +To reset your migration history to a clean state, first delete your local migration file. + +```bash +$ rm supabase/migrations/20230103054315_remote_commit.sql + +$ supabase migration list + LOCAL │ REMOTE │ TIME (UTC) + ─────────────────┼────────────────┼────────────────────── + │ 20230103054303 │ 2023-01-03 05:43:03 +``` + +Then mark the remote migration `20230103054303` as reverted. + +```bash +$ supabase migration repair 20230103054303 --status reverted +Connecting to remote database... +Repaired migration history: [20220810154537] => reverted +Finished supabase migration repair. + +$ supabase migration list + LOCAL │ REMOTE │ TIME (UTC) + ─────────────────┼────────────────┼────────────────────── +``` + +Now you can run `db pull` again to dump the remote schema as a local migration file. + +```bash +$ supabase db pull +Connecting to remote database... +Schema written to supabase/migrations/20240414044403_remote_schema.sql +Update remote migration history table? [Y/n] +Repaired migration history: [20240414044403] => applied +Finished supabase db pull. + +$ supabase migration list + LOCAL │ REMOTE │ TIME (UTC) + ─────────────────┼────────────────┼────────────────────── + 20240414044403 │ 20240414044403 │ 2024-04-14 04:44:03 +``` + + +supabase migration repair [version] ... [flags] + +# CLI Reference + +Squash migrations to a single file + + +Squashes local schema migrations to a single migration file. + +The squashed migration is equivalent to a schema only dump of the local database after applying existing migration files. This is especially useful when you want to remove repeated modifications of the same schema from your migration history. + +However, one limitation is that data manipulation statements, such as insert, update, or delete, are omitted from the squashed migration. You will have to add them back manually in a new migration file. This includes cron jobs, storage buckets, and any encrypted secrets in vault. + +By default, the latest `_.sql` file will be updated to contain the squashed migration. You can override the target version using the `--version ` flag. + +If your `supabase/migrations` directory is empty, running `supabase squash` will do nothing. + + +supabase migration squash [flags] + +# CLI Reference + +Apply pending migrations to local database + + + +supabase migration up [flags] + +# CLI Reference + +Resets applied migrations up to the last n versions + + + +supabase migration down [flags] + +# CLI Reference + +Seed a Supabase project from supabase/config.toml + + + + + +# CLI Reference + +Seed buckets declared in [storage.buckets] + + + +supabase seed buckets + +# CLI Reference + +Tools to inspect your Supabase database + + + + + +# CLI Reference + +Estimates space allocated to a relation that is full of dead tuples + + + +This command displays an estimation of table "bloat" - Due to Postgres' [MVCC](https://www.postgresql.org/docs/current/mvcc.html) when data is updated or deleted new rows are created and old rows are made invisible and marked as "dead tuples". Usually the [autovaccum](https://supabase.com/docs/guides/platform/database-size#vacuum-operations) process will asynchronously clean the dead tuples. Sometimes the autovaccum is unable to work fast enough to reduce or prevent tables from becoming bloated. High bloat can slow down queries, cause excessive IOPS and waste space in your database. + +Tables with a high bloat ratio should be investigated to see if there are vacuuming is not quick enough or there are other issues. + +``` + TYPE │ SCHEMA NAME │ OBJECT NAME │ BLOAT │ WASTE + ────────┼─────────────┼────────────────────────────┼───────┼───────────── + table │ public │ very_bloated_table │ 41.0 │ 700 MB + table │ public │ my_table │ 4.0 │ 76 MB + table │ public │ happy_table │ 1.0 │ 1472 kB + index │ public │ happy_table::my_nice_index │ 0.7 │ 880 kB +``` + + +supabase inspect db bloat + +# CLI Reference + +Show queries that are holding locks and the queries that are waiting for them to be released + + + +This command shows you statements that are currently holding locks and blocking, as well as the statement that is being blocked. This can be used in conjunction with `inspect db locks` to determine which statements need to be terminated in order to resolve lock contention. + +``` + BLOCKED PID │ BLOCKING STATEMENT │ BLOCKING DURATION │ BLOCKING PID │ BLOCKED STATEMENT │ BLOCKED DURATION + ──────────────┼──────────────────────────────┼───────────────────┼──────────────┼────────────────────────────────────────────────────────────────────────────────────────┼─────────────────── + 253 │ select count(*) from mytable │ 00:00:03.838314 │ 13495 │ UPDATE "mytable" SET "updated_at" = '2023─08─03 14:07:04.746688' WHERE "id" = 83719341 │ 00:00:03.821826 +``` + + +supabase inspect db blocking + +# CLI Reference + +Show queries from pg_stat_statements ordered by total times called + + + +This command is much like the `supabase inspect db outliers` command, but ordered by the number of times a statement has been called. + +You can use this information to see which queries are called most often, which can potentially be good candidates for optimisation. + +``` + + QUERY │ TOTAL EXECUTION TIME │ PROPORTION OF TOTAL EXEC TIME │ NUMBER CALLS │ SYNC IO TIME + ─────────────────────────────────────────────────┼──────────────────────┼───────────────────────────────┼──────────────┼────────────────── + SELECT * FROM users WHERE id = $1 │ 14:50:11.828939 │ 89.8% │ 183,389,757 │ 00:00:00.002018 + SELECT * FROM user_events │ 01:20:23.466633 │ 1.4% │ 78,325 │ 00:00:00 + INSERT INTO users (email, name) VALUES ($1, $2)│ 00:40:11.616882 │ 0.8% │ 54,003 │ 00:00:00.000322 + +``` + + +supabase inspect db calls + +# CLI Reference + +Show stats such as cache hit rates, total sizes, and WAL size + + + + +supabase inspect db db-stats + +# CLI Reference + +Show combined index size, usage percent, scan counts, and unused status + + + + +supabase inspect db index-stats + +# CLI Reference + +Show queries which have taken out an exclusive lock on a relation + + + +This command displays queries that have taken out an exclusive lock on a relation. Exclusive locks typically prevent other operations on that relation from taking place, and can be a cause of "hung" queries that are waiting for a lock to be granted. + +If you see a query that is hanging for a very long time or causing blocking issues you may consider killing the query by connecting to the database and running `SELECT pg_cancel_backend(PID);` to cancel the query. If the query still does not stop you can force a hard stop by running `SELECT pg_terminate_backend(PID);` + +``` + PID │ RELNAME │ TRANSACTION ID │ GRANTED │ QUERY │ AGE + ─────────┼─────────┼────────────────┼─────────┼─────────────────────────────────────────┼─────────── + 328112 │ null │ 0 │ t │ SELECT * FROM logs; │ 00:04:20 +``` + + +supabase inspect db locks + +# CLI Reference + +Show currently running queries running for longer than 5 minutes + + + +This command displays currently running queries, that have been running for longer than 5 minutes, descending by duration. Very long running queries can be a source of multiple issues, such as preventing DDL statements completing or vacuum being unable to update `relfrozenxid`. + +``` + PID │ DURATION │ QUERY +───────┼─────────────────┼─────────────────────────────────────────────────────────────────────────────────────── + 19578 | 02:29:11.200129 | EXPLAIN SELECT "students".* FROM "students" WHERE "students"."id" = 1450645 LIMIT 1 + 19465 | 02:26:05.542653 | EXPLAIN SELECT "students".* FROM "students" WHERE "students"."id" = 1889881 LIMIT 1 + 19632 | 02:24:46.962818 | EXPLAIN SELECT "students".* FROM "students" WHERE "students"."id" = 1581884 LIMIT 1 +``` + + +supabase inspect db long-running-queries + +# CLI Reference + +Show queries from pg_stat_statements ordered by total execution time + + + +This command displays statements, obtained from `pg_stat_statements`, ordered by the amount of time to execute in aggregate. This includes the statement itself, the total execution time for that statement, the proportion of total execution time for all statements that statement has taken up, the number of times that statement has been called, and the amount of time that statement spent on synchronous I/O (reading/writing from the file system). + +Typically, an efficient query will have an appropriate ratio of calls to total execution time, with as little time spent on I/O as possible. Queries that have a high total execution time but low call count should be investigated to improve their performance. Queries that have a high proportion of execution time being spent on synchronous I/O should also be investigated. + +``` + + QUERY │ EXECUTION TIME │ PROPORTION OF EXEC TIME │ NUMBER CALLS │ SYNC IO TIME +─────────────────────────────────────────┼──────────────────┼─────────────────────────┼──────────────┼─────────────── + SELECT * FROM archivable_usage_events.. │ 154:39:26.431466 │ 72.2% │ 34,211,877 │ 00:00:00 + COPY public.archivable_usage_events (.. │ 50:38:33.198418 │ 23.6% │ 13 │ 13:34:21.00108 + COPY public.usage_events (id, reporte.. │ 02:32:16.335233 │ 1.2% │ 13 │ 00:34:19.784318 + INSERT INTO usage_events (id, retaine.. │ 01:42:59.436532 │ 0.8% │ 12,328,187 │ 00:00:00 + SELECT * FROM usage_events WHERE (alp.. │ 01:18:10.754354 │ 0.6% │ 102,114,301 │ 00:00:00 +``` + + +supabase inspect db outliers + +# CLI Reference + +Show information about replication slots on the database + + +This command shows information about [logical replication slots](https://www.postgresql.org/docs/current/logical-replication.html) that are setup on the database. It shows if the slot is active, the state of the WAL sender process ('startup', 'catchup', 'streaming', 'backup', 'stopping') the replication client address and the replication lag in GB. + +This command is useful to check that the amount of replication lag is as low as possible, replication lag can occur due to network latency issues, slow disk I/O, long running transactions or lack of ability for the subscriber to consume WAL fast enough. + + +``` + NAME │ ACTIVE │ STATE │ REPLICATION CLIENT ADDRESS │ REPLICATION LAG GB + ─────────────────────────────────────────────┼────────┼─────────┼────────────────────────────┼───────────────────── + supabase_realtime_replication_slot │ t │ N/A │ N/A │ 0 + datastream │ t │ catchup │ 24.201.24.106 │ 45 +``` + +supabase inspect db replication-slots + +# CLI Reference + +Show information about roles on the database + + + +supabase inspect db role-stats + +# CLI Reference + +Show combined table size, index size, and estimated row count + + + + +supabase inspect db table-stats + +# CLI Reference + +Show read/write activity ratio for tables based on block I/O operations + + + +This command analyzes table I/O patterns to show read/write activity ratios based on block-level operations. It combines data from PostgreSQL's `pg_stat_user_tables` (for tuple operations) and `pg_statio_user_tables` (for block I/O) to categorize each table's workload profile. + + +The command classifies tables into categories: +- **Read-Heavy** - Read operations are more than 5x write operations (e.g., 1:10, 1:50) +- **Write-Heavy** - Write operations are more than 20% of read operations (e.g., 1:2, 1:4, 2:1, 10:1) +- **Balanced** - Mixed workload where writes are between 20% and 500% of reads +- **Read-Only** - Only read operations detected +- **Write-Only** - Only write operations detected + +``` +SCHEMA │ TABLE │ BLOCKS READ │ WRITE TUPLES │ BLOCKS WRITE │ ACTIVITY RATIO +───────┼──────────────┼─────────────┼──────────────┼──────────────┼──────────────────── +public │ user_events │ 450,234 │ 9,004,680│ 23,450 │ 20:1 (Write-Heavy) +public │ users │ 89,203 │ 12,451│ 1,203 │ 7.2:1 (Read-Heavy) +public │ sessions │ 15,402 │ 14,823│ 2,341 │ ≈1:1 (Balanced) +public │ cache_data │ 123,456 │ 0│ 0 │ Read-Only +auth │ audit_logs │ 0 │ 98,234│ 12,341 │ Write-Only +``` + +**Note:** This command only displays tables that have had both read and write activity. Tables with no I/O operations are not shown. The classification ratio threshold (default: 5:1) determines when a table is considered "heavy" in one direction versus balanced. + + + +supabase inspect db traffic-profile + +# CLI Reference + +Show statistics related to vacuum operations per table + + +This shows you stats about the vacuum activities for each table. Due to Postgres' [MVCC](https://www.postgresql.org/docs/current/mvcc.html) when data is updated or deleted new rows are created and old rows are made invisible and marked as "dead tuples". Usually the [autovaccum](https://supabase.com/docs/guides/platform/database-size#vacuum-operations) process will aysnchronously clean the dead tuples. + +The command lists when the last vacuum and last auto vacuum took place, the row count on the table as well as the count of dead rows and whether autovacuum is expected to run or not. If the number of dead rows is much higher than the row count, or if an autovacuum is expected but has not been performed for some time, this can indicate that autovacuum is not able to keep up and that your vacuum settings need to be tweaked or that you require more compute or disk IOPS to allow autovaccum to complete. + + +``` + SCHEMA │ TABLE │ LAST VACUUM │ LAST AUTO VACUUM │ ROW COUNT │ DEAD ROW COUNT │ EXPECT AUTOVACUUM? +──────────────────────┼──────────────────────────────────┼─────────────┼──────────────────┼──────────────────────┼────────────────┼───────────────────── + auth │ users │ │ 2023-06-26 12:34 │ 18,030 │ 0 │ no + public │ profiles │ │ 2023-06-26 23:45 │ 13,420 │ 28 │ no + public │ logs │ │ 2023-06-26 01:23 │ 1,313,033 │ 3,318,228 │ yes + storage │ objects │ │ │ No stats │ 0 │ no + storage │ buckets │ │ │ No stats │ 0 │ no + supabase_migrations │ schema_migrations │ │ │ No stats │ 0 │ no + +``` + + +supabase inspect db vacuum-stats + +# CLI Reference + +Generate a CSV output for all inspect commands + + + +supabase inspect report [flags] + +# CLI Reference + +Manage Supabase organizations + + + + + +# CLI Reference + +Create an organization + +Create an organization for the logged-in user. + +supabase orgs create + +# CLI Reference + +List all organizations + +List all organizations the logged-in user belongs. + +supabase orgs list + +# CLI Reference + +Manage Supabase projects + + +Provides tools for creating and managing your Supabase projects. + +This command group allows you to list all projects in your organizations, create new projects, delete existing projects, and retrieve API keys. These operations help you manage your Supabase infrastructure programmatically without using the dashboard. + +Project management via CLI is especially useful for automation scripts and when you need to provision environments in a repeatable way. + + + + +# CLI Reference + +Create a project on Supabase + + + +supabase projects create [project name] [flags] + +# CLI Reference + +List all Supabase projects + +List all Supabase projects the logged-in user can access. + +supabase projects list + +# CLI Reference + +List all API keys for a Supabase project + + + +supabase projects api-keys [flags] + +# CLI Reference + +Delete a Supabase project + + + +supabase projects delete [ref] + +# CLI Reference + +Manage Supabase project configurations + + + + + +# CLI Reference + +Pushes local config.toml to the linked project + + +Updates the configurations of a linked Supabase project with the local `supabase/config.toml` file. + +This command allows you to manage project configuration as code by defining settings locally and then pushing them to your remote project. + + +supabase config push + +# CLI Reference + +Manage Supabase preview branches + + + + + +# CLI Reference + +Create a preview branch + +Create a preview branch for the linked project. + +supabase branches create [name] [flags] + +# CLI Reference + +List all preview branches + +List all preview branches of the linked project. + +supabase branches list + +# CLI Reference + +Retrieve details of a preview branch + +Retrieve details of the specified preview branch. + +supabase branches get [name] + +# CLI Reference + +Update a preview branch + +Update a preview branch by its name or ID. + +supabase branches update [name] [flags] + +# CLI Reference + +Pause a preview branch + + + +supabase branches pause [name] + +# CLI Reference + +Unpause a preview branch + + + +supabase branches unpause [name] + +# CLI Reference + +Delete a preview branch + +Delete a preview branch by its name or ID. + +supabase branches delete [name] + +# CLI Reference + +Manage Supabase Edge functions + + +Manage Supabase Edge Functions. + +Supabase Edge Functions are server-less functions that run close to your users. + +Edge Functions allow you to execute custom server-side code without deploying or scaling a traditional server. They're ideal for handling webhooks, custom API endpoints, data validation, and serving personalized content. + +Edge Functions are written in TypeScript and run on Deno compatible edge runtime, which is a secure runtime with no package management needed, fast cold starts, and built-in security. + + + + +# CLI Reference + +Create a new Function locally + + +Creates a new Edge Function with boilerplate code in the `supabase/functions` directory. + +This command generates a starter TypeScript file with the necessary Deno imports and a basic function structure. The function is created as a new directory with the name you specify, containing an `index.ts` file with the function code. + +After creating the function, you can edit it locally and then use `supabase functions serve` to test it before deploying with `supabase functions deploy`. + + +supabase functions new + +# CLI Reference + +List all Functions in Supabase + +List all Functions in the linked Supabase project. + +supabase functions list [flags] + +# CLI Reference + +Download a Function from Supabase + +Download the source code for a Function from the linked Supabase project. + + +supabase functions download [flags] + +# CLI Reference + +Serve all Functions locally + + +Serve all Functions locally. + +`supabase functions serve` command includes additional flags to assist developers in debugging Edge Functions via the v8 inspector protocol, allowing for debugging via Chrome DevTools, VS Code, and IntelliJ IDEA for example. Refer to the [docs guide](/docs/guides/functions/debugging-tools) for setup instructions. + +1. `--inspect` + * Alias of `--inspect-mode brk`. + +2. `--inspect-mode [ run | brk | wait ]` + * Activates the inspector capability. + * `run` mode simply allows a connection without additional behavior. It is not ideal for short scripts, but it can be useful for long-running scripts where you might occasionally want to set breakpoints. + * `brk` mode same as `run` mode, but additionally sets a breakpoint at the first line to pause script execution before any code runs. + * `wait` mode similar to `brk` mode, but instead of setting a breakpoint at the first line, it pauses script execution until an inspector session is connected. + +3. `--inspect-main` + * Can only be used when one of the above two flags is enabled. + * By default, creating an inspector session for the main worker is not allowed, but this flag allows it. + * Other behaviors follow the `inspect-mode` flag mentioned above. + +Additionally, the following properties can be customized via `supabase/config.toml` under `edge_runtime` section. + +1. `inspector_port` + * The port used to listen to the Inspector session, defaults to 8083. +2. `policy` + * A value that indicates how the edge-runtime should forward incoming HTTP requests to the worker. + * `per_worker` allows multiple HTTP requests to be forwarded to a worker that has already been created. + * `oneshot` will force the worker to process a single HTTP request and then exit. (Debugging purpose, This is especially useful if you want to reflect changes you've made immediately.) + + +supabase functions serve [flags] + +# CLI Reference + +Deploy a Function to Supabase + +Deploy a Function to the linked Supabase project. + +supabase functions deploy [Function name] [flags] + +# CLI Reference + +Delete a Function from Supabase + +Delete a Function from the linked Supabase project. This does NOT remove the Function locally. + + +supabase functions delete [flags] + +# CLI Reference + +Manage Supabase secrets + + +Provides tools for managing environment variables and secrets for your Supabase project. + +This command group allows you to set, unset, and list secrets that are securely stored and made available to Edge Functions as environment variables. + +Secrets management through the CLI is useful for: +- Setting environment-specific configuration +- Managing sensitive credentials securely + +Secrets can be set individually or loaded from .env files for convenience. + + + + +# CLI Reference + +Set a secret(s) on Supabase + +Set a secret(s) to the linked Supabase project. + +supabase secrets set ... [flags] + +# CLI Reference + +List all secrets on Supabase + +List all secrets in the linked project. + +supabase secrets list + +# CLI Reference + +Unset a secret(s) on Supabase + +Unset a secret(s) from the linked Supabase project. + +supabase secrets unset [NAME] ... + +# CLI Reference + +Manage Supabase Storage objects + + + + + +# CLI Reference + +List objects by path prefix + + + +supabase storage ls [path] [flags] + +# CLI Reference + +Copy objects from src to dst path + +Relies on standard uploads to move files between local and remote storage. [Not suitable for moving files over 6MB in size](https://supabase.com/docs/guides/storage/uploads/standard-uploads?queryGroups=language&language=js#uploading). + + +supabase storage cp [flags] + +# CLI Reference + +Move objects from src to dst path + + + +supabase storage mv [flags] + +# CLI Reference + +Remove objects by file path + + + +supabase storage rm ... [flags] + +# CLI Reference + +Manage Single Sign-On (SSO) authentication for projects + + + + + +# CLI Reference + +Add a new SSO identity provider + +Add and configure a new connection to a SSO identity provider to your Supabase project. + + +supabase sso add [flags] + +# CLI Reference + +List all SSO identity providers for a project + +List all connections to a SSO identity provider to your Supabase project. + + +supabase sso list + +# CLI Reference + +Show information about an SSO identity provider + +Provides the information about an established connection to an identity provider. You can use --metadata to obtain the raw SAML 2.0 Metadata XML document stored in your project's configuration. + + +supabase sso show [flags] + +# CLI Reference + +Returns the SAML SSO settings required for the identity provider + + +Returns all of the important SSO information necessary for your project to be registered with a SAML 2.0 compatible identity provider. + + +supabase sso info + +# CLI Reference + +Update information about an SSO identity provider + +Update the configuration settings of a already added SSO identity provider. + + +supabase sso update [flags] + +# CLI Reference + +Remove an existing SSO identity provider + +Remove a connection to an already added SSO identity provider. Removing the provider will prevent existing users from logging in. Please treat this command with care. + + +supabase sso remove + +# CLI Reference + +Manage custom domain names for Supabase projects + +Manage custom domain names for Supabase projects. + +Use of custom domains and vanity subdomains is mutually exclusive. + + + + +# CLI Reference + +Activate the custom hostname for a project + + +Activates the custom hostname configuration for a project. + +This reconfigures your Supabase project to respond to requests on your custom hostname. + +After the custom hostname is activated, your project's third-party auth providers will no longer function on the Supabase-provisioned subdomain. Please refer to [Prepare to activate your domain](/docs/guides/platform/custom-domains#prepare-to-activate-your-domain) section in our documentation to learn more about the steps you need to follow. + + +supabase domains activate + +# CLI Reference + +Create a custom hostname + +Create a custom hostname for your Supabase project. + +Expects your custom hostname to have a CNAME record to your Supabase project's subdomain. + +supabase domains create [flags] + +# CLI Reference + +Get the current custom hostname config + +Retrieve the custom hostname config for your project, as stored in the Supabase platform. + + +supabase domains get + +# CLI Reference + +Re-verify the custom hostname config for your project + + + +supabase domains reverify + +# CLI Reference + +Deletes the custom hostname config for your project + + + +supabase domains delete + +# CLI Reference + +Manage vanity subdomains for Supabase projects + +Manage vanity subdomains for Supabase projects. + +Usage of vanity subdomains and custom domains is mutually exclusive. + + + +# CLI Reference + +Activate a vanity subdomain + +Activate a vanity subdomain for your Supabase project. + +This reconfigures your Supabase project to respond to requests on your vanity subdomain. +After the vanity subdomain is activated, your project's auth services will no longer function on the {project-ref}.{supabase-domain} hostname. + + +supabase vanity-subdomains activate [flags] + +# CLI Reference + +Get the current vanity subdomain + + + +supabase vanity-subdomains get + +# CLI Reference + +Checks if a desired subdomain is available for use + + + +supabase vanity-subdomains check-availability [flags] + +# CLI Reference + +Deletes a project's vanity subdomain + +Deletes the vanity subdomain for a project, and reverts to using the project ref for routing. + + +supabase vanity-subdomains delete + +# CLI Reference + +Manage network bans + +Network bans are IPs that get temporarily blocked if their traffic pattern looks abusive (e.g. multiple failed auth attempts). + +The subcommands help you view the current bans, and unblock IPs if desired. + + + +# CLI Reference + +Get the current network bans + + + +supabase network-bans get + +# CLI Reference + +Remove a network ban + + + +supabase network-bans remove [flags] + +# CLI Reference + +Manage network restrictions + + + + + +# CLI Reference + +Get the current network restrictions + + + +supabase network-restrictions get + +# CLI Reference + +Update network restrictions + + + +supabase network-restrictions update [flags] + +# CLI Reference + +Manage SSL enforcement configuration + + + + + +# CLI Reference + +Get the current SSL enforcement configuration + + + +supabase ssl-enforcement get + +# CLI Reference + +Update SSL enforcement configuration + + + +supabase ssl-enforcement update [flags] + +# CLI Reference + +Manage Postgres database config + + + + + +# CLI Reference + +Get the current Postgres database config overrides + + + +supabase postgres-config get + +# CLI Reference + +Update Postgres database config + +Overriding the default Postgres config could result in unstable database behavior. +Custom configuration also overrides the optimizations generated based on the compute add-ons in use. + +supabase postgres-config update [flags] + +# CLI Reference + +Delete specific Postgres database config overrides + +Delete specific config overrides, reverting them to their default values. + + +supabase postgres-config delete [flags] + +# CLI Reference + +Manage Supabase SQL snippets + + + + + +# CLI Reference + +List all SQL snippets + +List all SQL snippets of the linked project. + +supabase snippets list + +# CLI Reference + +Download contents of a SQL snippet + +Download contents of the specified SQL snippet. + +supabase snippets download + +# CLI Reference + +Show versions of all Supabase services + + + +supabase services + +# CLI Reference + +Generate the autocompletion script for the specified shell + +Generate the autocompletion script for supabase for the specified shell. +See each sub-command's help for details on how to use the generated script. + + + + +# CLI Reference + +Generate the autocompletion script for zsh + +Generate the autocompletion script for the zsh shell. + +If shell completion is not already enabled in your environment you will need +to enable it. You can execute the following once: + + echo "autoload -U compinit; compinit" >> ~/.zshrc + +To load completions in your current shell session: + + source <(supabase completion zsh) + +To load completions for every new session, execute once: + +#### Linux: + + supabase completion zsh > "${fpath[1]}/_supabase" + +#### macOS: + + supabase completion zsh > $(brew --prefix)/share/zsh/site-functions/_supabase + +You will need to start a new shell for this setup to take effect. + + +supabase completion zsh [flags] + +# CLI Reference + +Generate the autocompletion script for powershell + +Generate the autocompletion script for powershell. + +To load completions in your current shell session: + + supabase completion powershell | Out-String | Invoke-Expression + +To load completions for every new session, add the output of the above command +to your powershell profile. + + +supabase completion powershell [flags] + +# CLI Reference + +Generate the autocompletion script for fish + +Generate the autocompletion script for the fish shell. + +To load completions in your current shell session: + + supabase completion fish | source + +To load completions for every new session, execute once: + + supabase completion fish > ~/.config/fish/completions/supabase.fish + +You will need to start a new shell for this setup to take effect. + + +supabase completion fish [flags] + +# CLI Reference + +Generate the autocompletion script for bash + +Generate the autocompletion script for the bash shell. + +This script depends on the 'bash-completion' package. +If it is not installed already, you can install it via your OS's package manager. + +To load completions in your current shell session: + + source <(supabase completion bash) + +To load completions for every new session, execute once: + +#### Linux: + + supabase completion bash > /etc/bash_completion.d/supabase + +#### macOS: + + supabase completion bash > $(brew --prefix)/etc/bash_completion.d/supabase + +You will need to start a new shell for this setup to take effect. + + +supabase completion bash \ No newline at end of file diff --git a/docs/docs/llms-supabase-csharp.txt b/docs/docs/llms-supabase-csharp.txt new file mode 100644 index 0000000000..387991f025 --- /dev/null +++ b/docs/docs/llms-supabase-csharp.txt @@ -0,0 +1,1603 @@ +Supabase Reference (C#) + +# C# Reference + +Initializing + +Initializing a new client is pretty straightforward. Find your project url and public key from the +admin panel and pass it into your client initialization function. + +`Supabase` is heavily dependent on Models deriving from `BaseModel`. To interact with the API, one must have the associated model (see example) specified. + +Leverage `Table`, `PrimaryKey`, and `Column` attributes to specify names of classes/properties that are different from their C# Versions. + + +## Examples + +### Standard + +```c# +var url = Environment.GetEnvironmentVariable("SUPABASE_URL"); +var key = Environment.GetEnvironmentVariable("SUPABASE_KEY"); + +var options = new Supabase.SupabaseOptions +{ + AutoConnectRealtime = true +}; + +var supabase = new Supabase.Client(url, key, options); +await supabase.InitializeAsync(); +``` + + +### Dependency Injection (Maui-like) + +```c# +public static MauiApp CreateMauiApp() +{ + // ... + var builder = MauiApp.CreateBuilder(); + + var url = Environment.GetEnvironmentVariable("SUPABASE_URL"); + var key = Environment.GetEnvironmentVariable("SUPABASE_KEY"); + var options = new SupabaseOptions + { + AutoRefreshToken = true, + AutoConnectRealtime = true, + // SessionHandler = new SupabaseSessionHandler() <-- This must be implemented by the developer + }; + + // Note the creation as a singleton. + builder.Services.AddSingleton(provider => new Supabase.Client(url, key, options)); +} +``` + + +### With Models Example + +```c# +// Given the following Model representing the Supabase Database (Message.cs) +[Table("messages")] +public class Message : BaseModel +{ + [PrimaryKey("id")] + public int Id { get; set; } + + [Column("username")] + public string UserName { get; set; } + + [Column("channel_id")] + public int ChannelId { get; set; } + + public override bool Equals(object obj) + { + return obj is Message message && + Id == message.Id; + } + + public override int GetHashCode() + { + return HashCode.Combine(Id); + } +} + +void Initialize() +{ + // Get All Messages + var response = await client.Table().Get(); + List models = response.Models; + + // Insert + var newMessage = new Message { UserName = "acupofjose", ChannelId = 1 }; + await client.Table().Insert(); + + // Update + var model = response.Models.First(); + model.UserName = "elrhomariyounes"; + await model.Update(); + + // Delete + await response.Models.Last().Delete(); + + // etc. +} +``` + + +# C# Reference + +Fetch data: Select() + +Performs vertical filtering with SELECT. + + +## Examples + +### Getting your data + +```c# +// Given the following Model (City.cs) +[Table("cities")] +class City : BaseModel +{ + [PrimaryKey("id")] + public int Id { get; set; } + + [Column("name")] + public string Name { get; set; } + + [Column("country_id")] + public int CountryId { get; set; } + + //... etc. +} + +// A result can be fetched like so. +var result = await supabase.From().Get(); +var cities = result.Models +``` + + +### Selecting specific columns + +```c# +// Given the following Model (Movie.cs) +[Table("movies")] +class Movie : BaseModel +{ + [PrimaryKey("id")] + public int Id { get; set; } + + [Column("name")] + public string Name { get; set; } + + [Column("created_at")] + public DateTime CreatedAt { get; set; } + + //... etc. +} + +// A result can be fetched like so. +var result = await supabase + .From() + .Select(x => new object[] {x.Name, x.CreatedAt}) + .Get(); +``` + + +### Query foreign tables + +```c# +var data = await supabase + .From() + .Select("id, supplier:supplier_id(name), purchaser:purchaser_id(name)") + .Get(); +``` + + +### Filtering with inner joins + +```c# +var result = await supabase + .From() + .Select("*, users!inner(*)") + .Filter("user.username", Operator.Equals, "Jane") + .Get(); +``` + + +### Querying with count option + +```c# +var count = await supabase + .From() + .Select(x => new object[] { x.Name }) + .Count(CountType.Exact); +``` + + +### Querying JSON data + +```c# + var result = await supabase + .From() + .Select("id, name, address->street") + .Filter("address->postcode", Operator.Equals, 90210) + .Get(); +``` + + +# C# Reference + +Create data: Insert() + +Performs an INSERT into the table. + + +## Examples + +### Create a record + +```c# +[Table("cities")] +class City : BaseModel +{ + [PrimaryKey("id", false)] + public int Id { get; set; } + + [Column("name")] + public string Name { get; set; } + + [Column("country_id")] + public int CountryId { get; set; } +} + +var model = new City +{ + Name = "The Shire", + CountryId = 554 +}; + +await supabase.From().Insert(model); +``` + + +### Bulk create + +```c# +[Table("cities")] +class City : BaseModel +{ + [PrimaryKey("id", false)] + public int Id { get; set; } + + [Column("name")] + public string Name { get; set; } + + [Column("country_id")] + public int CountryId { get; set; } +} + +var models = new List +{ + new City { Name = "The Shire", CountryId = 554 }, + new City { Name = "Rohan", CountryId = 553 }, +}; + +await supabase.From().Insert(models); +``` + + +### Fetch inserted record + +```c# +var result = await supabase + .From() + .Insert(models, new QueryOptions { Returning = ReturnType.Representation }); +``` + + +# C# Reference + +Modify data: Update() + +Performs an UPDATE on the table. + + +## Examples + +### Update your data using Filter + +```c# +var update = await supabase + .From() + .Where(x => x.Name == "Auckland") + .Set(x => x.Name, "Middle Earth") + .Update(); +``` + + +### Update your data + +```c# +var model = await supabase + .From() + .Where(x => x.Name == "Auckland") + .Single(); + +model.Name = "Middle Earth"; + +await model.Update(); +``` + + +# C# Reference + +Upsert data: Upsert() + +Performs an UPSERT into the table. + + +## Examples + +### Upsert your data + +```c# +var model = new City +{ + Id = 554, + Name = "Middle Earth" +}; + +await supabase.From().Upsert(model); +``` + + +### Upserting into tables with constraints + +```c# +var model = new City +{ + Id = 554, + Name = "Middle Earth" +}; + +await supabase + .From() + .OnConflict(x => x.Name) + .Upsert(model); +``` + + +### Return the exact number of rows + +```c# +var model = new City +{ + Id = 554, + Name = "Middle Earth" +}; + +await supabase + .From() + .Upsert(model, new QueryOptions { Count = QueryOptions.CountType.Exact }); +``` + + +# C# Reference + +Delete data: Delete() + +Performs a DELETE on the table. + + +## Examples + +### Delete records + +```c# +await supabase + .From() + .Where(x => x.Id == 342) + .Delete(); +``` + + +# C# Reference + +Stored Procedures: Rpc() + +You can call stored procedures as a "Remote Procedure Call". + +That's a fancy way of saying that you can put some logic into your database then call it from anywhere. +It's especially useful when the logic rarely changes - like password resets and updates. + + +## Examples + +### Call a stored procedure + +```c# +await supabase.Rpc("hello_world", null); +``` + + +### With Parameters + +```c# +await supabase.Rpc("hello_world", new Dictionary { { "foo", "bar"} }); +``` + + +# C# Reference + +Using Filters + +Filters allow you to only return rows that match certain conditions. + +Filters can be used on `Select()`, `Update()`, and `Delete()` queries. + +**Note: LINQ expressions do not currently support parsing embedded resource columns. For these cases, `string` will need to be used.** + + +## Examples + +### Applying Filters + +```c# +var result = await supabase.From() + .Select(x => new object[] { x.Name, x.CountryId }) + .Where(x => x.Name == "The Shire") + .Single(); +``` + + +### Filter by values within a JSON column + +```c# +var result = await supabase.From() + .Filter("address->postcode", Operator.Equals, 90210) + .Get(); +``` + + +### Filter Foreign Tables + +```c# +var results = await supabase.From() + .Select("name, cities!inner(name)") + .Filter("cities.name", Operator.Equals, "Bali") + .Get(); +``` + + +# C# Reference + +Operator.Equals + +Finds all rows whose value on the stated `column` exactly matches the specified `value`. + + +## Examples + +### With `Select()` + +```c# +var result = await supabase.From() + .Where(x => x.Name == "Bali") + .Get(); +``` + + +# C# Reference + +Operator.NotEqual + +Finds all rows whose value on the stated `column` doesn't match the specified `value`. + + +## Examples + +### With `Select()` + +```c# +var result = await supabase.From() + .Select(x => new object[] { x.Name, x.CountryId }) + .Where(x => x.Name != "Bali") + .Get(); +``` + + +# C# Reference + +Operator.GreaterThan + +Finds all rows whose value on the stated `column` is greater than the specified `value`. + + +## Examples + +### With `Select()` + +```c# +var result = await supabase.From() + .Select(x => new object[] { x.Name, x.CountryId }) + .Where(x => x.CountryId > 250) + .Get(); +``` + + +# C# Reference + +Operator.GreaterThanOrEqual + +Finds all rows whose value on the stated `column` is greater than or equal to the specified `value`. + + +## Examples + +### With `Select()` + +```c# +var result = await supabase.From() + .Select(x => new object[] { x.Name, x.CountryId }) + .Where(x => x.CountryId >= 250) + .Get(); +``` + + +# C# Reference + +Operator.LessThan + +Finds all rows whose value on the stated `column` is less than the specified `value`. + + +## Examples + +### With `Select()` + +```c# +var result = await supabase.From() + .Select("name, country_id") + .Where(x => x.CountryId < 250) + .Get(); +``` + + +# C# Reference + +Operator.LessThanOrEqual + +Finds all rows whose value on the stated `column` is less than or equal to the specified `value`. + + +## Examples + +### With `Select()` + +```c# +var result = await supabase.From() + .Where(x => x.CountryId <= 250) + .Get(); +``` + + +# C# Reference + +Operator.Like + +Finds all rows whose value in the stated `column` matches the supplied `pattern` (case sensitive). + + +## Examples + +### With `Select()` + +```c# +var result = await supabase.From() + .Filter(x => x.Name, Operator.Like, "%la%") + .Get(); +``` + + +# C# Reference + +Operator.ILike + +Finds all rows whose value in the stated `column` matches the supplied `pattern` (case insensitive). + + +## Examples + +### With `Select()` + +```c# +await supabase.From() + .Filter(x => x.Name, Operator.ILike, "%la%") + .Get(); +``` + + +# C# Reference + +Operator.Is + +A check for exact equality (null, true, false), finds all rows whose value on the stated `column` exactly match the specified `value`. + + +## Examples + +### With `Select()` + +```c# +var result = await supabase.From() + .Where(x => x.Name == null + .Get(); +``` + + +# C# Reference + +Operator.In + +Finds all rows whose value on the stated `column` is found on the specified `values`. + + +## Examples + +### With `Select()` + +```c# +var result = await supabase.From() + .Filter(x => x.Name, Operator.In, new List { "Rio de Janiero", "San Francisco" }) + .Get(); +``` + + +# C# Reference + +Operator.Contains + + + +## Examples + +### With `Select()` + +```c# +var result = await supabase.From() + .Filter(x => x.MainExports, Operator.Contains, new List { "oil", "fish" }) + .Get(); +``` + + +# C# Reference + +Operator.ContainedIn + + + +## Examples + +### With `Select()` + +```c# +var result = await supabase.From() + .Filter(x => x.MainExports, Operator.ContainedIn, new List { "oil", "fish" }) + .Get(); +``` + + +# C# Reference + +Operator.[FTS,PLFTS,PHFTS,WFTS] (Full Text Search) + +Finds all rows whose tsvector value on the stated `column` matches to_tsquery(query). + + +## Examples + +### Text search + +```c# +var result = await supabase.From() + .Select(x => x.Catchphrase) + .Filter(x => x.Catchphrase, Operator.FTS, new FullTextSearchConfig("'fat' & 'cat", "english")) + .Get(); +``` + + +### Basic normalization + +```c# +var result = await supabase.From() + .Select(x => x.Catchphrase) + .Filter(x => x.Catchphrase, Operator.PLFTS, new FullTextSearchConfig("'fat' & 'cat", "english")) + .Get(); +``` + + +### Full normalization + +```c# +var result = await supabase.From() + .Select(x => x.Catchphrase) + .Filter(x => x.Catchphrase, Operator.PHFTS, new FullTextSearchConfig("'fat' & 'cat", "english")) + .Get(); +``` + + +### Websearch + +```c# +var result = await supabase.From() + .Select(x => x.Catchphrase) + .Filter(x => x.Catchphrase, Operator.WFTS, new FullTextSearchConfig("'fat' & 'cat", "english")) + .Get(); +``` + + +# C# Reference + +Match() + +- Finds a model given a class (useful when hydrating models and correlating with database) +- Finds all rows whose columns match the specified `Dictionary` object. + + +## Examples + +### With Model + +```c# +var city = new City +{ + Id = 224, + Name = "Atlanta" +}; + +var model = supabase.From().Match(city).Single(); +``` + + +### With Dictionary + +```c# +var opts = new Dictionary +{ + {"name","Beijing"}, + {"country_id", "156"} +}; + +var model = supabase.From().Match(opts).Single(); +``` + + +# C# Reference + +Not() + +Finds all rows which doesn't satisfy the filter. + + +## Examples + +### With `Select()` + +```c# +var result = await supabase.From() + .Select(x => new object[] { x.Name, x.CountryId }) + .Where(x => x.Name != "Paris") + .Get(); +``` + + +# C# Reference + +Or() + +Finds all rows satisfying at least one of the filters. + + +## Examples + +### With `Select()` + +```c# +var result = await supabase.From() + .Where(x => x.Id == 20 || x.Id == 30) + .Get(); +``` + + +### Use `or` with `and` + +```c# +var result = await supabase.From() + .Where(x => x.Population > 300000 || x.BirthRate < 0.6) + .Where(x => x.Name != "Mordor") + .Get(); +``` + + +# C# Reference + +Using Modifiers + +Filters work on the row level—they allow you to return rows that +only match certain conditions without changing the shape of the rows. +Modifiers are everything that don't fit that definition—allowing you to +change the format of the response (e.g., setting a limit or offset). + + +## Examples + + + +# C# Reference + +Order() + +Orders the result with the specified column. + + +## Examples + +### With `Select()` + +```c# +var result = await supabase.From() + .Select(x => new object[] { x.Name, x.CountryId }) + .Order(x => x.Id, Ordering.Descending) + .Get(); +``` + + +### With embedded resources + +```c# + var result = await supabase.From() + .Select("name, cities(name)") + .Filter(x => x.Name == "United States") + .Order("cities", "name", Ordering.Descending) + .Get(); +``` + + +# C# Reference + +Limit() + +Limits the result with the specified count. + + +## Examples + +### With `Select()` + +```c# +var result = await supabase.From() + .Select(x => new object[] { x.Name, x.CountryId }) + .Limit(10) + .Get(); +``` + + +### With embedded resources + +```c# +var result = await supabase.From() + .Select("name, cities(name)") + .Filter("name", Operator.Equals, "United States") + .Limit(10, "cities") + .Get(); +``` + + +# C# Reference + +Range() + +Limits the result to rows within the specified range, inclusive. + + +## Examples + +### With `Select()` + +```c# +var result = await supabase.From() + .Select("name, country_id") + .Range(0, 3) + .Get(); +``` + + +# C# Reference + +Single() + +Retrieves only one row from the result. Result must be one row (e.g. using limit), otherwise this will result in an error. + + +## Examples + +### With `Select()` + +```c# +var result = await supabase.From() + .Select(x => new object[] { x.Name, x.CountryId }) + .Single(); +``` + + +# C# Reference + +SignUp() + +Creates a new user. + + +## Examples + +### Sign up. + +```c# +var session = await supabase.Auth.SignUp(email, password); +``` + + +# C# Reference + +StateChanged + +Receive a notification every time an auth event happens. + + +## Examples + +### Listen to auth changes + +```c# +supabase.Auth.AddStateChangedListener((sender, changed) => +{ + switch (changed) + { + case AuthState.SignedIn: + break; + case AuthState.SignedOut: + break; + case AuthState.UserUpdated: + break; + case AuthState.PasswordRecovery: + break; + case AuthState.TokenRefreshed: + break; + } +}); +``` + + +# C# Reference + +SignIn(email, password) + +Log in an existing user using email or phone number with password. + + +## Examples + +### Sign in with email and password + +```c# +var session = await supabase.Auth.SignIn(email, password); +``` + + +### Sign in with phone and password + +```c# +var session = await supabase.Auth.SignIn(SignInType.Phone, phoneNumber, password); +``` + + +# C# Reference + +SendMagicLink() and SignIn(SignInType, Phone) + + + +## Examples + +### Send Magic Link. + +```c# +var options = new SignInOptions { RedirectTo = "http://myredirect.example" }; +var didSendMagicLink = await supabase.Auth.SendMagicLink("joseph@supabase.io", options); +``` + + +### Sign in with SMS OTP. + +```c# +await supabase.Auth.SignIn(SignInType.Phone, "+13334445555"); + +// Paired with `VerifyOTP` to get a session +var session = await supabase.Auth.VerifyOTP("+13334445555", TOKEN, MobileOtpType.SMS); +``` + + +# C# Reference + +SignIn(Provider) + +Signs the user in using third party OAuth providers. + + +## Examples + +### Sign in using a third-party provider + +```c# +var signInUrl = supabase.Auth.SignIn(Provider.Github); +``` + + +### With scopes + +```c# +var signInUrl = supabase.Auth.SignIn(Provider.Github, 'repo gist notifications'); + +// after user comes back from signin flow +var session = supabase.Auth.GetSessionFromUrl(REDIRECTED_URI); +``` + + +# C# Reference + +SignOut() + +Signs out the current user, if there is a logged in user. + + +## Examples + +### Sign out + +```c# +await supabase.Auth.SignOut(); +``` + + +# C# Reference + +VerifyOtp() + + + +## Examples + +### Verify Sms One-Time Password (OTP) + +```c# +var session = await supabase.Auth.VerifyOTP("+13334445555", TOKEN, MobileOtpType.SMS); +``` + + +# C# Reference + +CurrentSession + +Returns the session data, if there is an active session. + + +## Examples + +### Get the session data + +```c# +var session = supabase.Auth.CurrentSession; +``` + + +# C# Reference + +CurrentUser + +Returns the user data, if there is a logged in user. + + +## Examples + +### Get the logged in user + +```c# +var user = supabase.Auth.CurrentUser; +``` + + +# C# Reference + +UpdateUser() + +Updates user data, if there is a logged in user. + + +## Examples + +### Update the email for an authenticated user + +```c# +var attrs = new UserAttributes { Email = "new-email@example.com" }; +var response = await supabase.Auth.Update(attrs); +``` + + +### Update the password for an authenticated user + +```c# +var attrs = new UserAttributes { Password = "***********" }; +var response = await supabase.Auth.Update(attrs); +``` + + +### Update the user's metadata + +```c# +var attrs = new UserAttributes +{ + Data = new Dictionary { {"example", "data" } } +}; +var response = await supabase.Auth.Update(attrs); +``` + + +# C# Reference + +invoke() + +Invokes a Supabase Function. See the [guide](/docs/guides/functions) for details on writing Functions. + + +## Examples + +### Basic invocation. + +```c# +var options = new InvokeFunctionOptions +{ + Headers = new Dictionary {{ "Authorization", "Bearer 1234" }}, + Body = new Dictionary { { "foo", "bar" } } +}; + +await supabase.Functions.Invoke("hello", options: options); +``` + + +### Modeled invocation + +``` c# +class HelloResponse +{ + [JsonProperty("name")] + public string Name { get; set; } +} + +await supabase.Functions.Invoke("hello"); +``` + + +# C# Reference + +Realtime.Channel + +Subscribe to realtime changes in your database. + + +## Examples + +### Listen to broadcast messages + +```c# +class CursorBroadcast : BaseBroadcast +{ + [JsonProperty("cursorX")] + public int CursorX {get; set;} + + [JsonProperty("cursorY")] + public int CursorY {get; set;} +} + +var channel = supabase.Realtime.Channel("any"); +var broadcast = channel.Register(); +broadcast.AddBroadcastEventHandler((sender, baseBroadcast) => +{ + var response = broadcast.Current(); +}); + +await channel.Subscribe(); + +// Send a broadcast +await broadcast.Send("cursor", new CursorBroadcast { CursorX = 123, CursorY = 456 }); +``` + + +### Listen to presence sync + +```c# + class UserPresence : BasePresence + { + [JsonProperty("cursorX")] + public bool IsTyping {get; set;} + + [JsonProperty("onlineAt")] + public DateTime OnlineAt {get; set;} + } + + var channel = supabase.Realtime.Channel("any"); + var presenceKey = Guid.NewGuid().ToString(); + var presence = channel.Register(presenceKey); + presence.AddPresenceEventHandler(EventType.Sync, (sender, type) => + { + Debug.WriteLine($"The Event Type: {type}"); + var state = presence.CurrentState; + }); + + await channel.Subscribe(); + + // Send a presence update + await presence.Track(new UserPresence { IsTyping = false, OnlineAt = DateTime.Now }); +``` + + +### Listening to a specific table + +```c# +await supabase.From().On(ListenType.All, (sender, change) => +{ + Debug.WriteLine(change.Payload.Data); +}); +``` + + +### Listen to all database changes + +```c# +var channel = supabase.Realtime.Channel("realtime", "public", "*"); + +channel.AddPostgresChangeHandler(ListenType.All, (sender, change) => +{ + // The event type + Debug.WriteLine(change.Event); + // The changed record + Debug.WriteLine(change.Payload); +}); + +await channel.Subscribe(); +``` + + +### Listening to inserts + +```c# +await supabase.From().On(ListenType.Inserts, (sender, change) => +{ + Debug.WriteLine(change.Payload.Data); +}); +``` + + +### Listening to updates + +```c# +await supabase.From().On(ListenType.Updates, (sender, change) => +{ + Debug.WriteLine(change.Payload.Data); +}); +``` + + +### Listening to deletes + +```c# +await supabase.From().On(ListenType.Deletes, (sender, change) => +{ + Debug.WriteLine(change.Payload.Data); +}); +``` + + +### Listening to row level changes + +```c# +var channel = supabase.Realtime.Channel("realtime", "public", "countries", "id", "id=eq.200"); + +channel.AddPostgresChangeHandler(ListenType.All, (sender, change) => +{ + // The event type + Debug.WriteLine(change.Event); + // The changed record + Debug.WriteLine(change.Payload); +}); + +await channel.Subscribe(); +``` + + +# C# Reference + +Unsubscribe() + +Unsubscribes and removes Realtime channel from Realtime client. + + +## Examples + +### Remove a channel + +```c# +var channel = await supabase.From().On(ChannelEventType.All, (sender, change) => { }); +channel.Unsubscribe(); + +// OR + +var channel = supabase.Realtime.Channel("realtime", "public", "*"); +channel.Unsubscribe() +``` + + +# C# Reference + +Subscriptions + +Returns all Realtime channels. + + +## Examples + +### Get all channels + +```c# +var channels = supabase.Realtime.Subscriptions; +``` + + +# C# Reference + +Overview + + + +## Examples + + + +# C# Reference + +ListBuckets() + +Retrieves the details of all Storage buckets within an existing product. + + +## Examples + +### List buckets + +```c# +var buckets = await supabase.Storage.ListBuckets(); +``` + + +# C# Reference + +GetBucket() + +Retrieves the details of an existing Storage bucket. + + +## Examples + +### Get bucket + +```c# +var bucket = await supabase.Storage.GetBucket("avatars"); +``` + + +# C# Reference + +CreateBucket() + +Creates a new Storage bucket + + +## Examples + +### Create bucket + +```c# +var bucket = await supabase.Storage.CreateBucket("avatars"); +``` + + +# C# Reference + +EmptyBucket() + +Removes all objects inside a single bucket. + + +## Examples + +### Empty bucket + +```c# +var bucket = await supabase.Storage.EmptyBucket("avatars"); +``` + + +# C# Reference + +UpdateBucket() + +Updates a new Storage bucket + + +## Examples + +### Update bucket + +```c# +var bucket = await supabase.Storage.UpdateBucket("avatars", new BucketUpsertOptions { Public = false }); +``` + + +# C# Reference + +DeleteBucket() + +Deletes an existing bucket. A bucket can't be deleted with existing objects inside it. You must first `empty()` the bucket. + + +## Examples + +### Delete bucket + +```dart +var result = await supabase.Storage.DeleteBucket("avatars"); +``` + + +# C# Reference + +From().Upload() + +Uploads a file to an existing bucket. + + +## Examples + +### Upload file + +```c# +var imagePath = Path.Combine("Assets", "fancy-avatar.png"); + +await supabase.Storage + .From("avatars") + .Upload(imagePath, "fancy-avatar.png", new FileOptions { CacheControl = "3600", Upsert = false }); +``` + + +### Upload file with Progress + +```c# +var imagePath = Path.Combine("Assets", "fancy-avatar.png"); + +await supabase.Storage + .From("avatars") + .Upload(imagePath, "fancy-avatar.png", onProgress: (sender, progress) => Debug.WriteLine($"{progress}%")); +``` + + +# C# Reference + +From().update() + +Replaces an existing file at the specified path with a new one. + + +## Examples + +### Update file + +```c# +var imagePath = Path.Combine("Assets", "fancy-avatar.png"); +await supabase.Storage.From("avatars").Update(imagePath, "fancy-avatar.png"); +``` + + +# C# Reference + +From().Move() + +Moves an existing file, optionally renaming it at the same time. + + +## Examples + +### Move file + +```c# +await supabase.Storage.From("avatars") + .Move("public/fancy-avatar.png", "private/fancy-avatar.png"); +``` + + +# C# Reference + +From().CreateSignedUrl() + +Create signed url to download file without requiring permissions. This URL can be valid for a set number of seconds. + + +## Examples + +### Create Signed URL + +```c# +var url = await supabase.Storage.From("avatars").CreateSignedUrl("public/fancy-avatar.png", 60); +``` + + +# C# Reference + +from.getPublicUrl() + +Retrieve URLs for assets in public buckets + + +## Examples + +### Returns the URL for an asset in a public bucket + +```c# +var publicUrl = supabase.Storage.From("avatars").GetPublicUrl("public/fancy-avatar.png"); +``` + + +# C# Reference + +From().Download() + +Downloads a file. + + +## Examples + +### Download file + +```c# +var bytes = await supabase.Storage.From("avatars").Download("public/fancy-avatar.png"); +``` + + +### Download file with Progress + +```c# +var bytes = await supabase.Storage + .From("avatars") + .Download("public/fancy-avatar.png", (sender, progress) => Debug.WriteLine($"{progress}%")); +``` + + +# C# Reference + +From().Remove() + +Deletes files within the same bucket + + +## Examples + +### Delete file + +```c# +await supabase.Storage.From("avatars").Remove(new List { "public/fancy-avatar.png" }); +``` + + +# C# Reference + +From().list() + +Lists all the files within a bucket. + + +## Examples + +### List files in a bucket + +```c# +var objects = await supabase.Storage.From("avatars").List(); +``` diff --git a/docs/docs/llms-supabase-dart.txt b/docs/docs/llms-supabase-dart.txt new file mode 100644 index 0000000000..727d78424b --- /dev/null +++ b/docs/docs/llms-supabase-dart.txt @@ -0,0 +1,2907 @@ +Supabase Reference (Dart) + +# Dart Reference + +Initializing + +You can initialize Supabase with the static `initialize()` method of the `Supabase` class. + +The Supabase client is your entrypoint to the rest of the Supabase functionality +and is the easiest way to interact with everything we offer within the Supabase ecosystem. + + +## Examples + +### For Flutter + +```dart +Future main() async { + await Supabase.initialize( + url: 'https://xyzcompany.supabase.co', + anonKey: 'publishable-or-anon-key', + ); + + runApp(MyApp()); +} + +// Get a reference your Supabase client +final supabase = Supabase.instance.client; +``` + + +### For other Dart projects + +```dart +final supabase = SupabaseClient( + 'https://xyzcompany.supabase.co', + 'publishable-or-anon-key', +); +``` + + +# Dart Reference + +Fetch data: select() + +Perform a SELECT query on the table or view. + + +## Examples + +### Getting your data + +```dart +final data = await supabase + .from('instruments') + .select(); +``` + + +### Selecting specific columns + +```dart +final data = await supabase + .from('instruments') + .select(''' + name + '''); +``` + + +### Query referenced tables + +```dart +final data = await supabase + .from('orchestral_sections') + .select(''' + name, + instruments ( name ) + '''); +``` + + +### Query referenced tables through a join table + +```dart +final data = await supabase + .from('users') + .select(''' + name, + teams ( + name + ) + '''); + ``` + + +### Query the same referenced table multiple times + +```dart +final data = await supabase + .from('messages') + .select(''' + content, + from:sender_id(name), + to:receiver_id(name) + '''); +``` + + +### Filtering through referenced tables + +```dart +final data = await supabase + .from('instruments') + .select('name, orchestral_sections(*)') + .eq('orchestral_sections.name', 'percussion'); +``` + + +### Querying with count option + +```dart +final res = await supabase + .from('instruments') + .select('name') + .count(CountOption.exact); + +final data = res.data; +final count = res.count; +``` + + +### Querying JSON data + +```dart +final data = await supabase + .from('users') + .select(''' + id, name, + address->city + '''); +``` + + +### Querying referenced table with inner join + +```dart +final data = await supabase + .from('orchestral_sections') + .select('name, instruments!inner(name)') + .eq('orchestral_sections.name', 'strings') + .limit(1); +``` + + +### Switching schemas per query + +```dart +final data = await supabase + .schema('myschema') + .from('mytable') + .select(); +``` + + +# Dart Reference + +Create data: insert() + +Perform an INSERT into the table or view. + + +## Examples + +### Create a record + +```dart +await supabase + .from('cities') + .insert({'name': 'The Shire', 'country_id': 554}); +``` + + +### Fetch inserted record + +```dart +final List> data = + await supabase.from('cities').insert([ + {'name': 'The Shire', 'country_id': 554}, + {'name': 'Rohan', 'country_id': 555}, + ]).select(); +``` + + +### Bulk create + +```dart +await supabase.from('cities').insert([ + {'name': 'The Shire', 'country_id': 554}, + {'name': 'Rohan', 'country_id': 555}, +]); +``` + + +# Dart Reference + +Modify data: update() + +Perform an UPDATE on the table or view. + + +## Examples + +### Update your data + +```dart +await supabase + .from('instruments') + .update({ 'name': 'piano' }) + .eq('id', 1); +``` + + +### Update a record and return it + +```dart +final data = await supabase + .from('instruments') + .update({ 'name': 'piano' }) + .eq('id', 1) + .select(); +``` + + +### Update JSON data + +```dart +await supabase + .from('users') + .update({ + 'address': { + 'street': 'Melrose Place', + 'postcode': 90210 + } + }) + .eq('address->postcode', 90210); +``` + + +# Dart Reference + +Upsert data: upsert() + +Perform an UPSERT on the table or view. Depending on the column(s) passed to `onConflict`, `.upsert()` allows you to perform the equivalent of `.insert()` if a row with the corresponding `onConflict` columns doesn't exist, or if it does exist, perform an alternative action depending on `ignoreDuplicates`. + + +## Examples + +### Upsert your data + +```dart +final data = await supabase + .from('instruments') + .upsert({ 'id': 1, 'name': 'piano' }) + .select(); +``` + + +### Bulk Upsert your data + +```dart +final data = await supabase + .from('instruments') + .upsert([ + { 'id': 1, 'name': 'piano' }, + { 'id': 2, 'name': 'harp' }, + ]) + .select(); +``` + + +### Upserting into tables with constraints + +```dart +final data = await supabase + .from('users') + .upsert({ 'id': 42, 'handle': 'saoirse', 'display_name': 'Saoirse' }, { onConflict: 'handle' }) + .select(); +``` + + +# Dart Reference + +Delete data: delete() + +Perform a DELETE on the table or view. + + +## Examples + +### Delete records + +```dart +await supabase + .from('countries') + .delete() + .eq('id', 1); +``` + + +### Delete multiple records + +```dart +await supabase + .from('countries') + .delete() + .inFilter('id', [1, 2, 3]) +``` + + +### Fetch deleted records + +```dart +final List> data = await supabase + .from('cities') + .delete() + .match({ 'id': 666 }) + .select(); +``` + + +# Dart Reference + +Stored Procedures: rpc() + +Perform a function call. + +You can call Postgres functions as Remote Procedure Calls, logic in your database that you can execute from anywhere. +Functions are useful when the logic rarely changes—like for password resets and updates. + + +## Examples + +### Call a Postgres function without arguments + +```dart +final data = await supabase + .rpc('hello_world'); +``` + + +### Call a Postgres function with arguments + +```dart +final data = await supabase + .rpc('echo_city', params: { 'say': '👋' }); +``` + + +### Bulk processing + +```dart +final data = await supabase + .rpc('add_one_each', params: { arr: [1, 2, 3] }); +``` + + +### Call a Postgres function with filters + +```dart +final data = await supabase + .rpc('list_stored_countries') + .eq('id', 1) + .single(); +``` + + +# Dart Reference + +Using Filters + +Filters allow you to only return rows that match certain conditions. + +Filters can be used on `select()`, `update()`, `upsert()`, and `delete()` queries. + +If a Database function returns a table response, you can also apply filters. + + +## Examples + +### Applying Filters + +```dart +final data = await supabase + .from('cities') + .select('name, country_id') + .eq('name', 'The Shire'); // Correct + +final data = await supabase + .from('cities') + .eq('name', 'The Shire') // Incorrect + .select('name, country_id'); +``` + + +### Chaining Filters + +```dart +final data = await supabase + .from('cities') + .select('name, country_id') + .gte('population', 1000) + .lt('population', 10000) +``` + + +### Conditional Chaining + +```dart +final filterByName = null; +final filterPopLow = 1000; +final filterPopHigh = 10000; + +var query = supabase + .from('cities') + .select('name, country_id'); + +if (filterByName != null) query = query.eq('name', filterByName); +if (filterPopLow != null) query = query.gte('population', filterPopLow); +if (filterPopHigh != null) query = query.lt('population', filterPopHigh); + +final data = await query; +``` + + +### Filter by values within a JSON column + +```dart +final data = await supabase + .from('users') + .select() + .eq('address->postcode', 90210); +``` + + +### Filter Referenced Tables + +```dart +final data = await supabase + .from('orchestral_sections') + .select(''' + name, + instruments!inner ( + name + ) + ''') + .eq('instruments.name', 'flute'); +``` + + +# Dart Reference + +eq() + +Match only rows where `column` is equal to `value`. + + +## Examples + +### With select() + +```dart +final data = await supabase + .from('instruments') + .select() + .eq('name', 'viola'); +``` + + +# Dart Reference + +neq() + +Finds all rows whose value on the stated `column` doesn't match the specified `value`. + + +## Examples + +### With select() + +```dart +final data = await supabase + .from('instruments') + .select('id, name') + .neq('name', 'viola'); +``` + + +# Dart Reference + +gt() + +Finds all rows whose value on the stated `column` is greater than the specified `value`. + + +## Examples + +### With select() + +```dart +final data = await supabase + .from('countries') + .select() + .gt('id', 2); +``` + + +# Dart Reference + +gte() + +Finds all rows whose value on the stated `column` is greater than or equal to the specified `value`. + + +## Examples + +### With select() + +```dart +final data = await supabase + .from('countries') + .select() + .gte('id', 2); +``` + + +# Dart Reference + +lt() + +Finds all rows whose value on the stated `column` is less than the specified `value`. + + +## Examples + +### With select() + +```dart +final data = await supabase + .from('countries') + .select() + .lt('id', 2); +``` + + +# Dart Reference + +lte() + +Finds all rows whose value on the stated `column` is less than or equal to the specified `value`. + + +## Examples + +### With select() + +```dart +final data = await supabase + .from('countries') + .select() + .lte('id', 2); +``` + + +# Dart Reference + +like() + +Finds all rows whose value in the stated `column` matches the supplied `pattern` (case sensitive). + + +## Examples + +### With select() + +```dart +final data = await supabase + .from('planets') + .select() + .like('name', '%Ea%'); +``` + + +# Dart Reference + +ilike() + +Finds all rows whose value in the stated `column` matches the supplied `pattern` (case insensitive). + + +## Examples + +### With select() + +```dart +final data = await supabase + .from('planets') + .select() + .ilike('name', '%ea%'); +``` + + +# Dart Reference + +isFilter() + +A check for exact equality (null, true, false), finds all rows whose value on the stated `column` exactly match the specified `value`. + + +## Examples + +### Checking for nullness, true or false + +```dart +final data = await supabase + .from('countries') + .select() + .isFilter('name', null); +``` + + +# Dart Reference + +inFilter() + +Finds all rows whose value on the stated `column` is found on the specified `values`. + + +## Examples + +### With select() + +```dart +final data = await supabase + .from('characters') + .select() + .inFilter('name', ['Luke', 'Leia']); +``` + + +# Dart Reference + +contains() + +Only relevant for jsonb, array, and range columns. Match only rows where `column` contains every element appearing in `value`. + +## Examples + +### On array columns + +```dart +final data = await supabase + .from('issues') + .select() + .contains('tags', ['is:open', 'priority:low']); +``` + + +### On range columns + +```dart +final data = await supabase + .from('reservations') + .select() + .contains('during', '[2000-01-01 13:00, 2000-01-01 13:30)'); +``` + + +### On `jsonb` columns + +```dart +final data = await supabase + .from('users') + .select('name') + .contains('address', { 'street': 'Melrose Place' }); +``` + + +# Dart Reference + +containedBy() + +Only relevant for jsonb, array, and range columns. Match only rows where every element appearing in `column` is contained by `value`. + + +## Examples + +### On array columns + +```dart +final data = await supabase + .from('classes') + .select('name') + .containedBy('days', ['monday', 'tuesday', 'wednesday', 'friday']); +``` + + +### On range columns + +```dart +final data = await supabase + .from('reservations') + .select() + .containedBy('during', '[2000-01-01 00:00, 2000-01-01 23:59)'); +``` + + +### On `jsonb` columns + +```dart +final data = await supabase + .from('users') + .select('name') + .containedBy('address', {'postcode': 90210}); +``` + + +# Dart Reference + +rangeGt() + +Only relevant for range columns. Match only rows where every element in `column` is greater than any element in `range`. + + +## Examples + +### With select() + +```dart +final data = await supabase + .from('reservations') + .select() + .rangeGt('during', '[2000-01-02 08:00, 2000-01-02 09:00)'); +``` + + +# Dart Reference + +rangeGte() + +Only relevant for range columns. Match only rows where every element in `column` is either contained in `range` or greater than any element in `range`. + + +## Examples + +### With select() + +```dart +final data = await supabase + .from('reservations') + .select() + .rangeGte('during', '[2000-01-02 08:30, 2000-01-02 09:30)'); +``` + + +# Dart Reference + +rangeLt() + +Only relevant for range columns. Match only rows where every element in `column` is less than any element in `range`. + + +## Examples + +### With select() + +```dart +final data = await supabase + .from('reservations') + .select() + .rangeLt('during', '[2000-01-01 15:00, 2000-01-01 16:00)'); +``` + + +# Dart Reference + +rangeLte() + +Only relevant for range columns. Match only rows where every element in `column` is either contained in `range` or less than any element in `range`. + + +## Examples + +### With select() + +```dart +final data = await supabase + .from('reservations') + .select() + .rangeLte('during', '[2000-01-01 15:00, 2000-01-01 16:00)'); +``` + + +# Dart Reference + +rangeAdjacent() + +Only relevant for range columns. Match only rows where `column` is mutually exclusive to `range` and there can be no element between the two ranges. + + +## Examples + +### With select() + +```dart +final data = await supabase + .from('reservations') + .select() + .rangeAdjacent('during', '[2000-01-01 12:00, 2000-01-01 13:00)'); +``` + + +# Dart Reference + +overlaps() + +Only relevant for array and range columns. Match only rows where `column` and `value` have an element in common. + + +## Examples + +### On array columns + +```dart +final data = await supabase + .from('issues') + .select('title') + .overlaps('tags', ['is:closed', 'severity:high']); +``` + + +### On range columns + +```dart +final data = await supabase + .from('reservations') + .select() + .overlaps('during', '[2000-01-01 12:45, 2000-01-01 13:15)'); +``` + + +# Dart Reference + +textSearch() + +Finds all rows whose tsvector value on the stated `column` matches to_tsquery(query). + + +## Examples + +### Text search + +```dart +final data = await supabase + .from('quotes') + .select('catchphrase') + .textSearch('content', "'eggs' & 'ham'", + config: 'english' + ); +``` + + +### Basic normalization + +```dart +final data = await supabase + .from('quotes') + .select('catchphrase') + .textSearch('catchphrase', "'fat' & 'cat'", + type: TextSearchType.plain, + config: 'english' + ); +``` + + +### Full normalization + +```dart +final data = await supabase + .from('quotes') + .select('catchphrase') + .textSearch('catchphrase', "'fat' & 'cat'", + type: TextSearchType.phrase, + config: 'english' + ); +``` + + +### Websearch + +```dart +final data = await supabase + .from('quotes') + .select('catchphrase') + .textSearch('catchphrase', "'fat or cat'", + type: TextSearchType.websearch, + config: 'english' + ); +``` + + +# Dart Reference + +match() + +Finds all rows whose columns match the specified `query` object. + + +## Examples + +### With select() + +```dart +final data = await supabase + .from('instruments') + .select() + .match({ 'id': 2, 'name': 'viola' }); +``` + + +# Dart Reference + +not() + +Finds all rows which doesn't satisfy the filter. + + +## Examples + +### With select() + +```dart +final data = await supabase + .from('countries') + .select() + .not('name', 'is', null) +``` + + +### With update() + +```dart +final data = await supabase + .from('cities') + .update({ 'name': 'Mordor' }) + .not('name', 'eq', 'Rohan'); +``` + + +### With delete() + +```dart +final data = await supabase + .from('cities') + .delete() + .not('name', 'eq', 'Mordor'); +``` + + +### With rpc() + +```dart +// Only valid if the Stored Procedure returns a table type. +final data = await supabase + .rpc('echo_all_cities') + .not('name', 'eq', 'Mordor'); +``` + + +# Dart Reference + +or() + +Finds all rows satisfying at least one of the filters. + + +## Examples + +### With select() + +```dart +final data = await supabase + .from('instruments') + .select('name') + .or('id.eq.2,name.eq.cello'); +``` + + +### Use `or` with `and` + +```dart +final data = await supabase + .from('instruments') + .select('name') + .or('id.gt.3,and(id.eq.1,name.eq.violin)'); +``` + + +### Use `or` on referenced tables + +```dart +final data = await supabase + .from('orchestral_sections') + .select(''' + name, + instruments!inner ( + name + ) + ''') + .or('section_id.eq.1,name.eq.guzheng', referencedTable: 'instruments' ); +``` + + +# Dart Reference + +filter() + +Match only rows which satisfy the filter. This is an escape hatch - you should use the specific filter methods wherever possible. + + +## Examples + +### With select() + +```dart +final data = await supabase + .from('characters') + .select() + .filter('name', 'in', '("Ron","Dumbledore")') +``` + + +### With update() + +```dart +final data = await supabase + .from('instruments') + .update({ 'name': 'piano' }) + .filter('name', 'in', '("harpsichord","clavichord")'); +``` + + +### With delete() + +```dart +final data = await supabase + .from('countries') + .delete() + .filter('name', 'in', '("Rohan","Mordor")'); +``` + + +### With rpc() + +```dart +// Only valid if the Stored Procedure returns a table type. +final data = await supabase + .rpc('echo_all_countries') + .filter('name', 'in', '("Rohan","Mordor")'); +``` + + +### On a referenced table + +```dart +final data = await supabase + .from('orchestral_sections') + .select(''' + name, + instruments!inner ( + name + ) + ''') + .filter('characters.name', 'eq', 'flute') +``` + + +# Dart Reference + +Using Modifiers + +Filters work on the row level. That is, they allow you to return rows that +only match certain conditions without changing the shape of the rows. +Modifiers are everything that don't fit that definition—allowing you to +change the format of the response (e.g., returning a CSV string). + +Modifiers must be specified after filters. Some modifiers only apply for +queries that return rows (e.g., `select()` or `rpc()` on a function that +returns a table response). + + +## Examples + + + +# Dart Reference + +select() + + + +## Examples + +### With `upsert()` + +```dart +final data = await supabase + .from('instruments') + .upsert({ 'id': 1, 'name': 'piano' }) + .select(); +``` + + +# Dart Reference + +order() + +Orders the result with the specified column. + + +## Examples + +### With select() + +```dart +final data = await supabase + .from('instruments') + .select('id, name') + .order('id', ascending: false); +``` + + +### On a referenced table + +```dart +final data = await supabase + .from('orchestral_sections') + .select(''' + name, + instruments ( + name + ) + ''') + .order('name', referencedTable: 'instruments', ascending: false); + ``` + + +### Order parent table by a referenced table + +```dart +final data = await supabase + .from('instruments') + .select(''' + name, + section:orchestral_sections ( + name + ) + ''') + .order('section(name)', ascending: true) +``` + + +# Dart Reference + +limit() + +Limits the result with the specified count. + + +## Examples + +### With select() + +```dart +final data = await supabase + .from('instruments') + .select('name') + .limit(1); +``` + + +### On a referenced table + +```dart +final data = await supabase + .from('orchestral_sections') + .select(''' + name, + instruments ( + name + ) + ''') + .limit(1, referencedTable: 'instruments'); +``` + + +# Dart Reference + +range() + +Limits the result to rows within the specified range, inclusive. + + +## Examples + +### With select() + +```dart +final data = await supabase + .from('instruments') + .select('name') + .range(0, 1); +``` + + +# Dart Reference + +single() + +Retrieves only one row from the result. Result must be one row (e.g. using limit), otherwise this will result in an error. + + +## Examples + +### With select() + +```dart +final data = await supabase + .from('instruments') + .select('name') + .limit(1) + .single(); +``` + + +# Dart Reference + +maybeSingle() + + + +## Examples + +### With `select()` + +```dart +final data = await supabase + .from('instruments') + .select() + .eq('name', 'guzheng') + .maybeSingle(); +``` + + +# Dart Reference + +csv() + + + +## Examples + +### Return data as CSV + +```dart +final data = await supabase + .from('instruments') + .select() + .csv(); +``` + + +# Dart Reference + +Using Explain + +For debugging slow queries, you can get the [Postgres `EXPLAIN` execution plan](https://www.postgresql.org/docs/current/sql-explain.html) of a query +using the `explain()` method. This works on any query, even for `rpc()` or writes. + +Explain is not enabled by default as it can reveal sensitive information about your database. +It's best to only enable this for testing environments but if you wish to enable it for production you can provide additional protection by using a `pre-request` function. + +Follow the [Performance Debugging Guide](/docs/guides/database/debugging-performance) to enable the functionality on your project. + + +## Examples + +### Get the execution plan + +```dart +final data = await supabase + .from('instruments') + .select() + .explain(); +``` + + +### Get the execution plan with analyze and verbose + +```dart +final data = await supabase + .from('instruments') + .select() + .explain(analyze:true, verbose:true); +``` + + +# Dart Reference + +signUp() + +Creates a new user. + + +## Examples + +### Sign up with an email and password + +```dart +final AuthResponse res = await supabase.auth.signUp( + email: 'example@email.com', + password: 'example-password', +); +final Session? session = res.session; +final User? user = res.user; +``` + + +### Sign up with a phone number and password (SMS) + +```dart +final AuthResponse res = await supabase.auth.signUp( + phone: '123456789', + password: 'example-password', + channel: OtpChannel.sms, +); +``` + + +### Sign up with additional metadata + +```dart +final AuthResponse res = await supabase.auth.signUp( + email: 'example@email.com', + password: 'example-password', + data: {'username': 'my_user_name'}, +); +final Session? session = res.session; +final User? user = res.user; +``` + + +### Sign up with redirect URL + +```dart +final AuthResponse res = await supabase.auth.signUp( + email: 'example@email.com', + password: 'example-password', + emailRedirectTo: 'com.supabase.myapp://callback', +); +final Session? session = res.session; +final User? user = res.user; +``` + + +# Dart Reference + +onAuthStateChange() + +Receive a notification every time an auth event happens. + + +## Examples + +### Listen to auth changes + +```dart +final authSubscription = supabase.auth.onAuthStateChange.listen((data) { + final AuthChangeEvent event = data.event; + final Session? session = data.session; + + print('event: $event, session: $session'); + + switch (event) { + case AuthChangeEvent.initialSession: + // handle initial session + case AuthChangeEvent.signedIn: + // handle signed in + case AuthChangeEvent.signedOut: + // handle signed out + case AuthChangeEvent.passwordRecovery: + // handle password recovery + case AuthChangeEvent.tokenRefreshed: + // handle token refreshed + case AuthChangeEvent.userUpdated: + // handle user updated + case AuthChangeEvent.userDeleted: + // handle user deleted + case AuthChangeEvent.mfaChallengeVerified: + // handle mfa challenge verified + } +}); +``` + + +### Listen to a specific event + +```dart +final authSubscription = supabase.auth.onAuthStateChange.listen((data) { + final AuthChangeEvent event = data.event; + if (event == AuthChangeEvent.signedIn) { + // handle signIn + } +}); +``` + + +### Unsubscribe from auth subscription + +```dart +final authSubscription = supabase.auth.onAuthStateChange.listen((data) {}); + +authSubscription.cancel(); +``` + + +# Dart Reference + +signInAnonymously() + +Creates an anonymous user. + + +## Examples + +### Create an anonymous user + +```dart +await supabase.auth.signInAnonymously(); +``` + + +### Create an anonymous user with custom user metadata + +```dart +await supabase.auth.signInAnonymously( + data: {'hello': 'world'}, +); +``` + + +# Dart Reference + +signInWithPassword() + +Log in an existing user using email or phone number with password. + + +## Examples + +### Sign in with email and password + +```dart +final AuthResponse res = await supabase.auth.signInWithPassword( + email: 'example@email.com', + password: 'example-password', +); +final Session? session = res.session; +final User? user = res.user; +``` + + +### Sign in with phone and password + +```dart +final AuthResponse res = await supabase.auth.signInWithPassword( + phone: '+13334445555', + password: 'example-password', +); +final Session? session = res.session; +final User? user = res.user; +``` + + +# Dart Reference + +signInWithIdToken() + +Allows you to perform native Google, Apple, and Facebook sign in by combining it with [google_sign_in](https://pub.dev/packages/google_sign_in), [sign_in_with_apple](https://pub.dev/packages/sign_in_with_apple), or [flutter_facebook_auth](https://pub.dev/packages/flutter_facebook_auth) packages. + + +## Examples + +### Native Google sign in + +```dart +import 'package:google_sign_in/google_sign_in.dart'; +import 'package:supabase_flutter/supabase_flutter.dart'; + +const webClientId = ''; + +const iosClientId = ' signInWithFacebook() async { + final LoginResult result = await FacebookAuth.instance.login( + permissions: ['public_profile', 'email'], + ); + + if (result.status == LoginStatus.success) { + final accessToken = result.accessToken!.tokenString; + + final response = await supabase.auth.signInWithIdToken( + provider: OAuthProvider.facebook, + idToken: accessToken, + ); + } else { + throw const AuthException( + 'Facebook login failed: ${result.status}', + ); + } +} +``` + + +# Dart Reference + +signInWithOtp() + + + +## Examples + +### Sign in with email. + +```dart +await supabase.auth.signInWithOtp( + email: 'example@email.com', + emailRedirectTo: kIsWeb ? null : 'io.supabase.flutter://signin-callback/', +); +``` + + +### Sign in with SMS OTP. + +```dart +await supabase.auth.signInWithOtp( + phone: '+13334445555', +); +``` + + +### Sign in with WhatsApp OTP + +```dart +await supabase.auth.signInWithOtp( + phone: '+13334445555', + channel: OtpChannel.whatsapp, +); +``` + + +# Dart Reference + +signInWithOAuth() + +Signs the user in using third-party OAuth providers. + + +## Examples + +### Sign in using a third-party provider + +```dart +await supabase.auth.signInWithOAuth( + OAuthProvider.github, + redirectTo: kIsWeb ? null : 'my.scheme://my-host', // Optionally set the redirect link to bring back the user via deeplink. + authScreenLaunchMode: + kIsWeb ? LaunchMode.platformDefault : LaunchMode.externalApplication, // Launch the auth screen in a new webview on mobile. +); +``` + + +### With `redirectTo` + +```dart +await supabase.auth.signInWithOAuth( + OAuthProvider.github, + redirectTo: kIsWeb ? null : 'io.supabase.flutter://reset-callback/', +); +``` + + +### With scopes + +```dart +await supabase.auth.signInWithOAuth( + OAuthProvider.github, + scopes: 'repo gist notifications' +); +... +// after user comes back from signin flow + +final Session? session = supabase.auth.currentSession; +final String? oAuthToken = session?.providerToken; +``` + + +# Dart Reference + +signInWithSSO() + + + +## Examples + +### Sign in with email domain + +```dart +await supabase.auth.signInWithSSO( + domain: 'company.com', +); +``` + + +### Sign in with provider UUID + +```dart +await supabase.auth.signInWithSSO( + providerId: '21648a9d-8d5a-4555-a9d1-d6375dc14e92', +); +``` + + +# Dart Reference + +signOut() + +Signs out the current user, if there is a logged in user. + + +## Examples + +### Sign out + +```dart +await supabase.auth.signOut(); +``` + + +# Dart Reference + +verifyOtp() + + + +## Examples + +### Verify Signup One-Time Password (OTP) + +```dart +final AuthResponse res = await supabase.auth.verifyOTP( + type: OtpType.signup, + token: token, + phone: '+13334445555', +); +final Session? session = res.session; +final User? user = res.user; +``` + + +### Verify SMS One-Time Password (OTP) + +```dart +final AuthResponse res = await supabase.auth.verifyOTP( + type: OtpType.sms, + token: '111111', + phone: '+13334445555', +); +final Session? session = res.session; +final User? user = res.user; +``` + + +# Dart Reference + +currentSession + +Returns the session data, if there is an active session. + + +## Examples + +### Get the session data + +```dart +final Session? session = supabase.auth.currentSession; +``` + + +# Dart Reference + +refreshSession() + + + +## Examples + +### Refresh session using the current session + +```dart +final AuthResponse res = await supabase.auth.refreshSession(); +final session = res.session; +``` + + +# Dart Reference + +currentUser + +Returns the user data, if there is a logged in user. + + +## Examples + +### Get the logged in user + +```dart +final User? user = supabase.auth.currentUser; +``` + + +# Dart Reference + +updateUser() + +Updates user data for a logged in user. + + +## Examples + +### Update the email for an authenticated user + +```dart +final UserResponse res = await supabase.auth.updateUser( + UserAttributes( + email: 'example@email.com', + ), +); +final User? updatedUser = res.user; +``` + + +### Update the password for an authenticated user + +```dart +final UserResponse res = await supabase.auth.updateUser( + UserAttributes( + password: 'new password', + ), +); +final User? updatedUser = res.user; +``` + + +### Update the user's metadata + +```dart +final UserResponse res = await supabase.auth.updateUser( + UserAttributes( + data: { 'hello': 'world' }, + ), +); +final User? updatedUser = res.user; +``` + + +### Update the user's password with a nonce + +```dart +supabase.auth.updateUser(UserAttributes( + email: 'example@email.com', + nonce: '123456', +)); +``` + + +# Dart Reference + +getUserIdentities() + +Gets all the identities linked to a user. + + +## Examples + +### Returns a list of identities linked to the user + +```dart +final identities = await supabase.auth.getUserIdentities(); +``` + + +# Dart Reference + +linkIdentity() + +Links an oauth identity to an existing user. This method supports the PKCE flow. + + +## Examples + +### Link an identity to a user + +```dart +await supabase.auth.linkIdentity(OAuthProvider.google); +``` + + +# Dart Reference + +unlinkIdentity() + +Unlinks an identity from a user by deleting it. The user will no longer be able to sign in with that identity once it's unlinked. + + +## Examples + +### Unlink an identity + +```dart +// retrieve all identities linked to a user +final identities = await supabase.auth.getUserIdentities(); + +// find the google identity +final googleIdentity = identities.firstWhere( + (element) => element.provider == 'google', +); + +// unlink the google identity +await supabase.auth.unlinkIdentity(googleIdentity); +``` + + +# Dart Reference + +reauthenticate() + + + +## Examples + +### Send reauthentication nonce + +```dart +await supabase.auth.reauthenticate(); +``` + + +# Dart Reference + +resend() + + + +## Examples + +### Resend an email signup confirmation + +```dart +final ResendResponse res = await supabase.auth.resend( + type: OtpType.signup, + email: 'email@example.com', +); +``` + + +# Dart Reference + +setSession() + + + +## Examples + +### Refresh the session + +```dart +final refreshToken = supabase.currentSession?.refreshToken ?? ''; +final AuthResponse response = await supabase.auth.setSession(refreshToken); + +final session = res.session; +``` + + +# Dart Reference + +Overview + + + +## Examples + + + +# Dart Reference + +mfa.enroll() + + + +## Examples + +### Enroll a time-based, one-time password (TOTP) factor + +```dart +final res = await supabase.auth.mfa.enroll(factorType: FactorType.totp); + +final qrCodeUrl = res.totp.qrCode; +``` + + +### Enroll a Phone Factor + +```dart +final res = await supabase.auth.mfa.enroll(factorType: FactorType.phone, phone: '+1234567890'); + +final phone = res.phone; +``` + + +# Dart Reference + +mfa.challenge() + + + +## Examples + +### Create a challenge for a factor + +```dart +final res = await supabase.auth.mfa.challenge( + factorId: '34e770dd-9ff9-416c-87fa-43b31d7ef225', +); +``` + + +# Dart Reference + +mfa.verify() + + + +## Examples + +### Verify a challenge for a factor + +```dart +final res = await supabase.auth.mfa.verify( + factorId: '34e770dd-9ff9-416c-87fa-43b31d7ef225', + challengeId: '4034ae6f-a8ce-4fb5-8ee5-69a5863a7c15', + code: '123456', +); +``` + + +# Dart Reference + +mfa.challengeAndVerify() + + + +## Examples + +### Create and verify a challenge for a factor + +```dart +final res = await supabase.auth.mfa.challengeAndVerify( + factorId: '34e770dd-9ff9-416c-87fa-43b31d7ef225', + code: '123456', +); +``` + + +# Dart Reference + +mfa.unenroll() + + + +## Examples + +### Unenroll a factor + +```dart +final res = await supabase.auth.mfa.unenroll( + '34e770dd-9ff9-416c-87fa-43b31d7ef225', +); +``` + + +# Dart Reference + +mfa.getAuthenticatorAssuranceLevel() + + + +## Examples + +### Get the AAL details of a session + +```dart +final res = supabase.auth.mfa.getAuthenticatorAssuranceLevel(); +final currentLevel = res.currentLevel; +final nextLevel = res.nextLevel; +final currentAuthenticationMethods = res.currentAuthenticationMethods; +``` + + +# Dart Reference + +Overview + + + +## Examples + +### Create server-side auth client + +```dart +final supabase = SupabaseClient(supabaseUrl, serviceRoleKey); +``` + + +# Dart Reference + +getUserById() + + + +## Examples + +### Fetch the user object using the access_token jwt + +```dart +final res = await supabase.auth.admin.getUserById(userId); +final user = res.user; +``` + + +# Dart Reference + +listUsers() + + + +## Examples + +### Get a page of users + +```dart +// Returns the first 50 users. +final List users = await supabase.auth.admin.listUsers(); +``` + + +### Paginated list of users + +```dart +// Returns the 101th - 200th users. +final List res = await supabase.auth.admin.listUsers( + page: 2, + perPage: 100, +); +``` + + +# Dart Reference + +createUser() + + + +## Examples + +### With custom user metadata + +```dart +final res = await supabase.auth.admin.createUser(AdminUserAttributes( + email: 'user@email.com', + password: 'password', + userMetadata: {'name': 'Yoda'}, +)); +``` + + +### Auto-confirm the user's email + +```dart +final res = await supabase.auth.admin.createUser(AdminUserAttributes( + email: 'user@email.com', + emailConfirm: true, +)); +``` + + +### Auto-confirm the user's phone number + +```dart +final res = await supabase.auth.admin.createUser(AdminUserAttributes( + phone: '1234567890', + phoneConfirm: true, +)); +``` + + +# Dart Reference + +deleteUser() + + + +## Examples + +### Removes a user + +```dart +await supabase.auth.admin + .deleteUser('715ed5db-f090-4b8c-a067-640ecee36aa0'); +``` + + +# Dart Reference + +inviteUserByEmail() + + + +## Examples + +### Invite a user + +```dart +final UserResponse res = await supabase.auth.admin + .inviteUserByEmail('email@example.com'); +final User? user = res.user; +``` + + +# Dart Reference + +generateLink() + + + +## Examples + +### Generate a signup link + +```dart +final res = await supabase.auth.admin.generateLink( + type: GenerateLinkType.signup, + email: 'email@example.com', + password: 'secret', +); +final actionLink = res.properties.actionLink; +``` + + +# Dart Reference + +updateUserById() + + + +## Examples + +### Updates a user's email + +```dart +await supabase.auth.admin.updateUserById( + '6aa5d0d4-2a9f-4483-b6c8-0cf4c6c98ac4', + attributes: AdminUserAttributes( + email: 'new@email.com', + ), +); +``` + + +# Dart Reference + +invoke() + +Invokes a Supabase Function. See the [guide](/docs/guides/functions) for details on writing Functions. + + +## Examples + +### Basic invocation. + +```dart +final res = await supabase.functions.invoke('hello', body: {'foo': 'baa'}); +final data = res.data; +``` + + +### Parsing custom headers. + +```dart +final res = await supabase.functions.invoke( + 'hello', + body: {'foo': 'baa'}, + headers: { + 'Authorization': 'Bearer ${supabase.auth.currentSession?.accessToken}' + }, +); +``` + + +# Dart Reference + +stream() + +Returns real-time data from your table as a `Stream`. + + +## Examples + +### Listen to a table + +```dart +supabase.from('countries') + .stream(primaryKey: ['id']) + .listen((List> data) { + // Do something awesome with the data +}); +``` + + +### With filter, order and limit + +```dart +supabase.from('countries') + .stream(primaryKey: ['id']) + .eq('id', 120) + .order('name') + .limit(10); +``` + + +### With an IN filter + +```dart +supabase.from('countries') + .stream(primaryKey: ['id']) + .inFilter('id', [1, 2, 3]) + .order('name') + .limit(10); +``` + + +### Using `stream()` with `StreamBuilder` + +```dart +final supabase = Supabase.instance.client; + +class MyWidget extends StatefulWidget { + const MyWidget({Key? key}) : super(key: key); + + @override + State createState() => _MyWidgetState(); +} + +class _MyWidgetState extends State { + // Persist the stream in a local variable to prevent refetching upon rebuilds + final _stream = supabase.from('countries').stream(primaryKey: ['id']); + + @override + Widget build(BuildContext context) { + return StreamBuilder( + stream: _stream, + builder: (context, snapshot) { + // Return your widget with the data from the snapshot + }, + ); + } +} +``` + + +# Dart Reference + +on().subscribe() + +Subscribe to realtime changes in your database. + + +## Examples + +### Listen to database changes + +```dart +supabase + .channel('public:countries') + .onPostgresChanges( + event: PostgresChangeEvent.all, + schema: 'public', + table: 'countries', + callback: (payload) { + print('Change received: ${payload.toString()}'); + }) + .subscribe(); +``` + + +### Listen to inserts + +```dart +supabase + .channel('public:countries') + .onPostgresChanges( + event: PostgresChangeEvent.insert, + schema: 'public', + table: 'countries', + callback: (payload) { + print('Change received: ${payload.toString()}'); + }) + .subscribe(); +``` + + +### Listen to updates + +```dart +supabase + .channel('public:countries') + .onPostgresChanges( + event: PostgresChangeEvent.update, + schema: 'public', + table: 'countries', + callback: (payload) { + print('Change received: ${payload.toString()}'); + }) + .subscribe(); +``` + + +### Listen to deletes + +```dart +supabase + .channel('public:countries') + .onPostgresChanges( + event: PostgresChangeEvent.delete, + schema: 'public', + table: 'countries', + callback: (payload) { + print('Change received: ${payload.toString()}'); + }) + .subscribe(); +``` + + +### Listen to multiple events + +```dart +supabase + .channel('public:countries') + .onPostgresChanges( + event: PostgresChangeEvent.insert, + schema: 'public', + table: 'countries', + callback: (payload) { + print('Insert event received: ${payload.toString()}'); + }) + .onPostgresChanges( + event: PostgresChangeEvent.delete, + schema: 'public', + table: 'countries', + callback: (payload) { + print('Delete event received: ${payload.toString()}'); + }) + .subscribe(); +``` + + +### Listen to row level changes + +```dart +supabase + .channel('public:countries:id=eq.200') + .onPostgresChanges( + event: PostgresChangeEvent.delete, + schema: 'public', + table: 'countries', + filter: PostgresChangeFilter( + type: PostgresChangeFilterType.eq, + column: 'id', + value: 200, + ), + callback: (payload) { + print('Change received: ${payload.toString()}'); + }) + .subscribe(); +``` + + +### Listen to broadcast messages + +```dart +supabase + .channel('room1') + .onBroadcast( + event: 'cursor-pos', + callback: (payload) { + print('Cursor position received!: $payload'); + }) + .subscribe(); +``` + + +### Listen to presence events + +```dart +final channel = supabase.channel('room1'); + +channel.onPresenceSync((payload) { + print('Synced presence state: ${channel.presenceState()}'); +}).onPresenceJoin((payload) { + print('Newly joined presences $payload'); +}).onPresenceLeave((payload) { + print('Newly left presences: $payload'); +}).subscribe((status, error) async { + if (status == RealtimeSubscribeStatus.subscribed) { + await channel.track({'online_at': DateTime.now().toIso8601String()}); + } +}); +``` + + +# Dart Reference + +removeChannel() + +Unsubscribes and removes Realtime channel from Realtime client. + + +## Examples + +### Remove a channel + +```dart +final status = await supabase.removeChannel(channel); +``` + + +# Dart Reference + +removeAllChannels() + +Unsubscribes and removes all Realtime channels from Realtime client. + + +## Examples + +### Remove all channels + +```dart +final statuses = await supabase.removeAllChannels(); +``` + + +# Dart Reference + +getChannels() + +Returns all Realtime channels. + + +## Examples + +### Get all channels + +```dart +final channels = supabase.getChannels(); +``` + + +# Dart Reference + +Overview + + + +## Examples + + + +# Dart Reference + +listBuckets() + +Retrieves the details of all Storage buckets within an existing product. + + +## Examples + +### List buckets + +```dart +final List buckets = await supabase + .storage + .listBuckets(); +``` + + +# Dart Reference + +getBucket() + +Retrieves the details of an existing Storage bucket. + + +## Examples + +### Get bucket + +```dart +final Bucket bucket = await supabase + .storage + .getBucket('avatars'); +``` + + +# Dart Reference + +createBucket() + +Creates a new Storage bucket + + +## Examples + +### Create bucket + +```dart +final String bucketId = await supabase + .storage + .createBucket('avatars'); +``` + + +# Dart Reference + +emptyBucket() + +Removes all objects inside a single bucket. + + +## Examples + +### Empty bucket + +```dart +final String res = await supabase + .storage + .emptyBucket('avatars'); +``` + + +# Dart Reference + +updateBucket() + +Updates a new Storage bucket + + +## Examples + +### Update bucket + +```dart +final String res = await supabase + .storage + .updateBucket('avatars', const BucketOptions(public: false)); +``` + + +# Dart Reference + +deleteBucket() + +Deletes an existing bucket. A bucket can't be deleted with existing objects inside it. You must first `empty()` the bucket. + + +## Examples + +### Delete bucket + +```dart +final String res = await supabase + .storage + .deleteBucket('avatars'); +``` + + +# Dart Reference + +from.upload() + +Uploads a file to an existing bucket. + + +## Examples + +### Upload file + +```dart +final avatarFile = File('path/to/file'); +final String fullPath = await supabase.storage.from('avatars').upload( + 'public/avatar1.png', + avatarFile, + fileOptions: const FileOptions(cacheControl: '3600', upsert: false), + ); +``` + + +### Upload file on web + +```dart +final Uint8List avatarFile = file.bytes; +final String fullPath = await supabase.storage.from('avatars').uploadBinary( + 'public/avatar1.png', + avatarFile, + fileOptions: const FileOptions(cacheControl: '3600', upsert: false), + ); +``` + + +# Dart Reference + +from.update() + +Replaces an existing file at the specified path with a new one. + + +## Examples + +### Update file + +```dart +final avatarFile = File('path/to/local/file'); +final String path = await supabase.storage.from('avatars').update( + 'public/avatar1.png', + avatarFile, + fileOptions: const FileOptions(cacheControl: '3600', upsert: false), + ); +``` + + +### Update file on web + +```dart +final Uint8List avatarFile = file.bytes; +final String path = await supabase.storage.from('avatars').updateBinary( + 'public/avatar1.png', + avatarFile, + fileOptions: const FileOptions(cacheControl: '3600', upsert: false), + ); +``` + + +# Dart Reference + +from.move() + +Moves an existing file, optionally renaming it at the same time. + + +## Examples + +### Move file + +```dart +final String result = await supabase + .storage + .from('avatars') + .move('public/avatar1.png', 'private/avatar2.png'); +``` + + +# Dart Reference + +from.createSignedUrl() + +Create signed url to download file without requiring permissions. This URL can be valid for a set number of seconds. + + +## Examples + +### Create Signed URL + +```dart +final String signedUrl = await supabase + .storage + .from('avatars') + .createSignedUrl('avatar1.png', 60); +``` + + +### With transform + +```dart +final String signedUrl = await supabase + .storage + .from('avatars') + .createSignedUrl( + 'avatar1.png', + 60, + transform: TransformOptions( + width: 200, + height: 200, + ), + ); +``` + + +# Dart Reference + +from.getPublicUrl() + +Retrieve URLs for assets in public buckets + + +## Examples + +### Returns the URL for an asset in a public bucket + +```dart +final String publicUrl = supabase + .storage + .from('public-bucket') + .getPublicUrl('avatar1.png'); +``` + + +### With transform + +```dart +final String publicUrl = await supabase + .storage + .from('public-bucket') + .getPublicUrl( + 'avatar1.png', + transform: TransformOptions( + width: 200, + height: 200, + ), + ); +``` + + +# Dart Reference + +from.download() + +Downloads a file. + + +## Examples + +### Download file + +```dart +final Uint8List file = await supabase + .storage + .from('avatars') + .download('avatar1.png'); +``` + + +### With transform + +```dart +final Uint8List file = await supabase + .storage + .from('avatars') + .download( + 'avatar1.png', + transform: TransformOptions( + width: 200, + height: 200, + ), + ); +``` + + +# Dart Reference + +from.remove() + +Deletes files within the same bucket + + +## Examples + +### Delete file + +```dart +final List objects = await supabase + .storage + .from('avatars') + .remove(['avatar1.png']); +``` + + +# Dart Reference + +from.list() + +Lists all the files within a bucket. + + +## Examples + +### List files in a bucket + +```dart +final List objects = await supabase + .storage + .from('avatars') + .list(); +``` diff --git a/docs/docs/llms-supabase-guides.txt b/docs/docs/llms-supabase-guides.txt new file mode 100644 index 0000000000..fd03b00a8d --- /dev/null +++ b/docs/docs/llms-supabase-guides.txt @@ -0,0 +1,106228 @@ +Supabase Guides + +# AI & Vectors + +The best vector database is the database you already have. + +Supabase provides an open source toolkit for developing AI applications using Postgres and pgvector. Use the Supabase client libraries to store, index, and query your vector embeddings at scale. + +The toolkit includes: + +* A [vector store](/docs/guides/ai/vector-columns) and embeddings support using Postgres and pgvector. +* A [Python client](/docs/guides/ai/vecs-python-client) for managing unstructured embeddings. +* An [embedding generation](/docs/guides/ai/quickstarts/generate-text-embeddings) process using open source models directly in Edge Functions. +* [Database migrations](/docs/guides/ai/examples/headless-vector-search#prepare-your-database) for managing structured embeddings. +* Integrations with all popular AI providers, such as [OpenAI](/docs/guides/ai/examples/openai), [Hugging Face](/docs/guides/ai/hugging-face), [LangChain](/docs/guides/ai/langchain), and more. + + +## Search + +You can use Supabase to build different types of search features for your app, including: + +* [Semantic search](/docs/guides/ai/semantic-search): search by meaning rather than exact keywords +* [Keyword search](/docs/guides/ai/keyword-search): search by words or phrases +* [Hybrid search](/docs/guides/ai/hybrid-search): combine semantic search with keyword search + + +## Examples + +Check out all of the AI [templates and examples](https://github.com/supabase/supabase/tree/master/examples/ai) in our GitHub repository. + +{/* */} + +
+ {examples.map((x) => ( +
+ + + {x.description} + + +
+ ))} +
+ +export const examples = [ + { + name: 'Headless Vector Search', + description: 'A toolkit to perform vector similarity search on your knowledge base embeddings.', + href: '/guides/ai/examples/headless-vector-search', + }, + { + name: 'Image Search with OpenAI CLIP', + description: 'Implement image search with the OpenAI CLIP Model and Supabase Vector.', + href: '/guides/ai/examples/image-search-openai-clip', + }, + { + name: 'Hugging Face inference', + description: 'Generate image captions using Hugging Face.', + href: '/guides/ai/examples/huggingface-image-captioning', + }, + { + name: 'OpenAI completions', + description: 'Generate GPT text completions using OpenAI in Edge Functions.', + href: '/guides/ai/examples/openai', + }, + { + name: 'Building ChatGPT Plugins', + description: 'Use Supabase as a Retrieval Store for your ChatGPT plugin.', + href: '/guides/ai/examples/building-chatgpt-plugins', + }, + { + name: 'Vector search with Next.js and OpenAI', + description: + 'Learn how to build a ChatGPT-style doc search powered by Next.js, OpenAI, and Supabase.', + href: '/guides/ai/examples/nextjs-vector-search', + }, +] + +{/* */} + + +## Integrations + +{/* */} + +
+ {integrations.map((x) => ( +
+ + {x.description} + +
+ ))} +
+ +export const integrations = [ + { + name: 'OpenAI', + description: + 'OpenAI is an AI research and deployment company. Supabase provides a simple way to use OpenAI in your applications.', + href: '/guides/ai/examples/building-chatgpt-plugins', + }, + { + name: 'Amazon Bedrock', + description: + 'A fully managed service that offers a choice of high-performing foundation models from leading AI companies.', + href: '/guides/ai/integrations/amazon-bedrock', + }, + { + name: 'Hugging Face', + description: + "Hugging Face is an open-source provider of NLP technologies. Supabase provides a simple way to use Hugging Face's models in your applications.", + href: '/guides/ai/hugging-face', + }, + { + name: 'LangChain', + description: + 'LangChain is a language-agnostic, open-source, and self-hosted API for text translation, summarization, and sentiment analysis.', + href: '/guides/ai/langchain', + }, + { + name: 'LlamaIndex', + description: 'LlamaIndex is a data framework for your LLM applications.', + href: '/guides/ai/integrations/llamaindex', + }, +] + +{/* */} + + +## Case studies + +{/* */} + +
+ {[ + { + name: 'Berri AI Boosts Productivity by Migrating from AWS RDS to Supabase with pgvector', + description: + 'Learn how Berri AI overcame challenges with self-hosting their vector database on AWS RDS and successfully migrated to Supabase.', + href: 'https://supabase.com/customers/berriai', + }, + { + name: 'Firecrawl switches from Pinecone to Supabase for PostgreSQL vector embeddings', + description: + 'How Firecrawl boosts efficiency and accuracy of chat powered search for documentation using Supabase with pgvector', + href: 'https://supabase.com/customers/firecrawl', + }, + { + name: 'Markprompt: GDPR-Compliant AI Chatbots for Docs and Websites', + description: + "AI-powered chatbot platform, Markprompt, empowers developers to deliver efficient and GDPR-compliant prompt experiences on top of their content, by leveraging Supabase's secure and privacy-focused database and authentication solutions", + href: 'https://supabase.com/customers/markprompt', + }, + ].map((x) => ( +
+ + {x.description} + +
+ ))} +
+ +{/* */} + + +# REST API + + + +Supabase auto-generates an API directly from your database schema allowing you to connect to your database through a restful interface, directly from the browser. + +The API is auto-generated from your database and is designed to get you building as fast as possible, without writing a single line of code. + +You can use them directly from the browser (two-tier architecture), or as a complement to your own API server (three-tier architecture). + + +## Features \[#rest-api-overview] + +Supabase provides a RESTful API using [PostgREST](https://postgrest.org/). This is a very thin API layer on top of Postgres. +It exposes everything you need from a CRUD API at the URL `https://.supabase.co/rest/v1/`. + +The REST interface is automatically reflected from your database's schema and is: + +* **Instant and auto-generated.**
As you update your database the changes are immediately accessible through your API. +* **Self documenting.**
Supabase generates documentation in the Dashboard which updates as you make database changes. +* **Secure.**
The API is configured to work with PostgreSQL's Row Level Security, provisioned behind an API gateway with key-auth enabled. +* **Fast.**
Our benchmarks for basic reads are more than 300% faster than Firebase. The API is a very thin layer on top of Postgres, which does most of the heavy lifting. +* **Scalable.**
The API can serve thousands of simultaneous requests, and works well for Serverless workloads. + +The reflected API is designed to retain as much of Postgres' capability as possible including: + +* Basic CRUD operations (Create/Read/Update/Delete) +* Arbitrarily deep relationships among tables/views, functions that return table types can also nest related tables/views. +* Works with Postgres Views, Materialized Views and Foreign Tables +* Works with Postgres Functions +* User defined computed columns and computed relationships +* The Postgres security model - including Row Level Security, Roles, and Grants. + +The REST API resolves all requests to a single SQL statement leading to fast response times and high throughput. + +Reference: + +* [Docs](https://postgrest.org/) +* [Source Code](https://github.com/PostgREST/postgrest) + + +## API URL and keys + +You can find the API URL and Keys in the [Dashboard](/dashboard/project/_/settings/api-keys). + + +# Auth + +Use Supabase to authenticate and authorize your users. + +Supabase Auth makes it easy to implement authentication and authorization in your app. We provide client SDKs and API endpoints to help you create and manage users. + +Your users can use many popular Auth methods, including password, magic link, one-time password (OTP), social login, and single sign-on (SSO). + + +## About authentication and authorization + +Authentication and authorization are the core responsibilities of any Auth system. + +* **Authentication** means checking that a user is who they say they are. +* **Authorization** means checking what resources a user is allowed to access. + +Supabase Auth uses [JSON Web Tokens (JWTs)](/docs/guides/auth/jwts) for authentication. For a complete reference of all JWT fields, see the [JWT Fields Reference](/docs/guides/auth/jwt-fields). Auth integrates with Supabase's database features, making it easy to use [Row Level Security (RLS)](/docs/guides/database/postgres/row-level-security) for authorization. + + +## The Supabase ecosystem + +You can use Supabase Auth as a standalone product, but it's also built to integrate with the Supabase ecosystem. + +Auth uses your project's Postgres database under the hood, storing user data and other Auth information in a special schema. You can connect this data to your own tables using triggers and foreign key references. + +Auth also enables access control to your database's automatically generated [REST API](/docs/guides/api). When using Supabase SDKs, your data requests are automatically sent with the user's Auth Token. The Auth Token scopes database access on a row-by-row level when used along with [RLS policies](/docs/guides/database/postgres/row-level-security). + + +## Providers + +Supabase Auth works with many popular Auth methods, including Social and Phone Auth using third-party providers. See the following sections for a list of supported third-party providers. + + +### Social Auth + + + + +### Phone Auth + + + + +## Pricing + +Charges apply to Monthly Active Users (MAU), Monthly Active Third-Party Users (Third-Party MAU), and Monthly Active SSO Users (SSO MAU) and Advanced MFA Add-ons. For a detailed breakdown of how these charges are calculated, refer to the following pages: + +* [Pricing MAU](/docs/guides/platform/manage-your-usage/monthly-active-users) +* [Pricing Third-Party MAU](/docs/guides/platform/manage-your-usage/monthly-active-users-third-party) +* [Pricing SSO MAU](/docs/guides/platform/manage-your-usage/monthly-active-users-sso) +* [Advanced MFA - Phone](/docs/guides/platform/manage-your-usage/advanced-mfa-phone) + + +# Local Dev with CLI + +Developing locally using the Supabase CLI. + +You can use the Supabase CLI to run the entire Supabase stack locally on your machine, by running `supabase init` and then `supabase start`. To install the CLI, see the [installation guide](/docs/guides/cli/getting-started#installing-the-supabase-cli). + +The Supabase CLI provides tools to develop your project locally, deploy to the Supabase Platform, handle database migrations, and generate types directly from your database schema. + + +## Resources + +
+ {[ + { + name: 'Supabase CLI', + description: + 'The Supabase CLI provides tools to develop manage your Supabase projects from your local machine.', + href: 'https://github.com/supabase/cli', + }, + { + name: 'GitHub Action', + description: ' A GitHub action for interacting with your Supabase projects using the CLI.', + href: 'https://github.com/supabase/setup-cli', + }, + ].map((x) => ( +
+ + + {x.description} + + +
+ ))} +
+ + +# Cron + +Schedule Recurring Jobs with Cron Syntax in Postgres + +Supabase Cron is a Postgres Module that simplifies scheduling recurring Jobs with cron syntax and monitoring Job runs inside Postgres. + +Cron Jobs can be created via SQL or the [Integrations -> Cron](/dashboard/project/_/integrations) interface inside the Dashboard, and can run anywhere from every second to once a year depending on your use case. + +Manage cron jobs via the Dashboard + +Every Job can run SQL snippets or database functions with zero network latency or make an HTTP request, such as invoking a Supabase Edge Function, with ease. + + + For best performance, we recommend no more than 8 Jobs run concurrently. Each Job should run no more than 10 minutes. + + + +## How does Cron work? + +Under the hood, Supabase Cron uses the [`pg_cron`](https://github.com/citusdata/pg_cron) Postgres database extension which is the scheduling and execution engine for your Jobs. + +The extension creates a `cron` schema in your database and all Jobs are stored on the `cron.job` table. Every Job's run and its status is recorded on the `cron.job_run_details` table. + +The Supabase Dashboard provides an interface for you to schedule Jobs and monitor Job runs. You can also do the same with SQL. + + +## Resources + +* [`pg_cron` GitHub Repository](https://github.com/citusdata/pg_cron) + + +# Deployment & Branching + + + +Deploying your app makes it live and accessible to users. Usually, you deploy an app to at least two environments: a production environment for users and (one or multiple) staging or preview environments for developers. + +Supabase provides several options for environment management and deployment. + + +## Environment management + +You can maintain separate development, staging, and production environments for Supabase: + +* **Development**: Develop with a local Supabase stack using the [Supabase CLI](/docs/guides/local-development). +* **Staging**: Use [branching](/docs/guides/deployment/branching) to create staging or preview environments. You can use persistent branches for a long-lived staging setup, or ephemeral branches for short-lived previews (which are often tied to a pull request). +* **Production**: If you have branching enabled, you can use the Supabase GitHub integration to automatically push your migration files when you merge a pull request. Alternatively, you can set up your own continuous deployment pipeline using the Supabase CLI. + + + Read the [self-hosting guides](/docs/guides/self-hosting) for instructions on hosting your own Supabase stack. + + + +## Deployment + +You can automate deployments using: + +* The [Supabase GitHub integration](/dashboard/project/_/settings/integrations) (with branching enabled) +* The [Supabase CLI](/docs/guides/local-development) in your own continuous deployment pipeline +* The [Supabase Terraform provider](/docs/guides/deployment/terraform) + + +# Edge Functions + +Globally distributed TypeScript functions. + +Edge Functions are server-side TypeScript functions, distributed globally at the edge—close to your users. They can be used for listening to webhooks or integrating your Supabase project with third-parties [like Stripe](https://github.com/supabase/supabase/tree/master/examples/edge-functions/supabase/functions/stripe-webhooks). Edge Functions are developed using [Deno](https://deno.com), which offers a few benefits to you as a developer: + +* It is open source. +* It is portable. Supabase Edge Functions run locally, and on any other Deno-compatible platform (including self-hosted infrastructure). +* It is TypeScript first and supports WASM. +* Edge Functions are globally distributed for low-latency. + + +## How it works + +* **Request enters an edge gateway (relay)** — the gateway routes traffic, handles auth headers/JWT validation, and applies routing/traffic rules. +* **Auth & policies are applied** — the gateway (or your function) can validate Supabase JWTs, apply rate-limits, and centralize security checks before executing code. +* **[Edge runtime](https://github.com/supabase/edge-runtime) executes your function** — the function runs on a regionally-distributed Edge Runtime node closest to the user for minimal latency. +* **Integrations & data access** — functions commonly call Supabase APIs (Auth, Postgres, Storage) or third-party APIs. For Postgres, prefer connection strategies suited for edge/serverless environments (see the `connect-to-postgres` guide). +* **Observability and logs** — invocations emit logs and metrics you can explore in the dashboard or downstream monitoring (Sentry, etc.). +* **Response returns via the gateway** — the gateway forwards the response back to the client and records request metadata. + + +## Quick technical notes + +* **Runtime:** Supabase Edge Runtime (Deno compatible runtime with TypeScript first). Functions are simple `.ts` files that export a handler. +* **Local dev parity:** Use Supabase CLI for a local runtime similar to production for faster iteration (`supabase functions serve` command). +* **Global deployment:** Deploy your Edge Functions via Supabase Dashboard, CLI or MCP. +* **Cold starts & concurrency:** cold starts are possible — design for short-lived, idempotent operations. Heavy long-running jobs should be moved to [background workers](/docs/guides/functions/background-tasks). +* **Database connections:** treat Postgres like a remote, pooled service — use connection pools or serverless-friendly drivers. +* **Secrets:** store credentials in Supabase [project secrets](/docs/reference/cli/supabase-secrets) and access them via environment variables. + + +## When to use Edge Functions + +* Authenticated or public HTTP endpoints that need low latency. +* Webhook receivers (Stripe, GitHub, etc.). +* On-demand image or Open Graph generation. +* Small AI inference tasks or orchestrating calls to external LLM APIs (like OpenAI) +* Sending transactional emails. +* Building messaging bots for Slack, Discord, etc. + +
+ +
+ + +## Examples + +Check out the [Edge Function Examples](https://github.com/supabase/supabase/tree/master/examples/edge-functions) in our GitHub repository. + +
+ {[ + { + name: 'With supabase-js', + description: 'Use the Supabase client inside your Edge Function.', + href: '/guides/functions/auth', + }, + { + name: 'Type-Safe SQL with Kysely', + description: + 'Combining Kysely with Deno Postgres gives you a convenient developer experience for interacting directly with your Postgres database.', + href: '/guides/functions/kysely-postgres', + }, + { + name: 'Monitoring with Sentry', + description: 'Monitor Edge Functions with the Sentry Deno SDK.', + href: '/guides/functions/examples/sentry-monitoring', + }, + { + name: 'With CORS headers', + description: 'Send CORS headers for invoking from the browser.', + href: '/guides/functions/cors', + }, + { + name: 'React Native with Stripe', + description: 'Full example for using Supabase and Stripe, with Expo.', + href: 'https://github.com/supabase-community/expo-stripe-payments-with-supabase-functions', + }, + { + name: 'Flutter with Stripe', + description: 'Full example for using Supabase and Stripe, with Flutter.', + href: 'https://github.com/supabase-community/flutter-stripe-payments-with-supabase-functions', + }, + { + name: 'Building a RESTful Service API', + description: + 'Learn how to use HTTP methods and paths to build a RESTful service for managing tasks.', + href: 'https://github.com/supabase/supabase/blob/master/examples/edge-functions/supabase/functions/restful-tasks/index.ts', + }, + { + name: 'Working with Supabase Storage', + description: 'An example on reading a file from Supabase Storage.', + href: 'https://github.com/supabase/supabase/blob/master/examples/edge-functions/supabase/functions/read-storage/index.ts', + }, + { + name: 'Open Graph Image Generation', + description: 'Generate Open Graph images with Deno and Supabase Edge Functions.', + href: '/guides/functions/examples/og-image', + }, + { + name: 'OG Image Generation & Storage CDN Caching', + description: 'Cache generated images with Supabase Storage CDN.', + href: 'https://github.com/supabase/supabase/tree/master/examples/edge-functions/supabase/functions/og-image-with-storage-cdn', + }, + { + name: 'Get User Location', + description: `Get user location data from user's IP address.`, + href: 'https://github.com/supabase/supabase/tree/master/examples/edge-functions/supabase/functions/location', + }, + { + name: 'Cloudflare Turnstile', + description: `Protecting Forms with Cloudflare Turnstile.`, + href: '/guides/functions/examples/cloudflare-turnstile', + }, + { + name: 'Connect to Postgres', + description: `Connecting to Postgres from Edge Functions.`, + href: '/guides/functions/connect-to-postgres', + }, + { + name: 'GitHub Actions', + description: `Deploying Edge Functions with GitHub Actions.`, + href: '/guides/functions/examples/github-actions', + }, + { + name: 'Oak Server Middleware', + description: `Request Routing with Oak server middleware.`, + href: 'https://github.com/supabase/supabase/tree/master/examples/edge-functions/supabase/functions/oak-server', + }, + { + name: 'Hugging Face', + description: `Access 100,000+ Machine Learning models.`, + href: '/guides/ai/examples/huggingface-image-captioning', + }, + { + name: 'Amazon Bedrock', + description: `Amazon Bedrock Image Generator`, + href: '/guides/functions/examples/amazon-bedrock-image-generator', + }, + { + name: 'OpenAI', + description: `Using OpenAI in Edge Functions.`, + href: '/guides/ai/examples/openai', + }, + { + name: 'Stripe Webhooks', + description: `Handling signed Stripe Webhooks with Edge Functions.`, + href: '/guides/functions/examples/stripe-webhooks', + }, + { + name: 'Send emails', + description: `Send emails in Edge Functions with Resend.`, + href: '/guides/functions/examples/send-emails', + }, + { + name: 'Web Stream', + description: `Server-Sent Events in Edge Functions.`, + href: 'https://github.com/supabase/supabase/tree/master/examples/edge-functions/supabase/functions/streams', + }, + { + name: 'Puppeteer', + description: `Generate screenshots with Puppeteer.`, + href: '/guides/functions/examples/screenshots', + }, + { + name: 'Discord Bot', + description: `Building a Slash Command Discord Bot with Edge Functions.`, + href: '/guides/functions/examples/discord-bot', + }, + { + name: 'Telegram Bot', + description: `Building a Telegram Bot with Edge Functions.`, + href: '/guides/functions/examples/telegram-bot', + }, + { + name: 'Upload File', + description: `Process multipart/form-data.`, + href: 'https://github.com/supabase/supabase/tree/master/examples/edge-functions/supabase/functions/file-upload-storage', + }, + { + name: 'Upstash Redis', + description: `Build an Edge Functions Counter with Upstash Redis.`, + href: '/guides/functions/examples/upstash-redis', + }, + { + name: 'Rate Limiting', + description: `Rate Limiting Edge Functions with Upstash Redis.`, + href: '/guides/functions/examples/rate-limiting', + }, + { + name: 'Slack Bot Mention Edge Function', + description: `Slack Bot handling Slack mentions in Edge Function`, + href: '/guides/functions/examples/slack-bot-mention', + }, + ].map((x) => ( +
+ + + {x.description} + + +
+ ))} +
+ + +# Getting Started + + + +
+
+
+ {[ + { + title: 'Features', + hasLightIcon: true, + href: '/guides/getting-started/features', + description: 'A non-exhaustive list of features that Supabase provides for every project.' + }, + { + title: 'Architecture', + hasLightIcon: true, + href: '/guides/getting-started/architecture', + description: "An overview of Supabase's architecture and product principles.", + }, + { + title: 'Local Development', + hasLightIcon: true, + href: '/guides/cli/getting-started', + description: 'Use the Supabase CLI to develop locally and collaborate between teams.', + } + ].map((resource) => { + return ( + + + {resource.description} + + + ) + + })} +
+
+
+ + +### Use cases + +
+ {[ + { + title: 'AI, Vectors, and embeddings', + href: '/guides/ai#examples', + description: `Build AI-enabled applications using our Vector toolkit.`, + icon: '/docs/img/icons/openai_logo', + hasLightIcon: true, + }, + { + title: 'Subscription Payments (SaaS)', + href: 'https://github.com/vercel/nextjs-subscription-payments#nextjs-subscription-payments-starter', + description: `Clone, deploy, and fully customize a SaaS subscription application with Next.js.`, + icon: '/docs/img/icons/nextjs-icon', + }, + { + title: 'Partner Gallery', + href: 'https://github.com/supabase-community/partner-gallery-example#supabase-partner-gallery-example', + description: `Postgres full-text search, image storage, and more.`, + icon: '/docs/img/icons/nextjs-icon', + }, + ].map((item) => { + return ( + + + {item.description} + + + ) + })} +
+ + +### Framework quickstarts + +
+ {[ + { + title: 'React', + href: '/guides/getting-started/quickstarts/reactjs', + description: + 'Learn how to create a Supabase project, add some sample data to your database, and query the data from a React app.', + icon: '/docs/img/icons/react-icon', + enabled: isFeatureEnabled('docs:framework_quickstarts'), + }, + { + title: 'Next.js', + href: '/guides/getting-started/quickstarts/nextjs', + description: + 'Learn how to create a Supabase project, add some sample data to your database, and query the data from a Next.js app.', + icon: '/docs/img/icons/nextjs-icon', + hasLightIcon: true, + enabled: isFeatureEnabled('docs:framework_quickstarts'), + }, + { + title: 'Nuxt', + href: '/guides/getting-started/quickstarts/nuxtjs', + description: + 'Learn how to create a Supabase project, add some sample data to your database, and query the data from a Nuxt app.', + icon: '/docs/img/icons/nuxt-icon', + enabled: isFeatureEnabled('docs:framework_quickstarts'), + }, + { + title: 'Hono', + href: '/guides/getting-started/quickstarts/hono', + description: + 'Learn how to create a Supabase project, add some sample data to your database, secure it with auth, and query the data from a Hono app.', + icon: '/docs/img/icons/hono-icon', + enabled: isFeatureEnabled('docs:framework_quickstarts'), + }, + { + title: 'RedwoodJS', + href: '/guides/getting-started/quickstarts/redwoodjs', + description: + 'Learn how to create a Supabase project, add some sample data to your database using Prisma migration and seeds, and query the data from a RedwoodJS app.', + icon: '/docs/img/icons/redwood-icon', + enabled: isFeatureEnabled('docs:framework_quickstarts'), + }, + { + title: 'Flutter', + href: '/guides/getting-started/quickstarts/flutter', + description: + 'Learn how to create a Supabase project, add some sample data to your database, and query the data from a Flutter app.', + icon: '/docs/img/icons/flutter-icon', + enabled: isFeatureEnabled('sdk:dart'), + }, + { + title: 'iOS SwiftUI', + href: '/guides/getting-started/quickstarts/ios-swiftui', + description: + 'Learn how to create a Supabase project, add some sample data to your database, and query the data from an iOS app.', + icon: '/docs/img/icons/swift-icon', + enabled: isFeatureEnabled('sdk:swift'), + }, + { + title: 'Android Kotlin', + href: '/guides/getting-started/quickstarts/kotlin', + description: + 'Learn how to create a Supabase project, add some sample data to your database, and query the data from an Android Kotlin app.', + icon: '/docs/img/icons/kotlin-icon', + enabled: isFeatureEnabled('sdk:kotlin'), + }, + { + title: 'SvelteKit', + href: '/guides/getting-started/quickstarts/sveltekit', + description: + 'Learn how to create a Supabase project, add some sample data to your database, and query the data from a SvelteKit app.', + icon: '/docs/img/icons/svelte-icon', + enabled: isFeatureEnabled('docs:framework_quickstarts'), + }, + { + title: 'SolidJS', + href: '/guides/getting-started/quickstarts/solidjs', + description: + 'Learn how to create a Supabase project, add some sample data to your database, and query the data from a SolidJS app.', + icon: '/docs/img/icons/solidjs-icon', + enabled: isFeatureEnabled('docs:framework_quickstarts'), + }, + { + title: 'Vue', + href: '/guides/getting-started/quickstarts/vue', + description: + 'Learn how to create a Supabase project, add some sample data to your database, and query the data from a Vue app.', + icon: '/docs/img/icons/vuejs-icon', + enabled: isFeatureEnabled('docs:framework_quickstarts'), + }, + { + title: 'Refine', + href: '/guides/getting-started/quickstarts/refine', + description: + 'Learn how to create a Supabase project, add some sample data to your database, and query the data from a Refine app.', + icon: '/docs/img/icons/refine-icon', + enabled: isFeatureEnabled('docs:framework_quickstarts'), + }, + ] + .filter((item) => item.enabled !== false) + .map((item) => { + return ( + + + {item.description} + + + ) + })} +
+ + +### Web app demos + +
+ { + [ + { + title: 'Next.js', + href: '/guides/getting-started/tutorials/with-nextjs', + description: + 'Learn how to build a user management app with Next.js and Supabase Database, Auth, and Storage functionality.', + icon: '/docs/img/icons/nextjs-icon', + hasLightIcon: true, + }, + { + title: 'React', + href: '/guides/getting-started/tutorials/with-react', + description: + 'Learn how to build a user management app with React and Supabase Database, Auth, and Storage functionality.', + icon: '/docs/img/icons/react-icon', + }, + { + title: 'Vue 3', + href: '/guides/getting-started/tutorials/with-vue-3', + description: + 'Learn how to build a user management app with Vue 3 and Supabase Database, Auth, and Storage functionality.', + icon: '/docs/img/icons/vuejs-icon', + }, + { + title: 'Nuxt 3', + href: '/guides/getting-started/tutorials/with-nuxt-3', + description: + 'Learn how to build a user management app with Nuxt 3 and Supabase Database, Auth, and Storage functionality.', + icon: '/docs/img/icons/nuxt-icon', + }, + { + title: 'Angular', + href: '/guides/getting-started/tutorials/with-angular', + description: + 'Learn how to build a user management app with Angular and Supabase Database, Auth, and Storage functionality.', + icon: '/docs/img/icons/angular-icon', + }, + { + title: 'RedwoodJS', + href: '/guides/getting-started/tutorials/with-redwoodjs', + description: + 'Learn how to build a user management app with RedwoodJS and Supabase Database, Auth, and Storage functionality.', + icon: '/docs/img/icons/redwood-icon', + }, + { + title: 'Svelte', + href: '/guides/getting-started/tutorials/with-svelte', + description: + 'Learn how to build a user management app with Svelte and Supabase Database, Auth, and Storage functionality.', + icon: '/docs/img/icons/svelte-icon', + }, + { + title: 'SvelteKit', + href: '/guides/getting-started/tutorials/with-sveltekit', + description: + 'Learn how to build a user management app with SvelteKit and Supabase Database, Auth, and Storage functionality.', + icon: '/docs/img/icons/svelte-icon', + }, + { + title: 'Refine', + href: '/guides/getting-started/tutorials/with-refine', + description: + 'Learn how to build a user management app with Refine and Supabase Database, Auth, and Storage functionality.', + icon: '/docs/img/icons/refine-icon', + } + ] + .map((item) => { + return ( + + + {item.description} + + + ) + + })} +
+ + +### Mobile tutorials + +
+ {[ + { + title: 'Flutter', + href: '/guides/getting-started/tutorials/with-flutter', + description: + 'Learn how to build a user management app with Flutter and Supabase Database, Auth, and Storage functionality.', + icon: '/docs/img/icons/flutter-icon', + enabled: isFeatureEnabled('sdk:dart') + }, + { + title: 'Expo React Native', + href: '/guides/getting-started/tutorials/with-expo-react-native', + description: + 'Learn how to build a user management app with Expo React Native and Supabase Database, Auth, and Storage functionality.', + icon: '/docs/img/icons/expo-icon', + hasLightIcon: true, + enabled: true + }, + { + title: 'Expo React Native Social Auth', + href: '/guides/getting-started/tutorials/with-expo-react-native-social-auth', + description: + 'Learn how to implement social authentication in an app with Expo React Native and Supabase Database and Auth functionality.', + icon: '/docs/img/icons/expo-icon', + hasLightIcon: true + }, + { + title: 'Android Kotlin', + href: '/guides/getting-started/tutorials/with-kotlin', + description: + 'Learn how to build a product management app with Android and Supabase Database, Auth, and Storage functionality.', + icon: '/docs/img/icons/kotlin-icon', + enabled: isFeatureEnabled('sdk:kotlin') + }, + { + title: 'iOS Swift', + href: '/guides/getting-started/tutorials/with-swift', + description: + 'Learn how to build a user management app with iOS and Supabase Database, Auth, and Storage functionality.', + icon: '/docs/img/icons/swift-icon', + enabled: isFeatureEnabled('sdk:swift') + }, + { + title: 'Ionic React', + href: '/guides/getting-started/tutorials/with-ionic-react', + description: + 'Learn how to build a user management app with Ionic React and Supabase Database, Auth, and Storage functionality.', + icon: '/docs/img/icons/ionic-icon', + enabled: true + }, + { + title: 'Ionic Vue', + href: '/guides/getting-started/tutorials/with-ionic-vue', + description: + 'Learn how to build a user management app with Ionic Vue and Supabase Database, Auth, and Storage functionality.', + icon: '/docs/img/icons/ionic-icon', + enabled: true + }, + { + title: 'Ionic Angular', + href: '/guides/getting-started/tutorials/with-ionic-angular', + description: + 'Learn how to build a user management app with Ionic Angular and Supabase Database, Auth, and Storage functionality.', + icon: '/docs/img/icons/ionic-icon', + enabled: true + } + ] + .filter((item) => item.enabled !== false) + .map((item) => { + return ( + + + {item.description} + + + ) + + })} +
+ + +# Integrations + + + +Supabase integrates with many of your favorite third-party services. + + +## Vercel Marketplace + +Create and manage your Supabase projects directly through Vercel. [Get started with Vercel](/docs/guides/integrations/vercel-marketplace). + + +## Supabase Marketplace + +Browse tools for extending your Supabase project. [Browse the Supabase Marketplace](/partners/integrations). + + +# Local Development & CLI + +Learn how to develop locally and use the Supabase CLI + +Develop locally while running the Supabase stack on your machine. + + + As a prerequisite, you must install a container runtime compatible with Docker APIs. + + * [Docker Desktop](https://docs.docker.com/desktop/) (macOS, Windows, Linux) + * [Rancher Desktop](https://rancherdesktop.io/) (macOS, Windows, Linux) + * [Podman](https://podman.io/) (macOS, Windows, Linux) + * [OrbStack](https://orbstack.dev/) (macOS) + + + +## Quickstart + +1. Install the Supabase CLI: + + + + ```sh + npm install supabase --save-dev + ``` + + + + ```sh + NODE_OPTIONS=--no-experimental-fetch yarn add supabase --dev + ``` + + + + ```sh + pnpm add supabase --save-dev --allow-build=supabase + ``` + + + The `--allow-build=supabase` flag is required on pnpm version 10 or higher. If you're using an older version of pnpm, omit this flag. + + + + + ```sh + brew install supabase/tap/supabase + ``` + + + +2. In your repo, initialize the Supabase project: + + + + ```sh + npx supabase init + ``` + + + + ```sh + yarn supabase init + ``` + + + + ```sh + pnpx supabase init + ``` + + + + ```sh + supabase init + ``` + + + +3. Start the Supabase stack: + + + + ```sh + npx supabase start + ``` + + + + ```sh + yarn supabase start + ``` + + + + ```sh + pnpx supabase start + ``` + + + + ```sh + supabase start + ``` + + + +4. View your local Supabase instance at [http://localhost:54323](http://localhost:54323). + + + If your local development machine is connected to an untrusted public network, you should create a separate docker network and bind to 127.0.0.1 before starting the local development stack. This restricts network access to only your localhost machine. + + ```sh + docker network create -o 'com.docker.network.bridge.host_binding_ipv4=127.0.0.1' local-network + npx supabase start --network-id local-network + ``` + + You should never expose your local development stack publicly. + + + +## Local development + +Local development with Supabase allows you to work on your projects in a self-contained environment on your local machine. Working locally has several advantages: + +1. Faster development: You can make changes and see results instantly without waiting for remote deployments. +2. Offline work: You can continue development even without an internet connection. +3. Cost-effective: Local development is free and doesn't consume your project's quota. +4. Enhanced privacy: Sensitive data remains on your local machine during development. +5. Easy testing: You can experiment with different configurations and features without affecting your production environment. + +To get started with local development, you'll need to install the [Supabase CLI](#cli) and Docker. The Supabase CLI allows you to start and manage your local Supabase stack, while Docker is used to run the necessary services. + +Once set up, you can initialize a new Supabase project, start the local stack, and begin developing your application using local Supabase services. This includes access to a local Postgres database, Auth, Storage, and other Supabase features. + + +## CLI + +The Supabase CLI is a powerful tool that enables developers to manage their Supabase projects directly from the terminal. It provides a suite of commands for various tasks, including: + +* Setting up and managing local development environments +* Generating TypeScript types for your database schema +* Handling database migrations +* Managing environment variables and secrets +* Deploying your project to the Supabase platform + +With the CLI, you can streamline your development workflow, automate repetitive tasks, and maintain consistency across different environments. It's an essential tool for both local development and CI/CD pipelines. + +See the [CLI Getting Started guide](/docs/guides/local-development/cli/getting-started) for more information. + + +# Supabase Platform + + + +Supabase is a hosted platform which makes it very simple to get started without needing to manage any infrastructure. + +Visit [supabase.com/dashboard](/dashboard) and sign in to start creating projects. + + +## Projects + +Each project on Supabase comes with: + +* A dedicated [Postgres database](/docs/guides/database) +* [Auto-generated APIs](/docs/guides/database/api) +* [Auth and user management](/docs/guides/auth) +* [Edge Functions](/docs/guides/functions) +* [Realtime API](/docs/guides/realtime) +* [Storage](/docs/guides/storage) + + +## Organizations + +Organizations are a way to group your projects. Each organization can be configured with different team members and billing settings. +Refer to [access control](/docs/guides/platform/access-control) for more information on how to manage team members within an organization. + + +## Platform status + +If Supabase experiences outages, we keep you as informed as possible, as early as possible. We provide the following feedback channels: + +* Status page: [status.supabase.com](https://status.supabase.com/) +* RSS Feed: [status.supabase.com/history.rss](https://status.supabase.com/history.rss) +* Atom Feed: [status.supabase.com/history.atom](https://status.supabase.com/history.atom) +* Slack Alerts: You can receive updates via the RSS feed, using Slack's [built-in RSS functionality](https://slack.com/help/articles/218688467-Add-RSS-feeds-to-Slack)
`/feed subscribe https://status.supabase.com/history.atom` + +Make sure to review our [SLA](/docs/company/sla) for details on our commitment to Platform Stability. + + +# Supabase Queues + +Durable Message Queues with Guaranteed Delivery in Postgres + +Supabase Queues is a Postgres-native durable Message Queue system with guaranteed delivery built on the [pgmq database extension](https://github.com/tembo-io/pgmq). It offers developers a seamless way to persist and process Messages in the background while improving the resiliency and scalability of their applications and services. + +Queues couples the reliability of Postgres with the simplicity Supabase's platform and developer experience, enabling developers to manage Background Tasks with zero configuration. + + +## Features + +* **Postgres Native** +
+ Built on top of the `pgmq` database extension, create and manage Queues with any Postgres tooling. +* **Guaranteed Message Delivery** +
+ Messages added to Queues are guaranteed to be delivered to your consumers. +* **Exactly Once Message Delivery** +
A Message is delivered exactly once to a consumer within a customizable visibility window. +* **Message Durability and Archival** +
+ Messages are stored in Postgres and you can choose to archive them for analytical or auditing purposes. +* **Granular Authorization** +
+ Control client-side consumer access to Queues with API permissions and Row Level Security (RLS) policies. +* **Queue Management and Monitoring** +
+ Create, manage, and monitor Queues and Messages in the Supabase Dashboard. + + +## Resources + +* [Quickstart](/docs/guides/queues/quickstart) +* [API Reference](/docs/guides/queues/api) +* [`pgmq` GitHub Repository](https://github.com/tembo-io/pgmq) + + +# Realtime + +Send and receive messages to connected clients. + +Supabase provides a globally distributed [Realtime](https://github.com/supabase/realtime) service with the following features: + +* [Broadcast](/docs/guides/realtime/broadcast): Send low-latency messages between clients. Perfect for real-time messaging, database changes, cursor tracking, game events, and custom notifications. +* [Presence](/docs/guides/realtime/presence): Track and synchronize user state across clients. Ideal for showing who's online, or active participants. +* [Postgres Changes](/docs/guides/realtime/postgres-changes): Listen to database changes in real-time. + + +## What can you build? + +* **Chat applications** - Real-time messaging with typing indicators and online presence +* **Collaborative tools** - Document editing, whiteboards, and shared workspaces +* **Live dashboards** - Real-time data visualization and monitoring +* **Multiplayer games** - Synchronized game state and player interactions +* **Social features** - Live notifications, reactions, and user activity feeds + +Check the [Getting Started](/docs/guides/realtime/getting_started) guide to get started. + + +## Examples + +
+ {[ + { + name: 'Multiplayer.dev', + description: 'Showcase application displaying cursor movements and chat messages using Broadcast.', + href: 'https://multiplayer.dev', + }, + { + name: 'Chat', + description: 'Supabase UI chat component using Broadcast to send message between users.', + href: 'https://supabase.com/ui/docs/nextjs/realtime-chat' + }, + { + name: 'Avatar Stack', + description: 'Supabase UI avatar stack component using Presence to track connected users.', + href: 'https://supabase.com/ui/docs/nextjs/realtime-avatar-stack' + }, + { + name: 'Realtime Cursor', + description: "Supabase UI realtime cursor component using Broadcast to share users' cursors to build collaborative applications.", + href: 'https://supabase.com/ui/docs/nextjs/realtime-cursor' + } + ].map((x) => ( +
+ + {x.description} + +
+ ))} +
+ + +## Resources + +Find the source code and documentation in the Supabase GitHub repository. + +
+ {[ + { + name: 'Supabase Realtime', + description: 'View the source code.', + href: 'https://github.com/supabase/realtime', + }, + { + name: 'Realtime: Multiplayer Edition', + description: 'Read more about Supabase Realtime.', + href: 'https://supabase.com/blog/supabase-realtime-multiplayer-general-availability', + }, + ].map((x) => ( +
+ + {x.description} + +
+ ))} +
+ + +# Resources + + + +{/* */} + +
+
+
+ { + [ + { + title: 'Examples', + hasLightIcon: true, + href: '/guides/resources/examples', + description: 'Official GitHub examples, curated content from the community, and more.', + }, + { + title: 'Glossary', + hasLightIcon: true, + href: '/guides/resources/glossary', + description: 'Definitions for terminology and acronyms used in the Supabase documentation.', + } + ] + .map((resource) => { + return ( + + + {resource.description} + + + ) + + })} +
+
+ +
+
+ ### Migrate to Supabase +
+ +
+ { + [ + { + title: 'Auth0', + icon: '/docs/img/icons/auth0-icon', + href: '/guides/resources/migrating-to-supabase/auth0', + description: 'Move your auth users from Auth0 to a Supabase project.', + hasLightIcon: true, + }, + { + title: 'Firebase Auth', + icon: '/docs/img/icons/firebase-icon', + href: '/guides/resources/migrating-to-supabase/firebase-auth', + description: 'Move your auth users from a Firebase project to a Supabase project.', + }, + { + title: 'Firestore Data', + icon: '/docs/img/icons/firebase-icon', + href: '/guides/resources/migrating-to-supabase/firestore-data', + description: 'Migrate the contents of a Firestore collection to a single PostgreSQL table.', + }, + { + title: 'Firebase Storage', + icon: '/docs/img/icons/firebase-icon', + href: '/guides/resources/migrating-to-supabase/firebase-storage', + description: 'Convert your Firebase Storage files to Supabase Storage.' + }, + { + title: 'Heroku', + icon: '/docs/img/icons/heroku-icon', + href: '/guides/resources/migrating-to-supabase/heroku', + description: 'Migrate your Heroku Postgres database to Supabase.' + }, + { + title: 'Render', + icon: '/docs/img/icons/render-icon', + href: '/guides/resources/migrating-to-supabase/render', + description: 'Migrate your Render Postgres database to Supabase.' + }, + { + title: 'Amazon RDS', + icon: '/docs/img/icons/aws-rds-icon', + href: '/guides/resources/migrating-to-supabase/amazon-rds', + description: 'Migrate your Amazon RDS database to Supabase.' + }, + { + title: 'Postgres', + icon: '/docs/img/icons/postgres-icon', + href: '/guides/resources/migrating-to-supabase/postgres', + description: 'Migrate your Postgres database to Supabase.' + }, + { + title: 'MySQL', + icon: '/docs/img/icons/mysql-icon', + href: '/guides/resources/migrating-to-supabase/mysql', + description: 'Migrate your MySQL database to Supabase.' + }, + { + title: 'Microsoft SQL Server', + icon: '/docs/img/icons/mssql-icon', + href: '/guides/resources/migrating-to-supabase/mssql', + description: 'Migrate your Microsoft SQL Server database to Supabase.' + } + ] + .map((product) => { + return ( + + + {product.description} + + + ) + + })} +
+
+ +
+
+ ### Postgres resources +
+ +
+ { + [ + { + title: 'Managing Indexes', + hasLightIcon: true, + href: '/guides/database/postgres/indexes', + description: 'Improve query performance using various index types in Postgres.' + }, + { + title: 'Cascade Deletes', + hasLightIcon: true, + href: '/guides/database/postgres/cascade-deletes', + description: 'Understand the types of foreign key constraint deletes.' + }, + { + title: 'Drop all tables in schema', + hasLightIcon: true, + href: '/guides/database/postgres/dropping-all-tables-in-schema', + description: 'Delete all tables in a given schema.' + }, + { + title: 'Select first row per group', + hasLightIcon: true, + href: '/guides/database/postgres/first-row-in-group', + description: 'Retrieve the first row in each distinct group.' + }, + { + title: 'Print PostgreSQL version', + hasLightIcon: true, + href: '/guides/database/postgres/which-version-of-postgres', + description: 'Find out which version of Postgres you are running.' + } + ] + .map((resource) => { + return ( + + + {resource.description} + + + ) + + })} +
+
+ + {/* end of container */} +
+ + +# Supabase Security + + + +Supabase is a hosted platform which makes it very simple to get started without needing to manage any infrastructure. The hosted platform comes with many security and compliance controls managed by Supabase. + + +# Compliance + +Supabase is SOC 2 Type 2 compliant and regularly audited. All projects at Supabase are governed by the same set of compliance controls. +The [SOC 2 Compliance Guide](/docs/guides/security/soc-2-compliance) explains Supabase's SOC 2 responsibilities and controls in more detail. + +The [HIPAA Compliance Guide](/docs/guides/security/hipaa-compliance) explains Supabase's HIPAA responsibilities. Additional [security and compliance controls](/docs/guides/deployment/shared-responsibility-model#managing-healthcare-data) for projects that deal with electronic Protected Health Information (ePHI) and require HIPAA compliance are available through the HIPAA add-on. + + +# Platform configuration + +As a hosted platform, Supabase provides additional security controls to further enhance the security posture depending on organizations' own requirements or obligations. + +These can be found under the [dedicated security page](/dashboard/org/_/security) under organization settings. And are described in greater detail [here](/docs/guides/security/platform-security). + + +# Product configuration + +Each product offered by Supabase comes with customizable security controls and these security controls help ensure that applications built on Supabase are secure, compliant, and resilient against various threats. + +The [security configuration guides](/docs/guides/security/product-security) provide detailed information for configuring individual products. + + +# Self-Hosting + +Install and run your own Supabase on your computer, server, or cloud infrastructure. + +## Get started + +The fastest and recommended way to self-host Supabase is using Docker. + +
+
+ + + Docker + Official + + } + showIconBg={true} + > + Deploy Supabase within your own infrastructure using Docker Compose. + + +
+
+ + +## Other deployment options + +{/* supa-mdx-lint-disable-next-line Rule004ExcludeWords */} + +There are several other ways to deploy Supabase with the help of community-driven projects. These projects may be outdated and are seeking active maintainers. If you're interested in maintaining one of these projects, [contact the Community team](/open-source/contributing/supasquad). + +
+ {community.map((x) => ( +
+ + + {x.name} + Maintainer needed + + } + > + {x.description} + + +
+ + ))} +
+ +export const community = [ + { + name: 'Kubernetes', + description: 'Helm charts to deploy a Supabase on Kubernetes.', + href: 'https://github.com/supabase-community/supabase-kubernetes', + }, + { + name: 'Traefik', + description: 'A self-hosted Supabase setup with Traefik as a reverse proxy.', + href: 'https://github.com/supabase-community/supabase-traefik', + }, +] + + +## About self-hosting + +Self-hosting is a good fit if you need full control over your data, have compliance requirements that prevent using managed services, or want to run Supabase in an isolated environment. + + +### How self-hosted Supabase differs + +Self-hosted Supabase is different from: + +* **Supabase CLI** (local development), which is intended for development and testing only. +* **Managed Supabase** platform, which is fully hosted and operated by Supabase. + + +### Telemetry + +Self-hosted Supabase does not phone home or collect any telemetry. + + +### Your responsibilities when self-hosting + +When you self-host, **you are responsible for**: + +* Server provisioning and maintenance +* Security hardening and keeping OS and services updated +* Maintaining the Postgres database +* Backups and disaster recovery +* Monitoring and uptime + + +## Support and community + +Self-hosted Supabase is community-supported. + +For resolving common issues: + +* [GitHub Discussions](https://github.com/orgs/supabase/discussions?discussions_q=is%3Aopen+label%3Aself-hosted) - Questions, feature requests, and workarounds +* [GitHub Issues](https://github.com/supabase/supabase/issues?q=is%3Aissue%20state%3Aopen%20label%3Aself-hosted) - Known issues + +Get help and connect with other users: + +* [Discord](https://discord.supabase.com) - Real-time chat and community support + {/* supa-mdx-lint-disable-next-line Rule003Spelling */} +* [Reddit](https://www.reddit.com/r/Supabase/) - Official Supabase subreddit + +Share your self-hosting experience: + +* [GitHub Discussions](https://github.com/orgs/supabase/discussions/39820) - "Self-hosting: What's working (and what's not)?" + + +### Enterprise self-hosting + +If you're an enterprise using self-hosted Supabase, we'd love to hear from you. Reach out to our [Growth Team](https://forms.supabase.com/enterprise) to discuss your use case, share feedback, or explore design partnership opportunities. + + +# Storage + +Use Supabase to store and serve files. + +Supabase Storage is a robust, scalable solution for managing files of any size with fine-grained access controls and optimized delivery. Whether you're storing user-generated content, analytics data, or vector embeddings, Supabase Storage provides specialized bucket types to meet your specific needs. + + +## Key features + +* **Multi Protocol** - S3 compatible Storage, RESTful API, TUS resumable uploads +* **Global CDN** - Serve your assets with lightning-fast performance from over 285 cities worldwide +* **Image Optimization** - Resize, compress, and transform media files on the fly with built-in image processing +* **Fine-grained Access Control** - Manage file permissions with row-level security and custom policies +* **Multiple Bucket Types** - Specialized storage solutions for different use cases + + +## Storage bucket types + +Supabase Storage offers different bucket types optimized for specific use cases: + + +### Files buckets + +Store and serve traditional files including images, videos, documents, and general-purpose content. Ideal for user-generated content, media libraries, and asset management. + +**Use cases:** Images, videos, documents, PDFs, archives + +**Features:** + +* Global CDN delivery +* Image optimization and transformation +* Row-level security integration +* Direct URL access for files + +[Learn more about Files Buckets](/docs/guides/storage/quickstart) + + +### Analytics buckets + +Purpose-built for storing and analyzing data in open table formats like Apache Iceberg. Perfect for time-series data, logs, and large-scale analytical workloads. + +**Use cases:** Data lakes, analytics pipelines, ETL operations, historical data analysis + +**Features:** + +* Apache Iceberg table format support +* SQL-accessible via Postgres foreign tables +* Partitioned data organization +* Efficient data querying and transformation + +[Learn more about Analytics Buckets](/docs/guides/storage/analytics/introduction) + + +### Vector buckets + +Specialized storage for vector embeddings and similarity search operations. Designed for AI and ML applications requiring semantic search capabilities. + +**Use cases:** AI-powered search, semantic similarity matching, embedding storage, RAG systems + +**Features:** + +* Optimized vector indexing (HNSW, Flat) +* Multiple distance metrics (cosine, euclidean, L2) +* Metadata filtering for vectors +* Similarity search queries + +[Learn more about Vector Buckets](/docs/guides/storage/vector/introduction) + + +## Examples + +Check out all of the Storage [templates and examples](https://github.com/supabase/supabase/tree/master/examples/storage) in our GitHub repository. + +
+ {examples.map((x) => ( +
+ + + {x.description} + + +
+ ))} +
+ +export const examples = [ + { + name: 'Resumable Uploads with Uppy', + description: + 'Use Uppy to upload files to Supabase Storage using the TUS protocol (resumable uploads).', + href: 'https://github.com/supabase/supabase/tree/master/examples/storage/resumable-upload-uppy', + }, +] + + +## Resources + +Find the source code and documentation in the Supabase GitHub repository. + +
+ {[ + { + name: 'Supabase Storage API', + description: 'View the source code.', + href: 'https://github.com/supabase/storage-api', + }, + { + name: 'OpenAPI Spec', + description: 'See the Swagger Documentation for Supabase Storage.', + href: 'https://supabase.github.io/storage/', + }, + ].map((x) => ( +
+ + {x.description} + +
+ ))} +
+ + +# Telemetry + + + +Telemetry helps you understand what’s happening inside your app by collecting logs, metrics, and traces. + +* **Logs** capture individual events, such as errors or warnings, providing details about what happened at a specific moment. +* **Metrics** track numerical data over time, like request latency or database query performance, helping you spot trends. +* **Traces** show the flow of a request through different services, helping you debug slow or failing operations. + +Supabase is working towards full support for the [OpenTelemetry](https://opentelemetry.io/) standard, making it easier to integrate with observability tools. + +This section provides guidance on telemetry in Supabase, including how to work with Supabase Logs. + + +# Advanced Log Filtering + + + +# Querying the logs + + +## Understanding field references + +The log tables are queried with a subset of BigQuery SQL syntax. They all have three columns: `event_message`, `timestamp`, and `metadata`. + +| column | description | +| -------------- | --------------------------- | +| timestamp | time event was recorded | +| event\_message | the log's message | +| metadata | information about the event | + +The `metadata` column is an array of JSON objects that stores important details about each recorded event. For example, in the Postgres table, the `metadata.parsed.error_severity` field indicates the error level of an event. To work with its values, you need to `unnest` them using a `cross join`. + +This approach is commonly used with JSON and array columns, so it might look a bit unfamiliar if you're not used to working with these data types. + +```sql +select + event_message, + parsed.error_severity, + parsed.user_name +from + postgres_logs + -- extract first layer + cross join unnest(postgres_logs.metadata) as metadata + -- extract second layer + cross join unnest(metadata.parsed) as parsed; +``` + + +## Expanding results + +Logs returned by queries may be difficult to read in table format. A row can be double-clicked to expand the results into more readable JSON: + +![Expanding log results](/docs/img/guides/platform/expanded-log-results.png) + + +## Filtering with [regular expressions](https://en.wikipedia.org/wiki/Regular_expression) + +The Logs use BigQuery Style regular expressions with the [regexp\_contains function](https://cloud.google.com/bigquery/docs/reference/standard-sql/string_functions#regexp_contains). In its most basic form, it will check if a string is present in a specified column. + +```sql +select + cast(timestamp as datetime) as timestamp, + event_message, + metadata +from postgres_logs +where regexp_contains(event_message, 'is present'); +``` + +There are multiple operators that you should consider using: + + +### Find messages that start with a phrase + +`^` only looks for values at the start of a string + +```sql +-- find only messages that start with connection +regexp_contains(event_message, '^connection') +``` + + +### Find messages that end with a phrase: + +`$` only looks for values at the end of the string + +```sql +-- find only messages that ends with port=12345 +regexp_contains(event_message, '$port=12345') +``` + + +### Ignore case sensitivity: + +`(?i)` ignores capitalization for all proceeding characters + +```sql +-- find all event_messages with the word "connection" +regexp_contains(event_message, '(?i)COnnecTion') +``` + + +### Wildcards: + +`.` can represent any string of characters + +```sql +-- find event_messages like "helloworld" +regexp_contains(event_message, 'hello.world') +``` + + +### Alphanumeric ranges: + +`[1-9a-zA-Z]` finds any strings with only numbers and letters + +```sql +-- find event_messages that contain a number between 1 and 5 (inclusive) +regexp_contains(event_message, '[1-5]') +``` + + +### Repeated values: + +`x*` zero or more x +`x+` one or more x +`x?` zero or one x +`x{4,}` four or more x +`x{3}` exactly 3 x + +```sql +-- find event_messages that contains any sequence of 3 digits +regexp_contains(event_message, '[0-9]{3}') +``` + + +### Escaping reserved characters: + +`\.` interpreted as period `.` instead of as a wildcard + +```sql +-- escapes . +regexp_contains(event_message, 'hello world\.') +``` + + +### `or` statements: + +`x|y` any string with `x` or `y` present + +```sql +-- find event_messages that have the word 'started' followed by either the word "host" or "authenticated" +regexp_contains(event_message, 'started host|authenticated') +``` + + +### `and`/`or`/`not` statements in SQL: + +`and`, `or`, and `not` are all native terms in SQL and can be used in conjunction with regular expressions to filter results + +```sql +select + cast(timestamp as datetime) as timestamp, + event_message, + metadata +from postgres_logs +where + (regexp_contains(event_message, 'connection') and regexp_contains(event_message, 'host')) + or not regexp_contains(event_message, 'received'); +``` + + +### Filtering and unnesting example + +**Filter for Postgres** + +```sql +select + cast(postgres_logs.timestamp as datetime) as timestamp, + parsed.error_severity, + parsed.user_name, + event_message +from + postgres_logs + cross join unnest(metadata) as metadata + cross join unnest(metadata.parsed) as parsed +where regexp_contains(parsed.error_severity, 'ERROR|FATAL|PANIC') +order by timestamp desc +limit 100; +``` + + +## Limitations + + +### Log tables cannot be joined together + +Each product table operates independently without the ability to join with other log tables. This may change in the future. + + +### The `with` keyword and subqueries are not supported + +The parser does not yet support `with` and subquery statements. + + +### The `ilike` and `similar to` keywords are not supported + +Although `like` and other comparison operators can be used, `ilike` and `similar to` are incompatible with BigQuery's variant of SQL. `regexp_contains` can be used as an alternative. + + +### The wildcard operator `*` to select columns is not supported + +The log parser is not able to parse the `*` operator for column selection. Instead, you can access all fields from the `metadata` column: + +```sql +select + cast(postgres_logs.timestamp as datetime) as timestamp, + event_message, + metadata +from + +order by timestamp desc +limit 100; +``` + + +# Log Drains + + + +Log drains will send all logs of the Supabase stack to one or more desired destinations. It is only available for customers on Team and Enterprise Plans. Log drains is available in the dashboard under [Project Settings > Log Drains](/dashboard/project/_/settings/log-drains). + +You can read about the initial announcement [here](/blog/log-drains) and vote for your preferred drains in [this discussion](https://github.com/orgs/supabase/discussions/28324?sort=top). + + +# Supported destinations + +The following table lists the supported destinations and the required setup configuration: + +| Destination | Transport Method | Configuration | +| --------------------- | ---------------- | -------------------------------------------------- | +| Generic HTTP endpoint | HTTP | URL
HTTP Version
Gzip
Headers | +| DataDog | HTTP | API Key
Region | +| Loki | HTTP | URL
Headers | +| Sentry | HTTP | DSN | + +HTTP requests are batched with a max of 250 logs or 1 second intervals, whichever happens first. Logs are compressed via Gzip if the destination supports it. + + +## Generic HTTP endpoint + +Logs are sent as a POST request with a JSON body. Both HTTP/1 and HTTP/2 protocols are supported. +Custom headers can optionally be configured for all requests. + +Note that requests are **unsigned**. + + + Unsigned requests to HTTP endpoints are temporary and all requests will signed in the near future. + + + + + 1. Create and deploy the edge function + + Generate a new edge function template and update it to log out the received JSON payload. For simplicity, we will accept any request with an Anon Key. + + ```bash + supabase functions new hello-world + ``` + + You can use this example snippet as an illustration of how the received request will be like. + + ```ts + import 'npm:@supabase/functions-js/edge-runtime.d.ts' + + Deno.serve(async (req) => { + const data = await req.json() + + console.log(`Received ${data.length} logs, first log:\n ${JSON.stringify(data[0])}`) + return new Response(JSON.stringify({ message: 'ok' }), { + headers: { 'Content-Type': 'application/json' }, + }) + }) + ``` + + And then deploy it with: + + ```bash + supabase functions deploy hello-world --project-ref [PROJECT REF] + ``` + + + This will create an infinite loop, as we are generating an additional log event that will eventually trigger a new request to this edge function. However, due to the batching nature of how Log Drain events are dispatched, the rate of edge function triggers will not increase greatly and will have an upper bound. + + + 2. Configure the HTTP Drain + + Create a HTTP drain under the [Project Settings > Log Drains](/dashboard/project/_/settings/log-drains). + + * Disable the Gzip, as we want to receive the payload without compression. + * Under URL, set it to your edge function URL `https://[PROJECT REF].supabase.co/functions/v1/hello-world` + * Under Headers, set the `Authorization: Bearer [ANON KEY]` + + + + + + Gzip payloads can be decompressed using native in-built APIs. Refer to the Edge Function [compression guide](/docs/guides/functions/compression) + + ```ts + import { gunzipSync } from 'node:zlib' + + Deno.serve(async (req) => { + try { + // Check if the request body is gzip compressed + const contentEncoding = req.headers.get('content-encoding') + if (contentEncoding !== 'gzip') { + return new Response('Request body is not gzip compressed', { + status: 400, + }) + } + + // Read the compressed body + const compressedBody = await req.arrayBuffer() + + // Decompress the body + const decompressedBody = gunzipSync(new Uint8Array(compressedBody)) + + // Convert the decompressed body to a string + const decompressedString = new TextDecoder().decode(decompressedBody) + const data = JSON.parse(decompressedString) + // Process the decompressed body as needed + console.log(`Received: ${data.length} logs.`) + + return new Response('ok', { + headers: { 'Content-Type': 'text/plain' }, + }) + } catch (error) { + console.error('Error:', error) + return new Response('Error processing request', { status: 500 }) + } + }) + ``` + + + + +## DataDog logs + +Logs sent to DataDog have the name of the log source set on the `service` field of the event and the source set to `Supabase`. Logs are gzipped before they are sent to DataDog. + +The payload message is a JSON string of the raw log event, prefixed with the event timestamp. + +To setup DataDog log drain, generate a DataDog API key [here](https://app.datadoghq.com/organization-settings/api-keys) and the location of your DataDog site. + + + + 1. Generate API Key in [DataDog dashboard](https://app.datadoghq.com/organization-settings/api-keys) + 2. Create log drain in [Supabase dashboard](/dashboard/project/_/settings/log-drains) + 3. Watch for events in the [DataDog Logs page](https://app.datadoghq.com/logs) + + + + [Grok parser](https://docs.datadoghq.com/service_management/events/pipelines_and_processors/grok_parser?tab=matchers) matcher for extracting the timestamp to a `date` field + + ``` + %{date("yyyy-MM-dd'T'HH:mm:ss.SSSSSSZZ"):date} + ``` + + [Grok parser](https://docs.datadoghq.com/service_management/events/pipelines_and_processors/grok_parser?tab=matchers) matcher for converting stringified JSON to structured JSON on the `json` field. + + ``` + %{data::json} + ``` + + [Remapper](https://docs.datadoghq.com/service_management/events/pipelines_and_processors/remapper) for setting the log level. + + ``` + metadata.parsed.error_severity, metadata.level + ``` + + + +If you are interested in other log drains, upvote them [here](https://github.com/orgs/supabase/discussions/28324) + + +## Loki + +Logs sent to the Loki HTTP API are specifically formatted according to the HTTP API requirements. See the official Loki HTTP API documentation for [more details](https://grafana.com/docs/loki/latest/reference/loki-http-api/#ingest-logs). + +Events are batched with a maximum of 250 events per request. + +The log source and product name will be used as stream labels. + +The `event_message` and `timestamp` fields will be dropped from the events to avoid duplicate data. + +Loki must be configured to accept **structured metadata**, and it is advised to increase the default maximum number of structured metadata fields to at least 500 to accommodate large log event payloads of different products. + + +## Sentry + +Logs are sent to Sentry as part of [Sentry's Logging Product](https://docs.sentry.io/product/explore/logs/). Ingesting Supabase logs as Sentry errors is currently not supported. + +To setup the Sentry log drain, you need to do the following: + +1. Grab your DSN from your [Sentry project settings](https://docs.sentry.io/concepts/key-terms/dsn-explainer/). It should be of the format `{PROTOCOL}://{PUBLIC_KEY}:{SECRET_KEY}@{HOST}{PATH}/{PROJECT_ID}`. +2. Create log drain in [Supabase dashboard](/dashboard/project/_/settings/log-drains) +3. Watch for events in the [Sentry Logs page](https://sentry.io/explore/logs/) + +All fields from the log event are attached as attributes to the Sentry log, which can be used for filtering and grouping in the Sentry UI. There are no limits to cardinality or the number of attributes that can be attached to a log. + +If you are self-hosting Sentry, Sentry Logs are only supported in self-hosted version [25.9.0](https://github.com/getsentry/self-hosted/releases/tag/25.9.0) and later. + + +## Pricing + +For a detailed breakdown of how charges are calculated, refer to [Manage Log Drain usage](/docs/guides/platform/manage-your-usage/log-drains). + + +# Logging + + + +The Supabase Platform includes a Logs Explorer that allows log tracing and debugging. Log retention is based on your [project's pricing plan](/pricing). + + +## Product logs + +Supabase provides a logging interface specific to each product. You can use simple regular expressions for keywords and patterns to search log event messages. You can also export and download the log events matching your query as a spreadsheet. + +{/* */} + + + + [API logs](/dashboard/project/_/logs/edge-logs) show all network requests and response for the REST and GraphQL [APIs](../../guides/database/api). If [Read Replicas](/docs/guides/platform/read-replicas) are enabled, logs are automatically filtered between databases as well as the [API Load Balancer](/docs/guides/platform/read-replicas#api-load-balancer) endpoint. Logs for a specific endpoint can be toggled with the `Source` button on the upper-right section of the dashboard. + + When viewing logs originating from the API Load Balancer endpoint, the upstream database or the one that eventually handles the request can be found under the `Redirect Identifier` field. This is equivalent to `metadata.load_balancer_redirect_identifier` when querying the underlying logs. + + ![API Logs](/docs/img/guides/platform/logs/logs-api.png) + + + + [Postgres logs](/dashboard/project/_/logs/postgres-logs) show queries and activity for your [database](../../guides/database). If [Read Replicas](/docs/guides/platform/read-replicas) are enabled, logs are automatically filtered between databases. Logs for a specific database can be toggled with the `Source` button on the upper-right section of the dashboard. + + ![Postgres Logs](/docs/img/guides/platform/logs/logs-database.png) + + + + [Auth logs](/dashboard/project/_/logs/auth-logs) show all server logs for your [Auth usage](../../guides/auth). + + ![Auth Logs](/docs/img/guides/platform/logs/logs-auth.png) + + + + [Storage logs](/dashboard/project/_/logs/storage-logs) shows all server logs for your [Storage API](../../guides/storage). + + ![Storage Logs](/docs/img/guides/platform/logs/logs-storage.png) + + + + [Realtime logs](/dashboard/project/_/logs/realtime-logs) show all server logs for your [Realtime API usage](../../guides/realtime). + + + Realtime connections are not logged by default. Turn on [Realtime connection logs per client](#logging-realtime-connections) with the `log_level` parameter. + + + ![Realtime Logs](/docs/img/guides/platform/logs/logs-realtime.png) + + + + For each [Edge Function](/dashboard/project/_/functions), logs are available under the following tabs: + + **Invocations** + + The Invocations tab displays the edge logs of function calls. + + ![Function Edge Logs](/docs/img/guides/platform/logs/logs-functions-edge.png) + + **Logs** + + The Logs tab displays logs emitted during function execution. + + ![Function Logs](/docs/img/guides/platform/logs/logs-functions.png) + + **Log Message Length** + + Edge Function log messages have a max length of 10,000 characters. If you try to log a message longer than that it will be truncated. + + + +*** + + +## Working with API logs + +[API logs](/dashboard/project/_/logs/edge-logs) run through the Cloudflare edge servers and will have attached Cloudflare metadata under the `metadata.request.cf.*` fields. + + +### Allowed headers + +A strict list of request and response headers are permitted in the API logs. Request and response headers will still be received by the server(s) and client(s), but will not be attached to the API logs generated. + +Request headers: + +* `accept` +* `cf-connecting-ip` +* `cf-ipcountry` +* `host` +* `user-agent` +* `x-forwarded-proto` +* `referer` +* `content-length` +* `x-real-ip` +* `x-client-info` +* `x-forwarded-user-agent` +* `range` +* `prefer` + +Response headers: + +* `cf-cache-status` +* `cf-ray` +* `content-location` +* `content-range` +* `content-type` +* `content-length` +* `date` +* `transfer-encoding` +* `x-kong-proxy-latency` +* `x-kong-upstream-latency` +* `sb-gateway-mode` +* `sb-gateway-version` + + +### Additional request metadata + +To attach additional metadata to a request, it is recommended to use the `User-Agent` header for purposes such as device or version identification. + +For example: + +``` +node MyApp/1.2.3 (device-id:abc123) +Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0 MyApp/1.2.3 (Foo v1.3.2; Bar v2.2.2) +``` + + + Do not log Personal Identifiable Information (PII) within the `User-Agent` header, to avoid infringing data protection privacy laws. Overly fine-grained and detailed user agents may allow fingerprinting and identification of the end user through PII. + + + +## Logging Postgres queries + +To enable query logs for other categories of statements: + +1. [Enable the pgAudit extension](/dashboard/project/_/database/extensions). +2. Configure `pgaudit.log` (see below). Perform a fast reboot if needed. +3. View your query logs under [Logs > Postgres Logs](/dashboard/project/_/logs/postgres-logs). + + +### Configuring `pgaudit.log` + +The stored value under `pgaudit.log` determines the classes of statements that are logged by [pgAudit extension](https://www.pgaudit.org/). Refer to the pgAudit documentation for the [full list of values](https://github.com/pgaudit/pgaudit/blob/master/README.md#pgauditlog). + +To enable logging for function calls/do blocks, writes, and DDL statements for a single session, execute the following within the session: + +```sql +-- temporary single-session config update +set pgaudit.log = 'function, write, ddl'; +``` + +To *permanently* set a logging configuration (beyond a single session), execute the following, then perform a fast reboot: + +```sql +-- equivalent permanent config update. +alter role postgres set pgaudit.log to 'function, write, ddl'; +``` + +To help with debugging, we recommend adjusting the log scope to only relevant statements as having too wide of a scope would result in a lot of noise in your Postgres logs. + +Note that in the above example, the role is set to `postgres`. To log user-traffic flowing through the [HTTP APIs](../../guides/database/api#rest-api-overview) powered by PostgREST, set your configuration values for the `authenticator`. + +```sql +-- for API-related logs +alter role authenticator set pgaudit.log to 'write'; +``` + +By default, the log level will be set to `log`. To view other levels, run the following: + +```sql +-- adjust log level +alter role postgres set pgaudit.log_level to 'info'; +alter role postgres set pgaudit.log_level to 'debug5'; +``` + +Note that as per the pgAudit [log\_level documentation](https://github.com/pgaudit/pgaudit/blob/master/README.md#pgauditlog_level), `error`, `fatal`, and `panic` are not allowed. + +To reset system-wide settings, execute the following, then perform a fast reboot: + +```sql +-- resets stored config. +alter role postgres reset pgaudit.log +``` + + + If any permission errors are encountered when executing `alter role postgres ...`, it is likely that your project has yet to receive the patch to the latest version of [supautils](https://github.com/supabase/supautils), which is currently being rolled out. + + + +### `RAISE`d log messages in Postgres + +Messages that are manually logged via `RAISE INFO`, `RAISE NOTICE`, `RAISE WARNING`, and `RAISE LOG` are shown in Postgres Logs. Note that only messages at or above your logging level are shown. Syncing of messages to Postgres Logs may take a few minutes. + +If your logs aren't showing, check your logging level by running: + +```sql +show log_min_messages; +``` + +Note that `LOG` is a higher level than `WARNING` and `ERROR`, so if your level is set to `LOG`, you will not see `WARNING` and `ERROR` messages. + + +## Logging realtime connections + +Realtime doesn't log new WebSocket connections or Channel joins by default. Enable connection logging per client by including an `info` `log_level` parameter when instantiating the Supabase client. + +```javascript +import { createClient } from '@supabase/supabase-js' + +const options = { + realtime: { + params: { + log_level: 'info', + }, + }, +} +const supabase = createClient('https://xyzcompany.supabase.co', 'publishable-or-anon-key', options) +``` + + +## Logs Explorer + +The [Logs Explorer](/dashboard/project/_/logs-explorer) exposes logs from each part of the Supabase stack as a separate table that can be queried and joined using SQL. + +![Logs Explorer](/docs/img/guides/platform/logs/logs-explorer.png) + +You can access the following logs from the **Sources** drop-down: + +* `auth_logs`: GoTrue server logs, containing authentication/authorization activity. +* `edge_logs`: Edge network logs, containing request and response metadata retrieved from Cloudflare. +* `function_edge_logs`: Edge network logs for only edge functions, containing network requests and response metadata for each execution. +* `function_logs`: Function internal logs, containing any `console` logging from within the edge function. +* `postgres_logs`: Postgres database logs, containing statements executed by connected applications. +* `realtime_logs`: Realtime server logs, containing client connection information. +* `storage_logs`: Storage server logs, containing object upload and retrieval information. + + +## Querying with the Logs Explorer + +The Logs Explorer uses BigQuery and supports all [available SQL functions and operators](https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators). + + +### Timestamp display and behavior + +Each log entry is stored with a `timestamp` as a `TIMESTAMP` data type. Use the appropriate [timestamp function](https://cloud.google.com/bigquery/docs/reference/standard-sql/timestamp_functions#timestamp) to utilize the `timestamp` field in a query. + +Raw top-level timestamp values are rendered as unix microsecond. To render the timestamps in a human-readable format, use the `DATETIME()` function to convert the unix timestamp display into an ISO-8601 timestamp. + +```sql +-- timestamp column without datetime() +select timestamp from .... +-- 1664270180000 + +-- timestamp column with datetime() +select datetime(timestamp) from .... +-- 2022-09-27T09:17:10.439Z +``` + + +### Unnesting arrays + +Each log event stores metadata an array of objects with multiple levels, and can be seen by selecting single log events in the Logs Explorer. To query arrays, use `unnest()` on each array field and add it to the query as a join. This allows you to reference the nested objects with an alias and select their individual fields. + +For example, to query the edge logs without any joins: + +```sql +select timestamp, metadata from edge_logs as t; +``` + +The resulting `metadata` key is rendered as an array of objects in the Logs Explorer. In the following diagram, each box represents a nested array of objects: + +{/* */} + +![Without Unnesting](/docs/img/unnesting-none.png) + +Perform a `cross join unnest()` to work with the keys nested in the `metadata` key. + +To query for a nested value, add a join for each array level: + +```sql +select timestamp, request.method, header.cf_ipcountry +from + edge_logs as t + cross join unnest(t.metadata) as metadata + cross join unnest(metadata.request) as request + cross join unnest(request.headers) as header; +``` + +This surfaces the following columns available for selection: +![With Two Level Unnesting](/docs/img/unnesting-2.png) + +This allows you to select the `method` and `cf_ipcountry` columns. In JS dot notation, the full paths for each selected column are: + +* `metadata[].request[].method` +* `metadata[].request[].headers[].cf_ipcountry` + + +### LIMIT and result row limitations + +The Logs Explorer has a maximum of 1000 rows per run. Use `LIMIT` to optimize your queries by reducing the number of rows returned further. + + +### Best practices + +1. Include a filter over **timestamp** + +Querying your entire log history might seem appealing. For **Enterprise** customers that have a large retention range, you run the risk of timeouts due additional time required to scan the larger dataset. + +2. Avoid selecting large nested objects. Select individual values instead. + +When querying large objects, the columnar storage engine selects each column associated with each nested key, resulting in a large number of columns being selected. This inadvertently impacts the query speed and may result in timeouts or memory errors, especially for projects with a lot of logs. + +Instead, select only the values required. + +```sql +-- ❌ Avoid doing this +select + datetime(timestamp), + m as metadata -- <- metadata contains many nested keys +from + edge_logs as t + cross join unnest(t.metadata) as m; + +-- ✅ Do this +select + datetime(timestamp), + r.method -- <- select only the required values +from + edge_logs as t + cross join unnest(t.metadata) as m + cross join unnest(m.request) as r; +``` + + +### Examples and templates + +The Logs Explorer includes **Templates** (available in the Templates tab or the dropdown in the Query tab) to help you get started. + +For example, you can enter the following query in the SQL Editor to retrieve each user's IP address: + +```sql +select datetime(timestamp), h.x_real_ip +from + edge_logs + cross join unnest(metadata) as m + cross join unnest(m.request) as r + cross join unnest(r.headers) as h +where h.x_real_ip is not null and r.method = "GET"; +``` + + +### Logs field reference + +Refer to the full field reference for each available source below. Do note that in order to access each nested key, you would need to perform the [necessary unnesting joins](#unnesting-arrays) + + + {(logConstants) => ( + + {logConstants.schemas.map((schema) => ( + + + + + + + + + + {schema.fields + .sort((a, b) => a.path - b.path) + .map((field) => ( + + + + + ))} + +
PathType
{field.path}{field.type}
+
+ ))} +
+ )} +
+ + +# Metrics API + + + +Every Supabase project exposes a [Prometheus](https://prometheus.io/)-compatible **Metrics API** endpoint that surfaces ~200 Postgres performance and health series. You can scrape it into any observability stack to power custom dashboards, alerting rules, or long-term retention that goes beyond what Supabase Studio provides out of the box. + + + The Metrics API is currently in beta. Metric names and labels might evolve as we expand the dataset, and the feature is not available in self-hosted Supabase instances. + + + +## What you can do with the Metrics API + +* Stream database CPU, IO, WAL, connection, and query stats into Prometheus-compatible systems. +* Combine Supabase metrics with application signals in Grafana, Datadog, or any other observability vendor. +* Reuse our [supabase-grafana dashboard JSON](https://github.com/supabase/supabase-grafana) to bootstrap over 200 ready-made charts. +* Build your own alerting policies (right-sizing, saturation detection, index regression, and more). + + + What you can do with the Metrics API} id="how-do-i-check-when-a-user-went-through-mfa" className="border-0 px-2 py-4"> + Every Supabase project exposes a metrics feed at `https://.supabase.co/customer/v1/privileged/metrics`. Replace `` with the identifier from your project URL or from the dashboard sidebar. + + 1. Copy your project reference and confirm the base URL using the helper below. + + + + 2. Configure your collector to scrape once per minute. The endpoint already emits the full set of metrics on each request. + 3. Authenticate with HTTP Basic Auth: + + * **Username**: `service_role` + * **Password**: a service role secret (JWT) from [**Project Settings > JWT**](/dashboard/project/_/settings/jwt) or any other Secret API key from [**Project Settings > API keys** (opens in a new tab)](/dashboard/project/_/settings/api-keys) + + Testing locally is as simple as running `curl` with your service role secret: + + ```bash + curl /customer/v1/privileged/metrics \ + --user 'service_role:sb_secret_...' + ``` + + You can provision long-lived automation tokens in two ways: + + * Create an account access token once at [**Account Settings > Access Tokens**](/dashboard/account/tokens) and reuse it wherever you configure observability tooling. + * **Optional**: programmatically exchange an access token for project API keys via the [Management API ](/docs/reference/api/management-projects-api-keys-retrieve'). + + ```bash + # (Optional) Exchange an account access token for project API keys + export SUPABASE_ACCESS_TOKEN="your-access-token" + export PROJECT_REF="your-project-ref" + + curl -H "Authorization: Bearer $SUPABASE_ACCESS_TOKEN" \ + "https://api.supabase.com/v1/projects/$PROJECT_REF/api-keys?reveal=true" + ``` + + + + +## Choose your monitoring stack + +Pick the workflow that best matches your tooling. Cards link to Supabase-authored guides or vendor integration docs, and some include a “Community” pill when there’s an accompanying vendor reference. + + + +Supabase Grafana dashboard showcasing database metrics + + +## Additional resources + +* [Supabase Grafana repository](https://github.com/supabase/supabase-grafana) for dashboard JSON and alert examples. +* [Grafana Cloud’s Supabase integration doc](https://grafana.com/docs/grafana-cloud/monitor-infrastructure/integrations/integration-reference/integration-supabase/) (community-maintained, built on this Metrics API). +* [Datadog’s Supabase integration doc](https://docs.datadoghq.com/integrations/supabase/) (community-maintained, built on this Metrics API). +* [Log Drains ](/docs/guides/telemetry/log-drains) for exporting event-based telemetry alongside metrics. +* [Query Performance report](/dashboard/project/_/observability/query-performance) for built-in visualizations based on the same underlying metrics. + + +# Reports + + + +Supabase Reports provide comprehensive observability for your project through dedicated monitoring dashboards that visualize key metrics across your database, auth, storage, realtime, and API systems. Each report offers self-debugging tools to gain actionable insights for optimizing performance and troubleshooting issues. + + + Reports are only available for projects hosted on the Supabase Cloud platform and are not available for self-hosted instances. + + + +## Using reports + +Reports can be filtered by time range to focus your analysis on specific periods. Available time ranges are gated by your organization's plan, with higher-tier plans providing access to longer historical periods. + +| Time Range | Free | Pro | Team | Enterprise | +| --------------- | ---- | --- | ---- | ---------- | +| Last 10 minutes | ✅ | ✅ | ✅ | ✅ | +| Last 30 minutes | ✅ | ✅ | ✅ | ✅ | +| Last 60 minutes | ✅ | ✅ | ✅ | ✅ | +| Last 3 hours | ✅ | ✅ | ✅ | ✅ | +| Last 24 hours | ✅ | ✅ | ✅ | ✅ | +| Last 7 days | ❌ | ✅ | ✅ | ✅ | +| Last 14 days | ❌ | ❌ | ✅ | ✅ | +| Last 28 days | ❌ | ❌ | ✅ | ✅ | + +*** + + +## Database + +The Database report provides the most comprehensive view into your Postgres instance's health and performance characteristics. These charts help you identify performance bottlenecks, resource constraints, and optimization opportunities at a glance. + +The following charts are available for Free and Pro plans: + +| Chart | Available Plans | Description | Key Insights | +| ---------------------------- | --------------- | -------------------------------------------- | --------------------------------------------- | +| Memory usage | Free, Pro | RAM usage percentage by the database | Memory pressure and resource utilization | +| CPU usage | Free, Pro | Average CPU usage percentage | CPU-intensive query identification | +| Disk IOPS | Free, Pro | Read/write operations per second with limits | IO bottleneck detection and workload analysis | +| Database connections | Free, Pro | Number of pooler connections to the database | Connection pool monitoring | +| Shared Pooler connections | All | Client connections to the shared pooler | Shared pooler usage patterns | +| Dedicated Pooler connections | All | Client connections to PgBouncer | Dedicated pooler connection monitoring | + +{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */} + + +### Advanced Telemetry + +The following charts provide a more advanced and detailed view of your database performance and are available only for Team, Enterprise, and Platform plans. + + +### Memory usage + +Memory usage chart + +| Component | Description | +| ------------------- | ------------------------------------------------------ | +| **Used** | RAM actively used by Postgres and the operating system | +| **Cache + buffers** | Memory used for page cache and Postgres buffers | +| **Free** | Available unallocated memory | + +How it helps debug issues: + +| Issue | Description | +| ------------------------------ | ------------------------------------------------ | +| Memory pressure detection | Identify when free memory is consistently low | +| Cache effectiveness monitoring | Monitor cache performance for query optimization | +| Memory leak detection | Detect inefficient memory usage patterns | + +Actions you can take: + +| Action | Description | +| --------------------------------------------------------------------------- | ---------------------------------------------- | +| [Upgrade compute size](/docs/guides/platform/compute-and-disk#compute-size) | Increase available memory resources | +| Optimize queries | Reduce memory consumption of expensive queries | +| Tune Postgres configuration | Improve memory management settings | +| Implement application caching | Add query result caching to reduce memory load | + + +### CPU usage + +CPU usage chart + +| Category | Description | +| ---------- | ------------------------------------------------ | +| **System** | CPU time for kernel operations | +| **User** | CPU time for database queries and user processes | +| **IOWait** | CPU time waiting for disk/network IO | +| **IRQs** | CPU time handling interrupts | +| **Other** | CPU time for miscellaneous tasks | + +How it helps debug issues: + +| Issue | Description | +| ---------------------------------- | -------------------------------------------------- | +| CPU-intensive query identification | Identify expensive queries when User CPU is high | +| IO bottleneck detection | Detect disk/network issues when IOWait is elevated | +| System overhead monitoring | Monitor resource contention and kernel overhead | + +Actions you can take: + +| Action | Description | +| -------------------------------------------------------------- | --------------------------------------------------------------------------- | +| Optimize CPU-intensive queries | Target queries causing high User CPU usage | +| Address IO bottlenecks | Resolve disk/network issues when IOWait is high | +| [Upgrade compute size](/docs/guides/platform/compute-and-disk) | Increase available CPU capacity | +| Implement proper indexing | Use [query optimization](/docs/guides/database/postgres/indexes) techniques | + + +### Disk input/output operations per second (IOPS) + +Disk IOPS chart + +This chart displays read and write IOPS with a reference line showing your compute size's maximum IOPS capacity. + +How it helps debug issues: + +| Issue | Description | +| --------------------------------- | ---------------------------------------------------------------- | +| Disk IO bottleneck identification | Identify when disk IO becomes a performance constraint | +| Workload pattern analysis | Distinguish between read-heavy vs write-heavy operations | +| Performance correlation | Spot disk activity spikes that correlate with performance issues | + +Actions you can take: + +| Action | Description | +| -------------------------------------------------------------- | --------------------------------------------------------- | +| Optimize indexing | Reduce high read IOPS through better query indexing | +| Consider read replicas | Distribute read-heavy workloads across multiple instances | +| Batch write operations | Reduce write IOPS by grouping database writes | +| [Upgrade compute size](/docs/guides/platform/compute-and-disk) | Increase IOPS limits with larger compute instances | + + +### Disk throughput + +Available on Team and Enterprise plans. + +This chart displays read and write throughput (bytes per second) with a reference line showing your compute size's maximum disk throughput. + +How it helps debug issues: + +| Issue | Description | +| ------------------------------------ | ------------------------------------------------------- | +| Throughput bottleneck identification | Spot when disk bandwidth is saturated | +| Workload pattern analysis | Differentiate read-heavy vs write-heavy bandwidth usage | +| Performance correlation | Correlate spikes with query performance changes | + +Actions you can take: + +| Action | Description | +| -------------------------------------------------------------- | ------------------------------------------------------------- | +| Optimize query patterns | Reduce large sequential reads/writes | +| Tune caching and batching | Minimize repeated disk access and improve throughput headroom | +| [Upgrade compute size](/docs/guides/platform/compute-and-disk) | Increase throughput limits for sustained workloads | + + +### Disk size + +Disk Size chart + +| Component | Description | +| ------------ | --------------------------------------------------------- | +| **Database** | Space used by your actual database data (tables, indexes) | +| **WAL** | Space used by Write-Ahead Logging | +| **System** | Reserved space for system operations | + +How it helps debug issues: + +| Issue | Description | +| ----------------------------- | ------------------------------------------- | +| Space consumption monitoring | Track disk usage trends over time | +| Growth pattern identification | Identify rapid growth requiring attention | +| Capacity planning | Plan upgrades before hitting storage limits | + +Actions you can take: + +| Action | Description | +| -------------------------------------------------------------------------------- | -------------------------------------------------------------------- | +| Run [VACUUM](https://www.postgresql.org/docs/current/sql-vacuum.html) operations | Reclaim dead tuple space and optimize storage | +| Analyze large tables | Use CLI commands like `table-sizes` to identify optimization targets | +| Implement data archival | Archive historical data to reduce active storage needs | +| [Upgrade disk size](/docs/guides/platform/database-size) | Increase storage capacity when approaching limits | + + +### Database connections + +Database connections chart + +| Connection Type | Description | +| --------------- | ------------------------------------------------ | +| **Postgres** | Direct connections from your application | +| **PostgREST** | Connections from the PostgREST API layer | +| **Reserved** | Administrative connections for Supabase services | +| **Auth** | Connections from Supabase Auth service | +| **Storage** | Connections from Supabase Storage service | +| **Other roles** | Miscellaneous database connections | + +How it helps debug issues: + +| Issue | Description | +| ------------------------------- | ----------------------------------------------------------- | +| Connection pool exhaustion | Identify when approaching maximum connection limits | +| Connection leak detection | Spot applications not properly closing connections | +| Service distribution monitoring | Monitor connection usage across different Supabase services | + +Actions you can take: + +| Action | Description | +| ------------------------------------------------------------------------------------------ | --------------------------------------------------------------- | +| [Upgrade compute size](/docs/guides/platform/compute-and-disk#compute-size) | Increase maximum connection limits | +| Implement [connection pooling](/docs/guides/database/connecting-to-postgres#shared-pooler) | Optimize connection management for high direct connection usage | +| Review application code | Ensure proper connection handling and cleanup | + + +## Auth + +The Auth report focuses on user authentication patterns and behaviors within your Supabase project. + +| Chart | Description | Key Insights | +| ------------------------ | --------------------------------------------- | ----------------------------------------------- | +| Active Users | Count of unique users performing auth actions | User engagement and retention patterns | +| Sign In Attempts by Type | Breakdown of authentication methods used | Password vs OAuth vs magic link preferences | +| Sign Ups | Total new user registrations | Growth trends and onboarding funnel performance | +| Auth Errors | Error rates grouped by status code | Authentication friction and security issues | +| Password Reset Requests | Volume of password recovery attempts | User experience pain points | + + +## Storage + +The Storage report provides visibility into how your Supabase Storage is being utilized, including request patterns, performance characteristics, and caching effectiveness. + +| Chart | Description | Key Insights | +| --------------- | ------------------------------------------ | ------------------------------------------------------ | +| Total Requests | Overall request volume to Storage | Traffic patterns and usage trends | +| Response Speed | Average response time for storage requests | Performance bottlenecks and optimization opportunities | +| Network Traffic | Ingress and egress usage | Data transfer costs and CDN effectiveness | +| Request Caching | Cache hit rates and miss patterns | CDN performance and cost optimization | +| Top Routes | Most frequently accessed storage paths | Popular content and usage patterns | + + +## Realtime + +The Realtime report tracks WebSocket connections, channel activity, and real-time event patterns in your Supabase project. + +| Chart | Description | Key Insights | +| ---------------------------------------------------------- | --------------------------------------------------------------------------------------- | ------------------------------------------------- | +| Realtime Connections | Active WebSocket connections over time | Concurrent user activity and connection stability | +| Broadcast Events | Broadcast events over time | Real-time feature usage patterns | +| Presence Events | Presence events over time | Real-time feature usage patterns | +| Postgres Changes Events | Postgres Changes events over time | Real-time feature usage patterns | +| Rate of Channel Joins | Frequency of new channel subscriptions | User engagement with real-time features | +| Message Payload Size | Median size of message payloads sent | Payload size that is being transmitted | +| Broadcast From Database Replication Lag | Median latency between database commit and broadcast when using broadcast from database | Latency to Broadcast from the database | +| Read/Write Private Channel Subscription RLS Execution Time | Median time to authorize private channels | `realtime.messages` RLS policies performance | +| Total Requests | HTTP requests to Realtime endpoints | API usage alongside WebSocket activity | +| Response Speed | Performance of Realtime API endpoints | Infrastructure optimization opportunities | + + +## Edge Functions + +The Edge Functions report provides insights into serverless function performance, execution patterns, and regional distribution across Supabase's global edge network. + +| Chart | Description | Key Insights | +| ---------------------- | ----------------------------------------- | ---------------------------------------------- | +| Execution Status Codes | Function response codes and error rates | Function reliability and error patterns | +| Execution Time | Average function duration and performance | Performance optimization opportunities | +| Invocations by Region | Geographic distribution of function calls | Global usage patterns and latency optimization | + + +## API gateway + +The API Gateway report analyzes traffic patterns and performance characteristics of requests flowing through your Supabase project's API layer. + +| Chart | Description | Key Insights | +| --------------- | ----------------------------------------- | ------------------------------------------------ | +| Total Requests | Overall API request volume | Traffic patterns and growth trends | +| Response Errors | Error rates with 4XX and 5XX status codes | API reliability and user experience issues | +| Response Speed | Average API response times | Performance bottlenecks and optimization targets | +| Network Traffic | Request and response egress usage | Data transfer patterns and cost implications | +| Top Routes | Most frequently accessed API endpoints | Usage patterns and optimization priorities | + + +# Sentry integration + +Integrate Sentry to monitor errors from a Supabase client + +You can use [Sentry](https://sentry.io/welcome/) to monitor errors thrown from a Supabase JavaScript client. Install the [Supabase Sentry integration](https://github.com/supabase-community/sentry-integration-js) to get started. + +The Sentry integration supports browser, Node, and edge environments. + + +## Installation + +Install the Sentry integration using your package manager: + + + + ```sh + npm install @supabase/sentry-js-integration + ``` + + + + ```sh + yarn add @supabase/sentry-js-integration + ``` + + + + ```sh + pnpm add @supabase/sentry-js-integration + ``` + + + + +## Use + + + If you are using Sentry JavaScript SDK v7, reference [`supabase-community/sentry-integration-js` repository](https://github.com/supabase-community/sentry-integration-js/blob/master/README-v7.md) instead. + + +To use the Supabase Sentry integration, add it to your `integrations` list when initializing your Sentry client. + +You can supply either the Supabase Client constructor or an already-initiated instance of a Supabase Client. + + + + ```ts + import * as Sentry from '@sentry/browser' + import { SupabaseClient } from '@supabase/supabase-js' + import { supabaseIntegration } from '@supabase/sentry-js-integration' + + Sentry.init({ + dsn: SENTRY_DSN, + integrations: [ + supabaseIntegration(SupabaseClient, Sentry, { + tracing: true, + breadcrumbs: true, + errors: true, + }), + ], + }) + ``` + + + + ```ts + import * as Sentry from '@sentry/browser' + import { createClient } from '@supabase/supabase-js' + import { supabaseIntegration } from '@supabase/sentry-js-integration' + + const supabaseClient = createClient(SUPABASE_URL, SUPABASE_KEY) + + Sentry.init({ + dsn: SENTRY_DSN, + integrations: [ + supabaseIntegration(supabaseClient, Sentry, { + tracing: true, + breadcrumbs: true, + errors: true, + }), + ], + }) + ``` + + + +All available configuration options are available in our [`supabase-community/sentry-integration-js` repository](https://github.com/supabase-community/sentry-integration-js/blob/master/README.md#options). + + +## Deduplicating spans + +If you're already monitoring HTTP errors in Sentry, for example with the HTTP, Fetch, or Undici integrations, you will get duplicate spans for Supabase calls. You can deduplicate the spans by skipping them in your other integration: + +```ts +import * as Sentry from '@sentry/browser' +import { SupabaseClient } from '@supabase/supabase-js' +import { supabaseIntegration } from '@supabase/sentry-js-integration' + +Sentry.init({ + dsn: SENTRY_DSN, + integrations: [ + supabaseIntegration(SupabaseClient, Sentry, { + tracing: true, + breadcrumbs: true, + errors: true, + }), + + // @sentry/browser + Sentry.browserTracingIntegration({ + shouldCreateSpanForRequest: (url) => { + return !url.startsWith(`${SUPABASE_URL}/rest`) + }, + }), + + // or @sentry/node + Sentry.httpIntegration({ + tracing: { + ignoreOutgoingRequests: (url) => { + return url.startsWith(`${SUPABASE_URL}/rest`) + }, + }, + }), + + // or @sentry/node with Fetch support + Sentry.nativeNodeFetchIntegration({ + ignoreOutgoingRequests: (url) => { + return url.startsWith(`${SUPABASE_URL}/rest`) + }, + }), + + // or @sentry/WinterCGFetch for Next.js Proxy & Edge Functions + Sentry.winterCGFetchIntegration({ + breadcrumbs: true, + shouldCreateSpanForRequest: (url) => { + return !url.startsWith(`${SUPABASE_URL}/rest`) + }, + }), + ], +}) +``` + + +## Example Next.js configuration + +See this example for a setup with Next.js to cover browser, server, and edge environments. First, run through the [Sentry Next.js wizard](https://docs.sentry.io/platforms/javascript/guides/nextjs/#install) to generate the base Next.js configuration. Then add the Supabase Sentry Integration to all your `Sentry.init` calls with the appropriate filters. + + + + ```ts sentry.client.config.ts + import * as Sentry from '@sentry/nextjs' + import { SupabaseClient } from '@supabase/supabase-js' + import { supabaseIntegration } from '@supabase/sentry-js-integration' + + Sentry.init({ + dsn: SENTRY_DSN, + integrations: [ + supabaseIntegration(SupabaseClient, Sentry, { + tracing: true, + breadcrumbs: true, + errors: true, + }), + Sentry.browserTracingIntegration({ + shouldCreateSpanForRequest: (url) => { + return !url.startsWith(`${process.env.NEXT_PUBLIC_SUPABASE_URL}/rest`) + }, + }), + ], + + // Adjust this value in production, or use tracesSampler for greater control + tracesSampleRate: 1, + + // Setting this option to true will print useful information to the console while you're setting up Sentry. + debug: true, + }) + ``` + + + + ```ts sentry.server.config.ts + import * as Sentry from '@sentry/nextjs' + import { SupabaseClient } from '@supabase/supabase-js' + import { supabaseIntegration } from '@supabase/sentry-js-integration' + + Sentry.init({ + dsn: SENTRY_DSN, + integrations: [ + supabaseIntegration(SupabaseClient, Sentry, { + tracing: true, + breadcrumbs: true, + errors: true, + }), + Sentry.nativeNodeFetchIntegration({ + breadcrumbs: true, + ignoreOutgoingRequests: (url) => { + return url.startsWith(`${process.env.NEXT_PUBLIC_SUPABASE_URL}/rest`) + }, + }), + ], + // Adjust this value in production, or use tracesSampler for greater control + tracesSampleRate: 1, + + // Setting this option to true will print useful information to the console while you're setting up Sentry. + debug: true, + }) + ``` + + + + ```js sentry.edge.config.ts + import * as Sentry from '@sentry/nextjs' + import { SupabaseClient } from '@supabase/supabase-js' + import { supabaseIntegration } from '@supabase/sentry-js-integration' + + Sentry.init({ + dsn: SENTRY_DSN, + integrations: [ + supabaseIntegration(SupabaseClient, Sentry, { + tracing: true, + breadcrumbs: true, + errors: true, + }), + Sentry.winterCGFetchIntegration({ + breadcrumbs: true, + shouldCreateSpanForRequest: (url) => { + return !url.startsWith(`${process.env.NEXT_PUBLIC_SUPABASE_URL}/rest`) + }, + }), + ], + // Adjust this value in production, or use tracesSampler for greater control + tracesSampleRate: 1, + + // Setting this option to true will print useful information to the console while you're setting up Sentry. + debug: true, + }) + ``` + + + + ```js instrumentation.ts + // https://nextjs.org/docs/app/building-your-application/optimizing/instrumentation + export async function register() { + if (process.env.NEXT_RUNTIME === 'nodejs') { + await import('./sentry.server.config') + } + + if (process.env.NEXT_RUNTIME === 'edge') { + await import('./sentry.edge.config') + } + } + ``` + + + +Afterwards, build your application (`npm run build`) and start it locally (`npm run start`). You will now see the transactions being logged in the terminal when making supabase-js requests. + + +# Metrics API with Grafana Cloud + + + +Grafana Cloud gives you a fully managed Prometheus endpoint plus hosted Grafana dashboards, which makes it the fastest way to explore the Supabase Metrics API without operating your own infrastructure. + + + Grafana maintains a [Supabase integration guide](https://grafana.com/docs/grafana-cloud/monitor-infrastructure/integrations/integration-reference/integration-supabase/) for Grafana Cloud. It runs on the same Metrics API documented here, but is community-maintained by Grafana, so feature coverage might differ from what Supabase officially supports. + + + +## Prerequisites + +* A Supabase project with access to the Metrics API (service role key or another secret key). +* A Grafana Cloud account with Prometheus metrics enabled (Free or Pro tier). +* A Grafana API token with the `metrics:write` and `metrics:read` scopes if you plan to push data manually. + + + What you can do with the Metrics API} id="how-do-i-check-when-a-user-went-through-mfa" className="border-0 px-2 py-4"> + Every Supabase project exposes a metrics feed at `https://.supabase.co/customer/v1/privileged/metrics`. Replace `` with the identifier from your project URL or from the dashboard sidebar. + + 1. Copy your project reference and confirm the base URL using the helper below. + + + + 2. Configure your collector to scrape once per minute. The endpoint already emits the full set of metrics on each request. + 3. Authenticate with HTTP Basic Auth: + + * **Username**: `service_role` + * **Password**: a service role secret (JWT) from [**Project Settings > JWT**](/dashboard/project/_/settings/jwt) or any other Secret API key from [**Project Settings > API keys** (opens in a new tab)](/dashboard/project/_/settings/api-keys) + + Testing locally is as simple as running `curl` with your service role secret: + + ```bash + curl /customer/v1/privileged/metrics \ + --user 'service_role:sb_secret_...' + ``` + + You can provision long-lived automation tokens in two ways: + + * Create an account access token once at [**Account Settings > Access Tokens**](/dashboard/account/tokens) and reuse it wherever you configure observability tooling. + * **Optional**: programmatically exchange an access token for project API keys via the [Management API ](/docs/reference/api/management-projects-api-keys-retrieve'). + + ```bash + # (Optional) Exchange an account access token for project API keys + export SUPABASE_ACCESS_TOKEN="your-access-token" + export PROJECT_REF="your-project-ref" + + curl -H "Authorization: Bearer $SUPABASE_ACCESS_TOKEN" \ + "https://api.supabase.com/v1/projects/$PROJECT_REF/api-keys?reveal=true" + ``` + + + + +## 1. Create a Grafana Cloud stack + +1. Sign in to [Grafana Cloud](https://grafana.com/auth/sign-in). +2. Create (or select) a stack that has **Prometheus Metrics** enabled (Free and Pro tiers both work for this guide). + + +## 2. Configure the Supabase integration + +1. Navigate to **Connections → Add new connection → Supabase** inside Grafana Cloud. +2. Provide: + * Your Supabase project ref (e.g. `abcd1234`). + * The Metrics API endpoint: `https://.supabase.co/customer/v1/privileged/metrics`. + * HTTP Basic Auth credentials (`service_role` / `service_role key`). +3. Choose the scrape interval (1 minute recommended) and test the connection. Grafana Cloud will deploy an agent in the background that scrapes the Metrics API and forwards the data to Prometheus. + +If you prefer to reuse an existing Grafana Agent deployment, configure an [integration pipeline](https://grafana.com/docs/grafana-cloud/send-data/agent/integrations/integration-reference/integration-supabase/) with the same URL and credentials. + + +## 3. Import the Supabase dashboard + +1. Open your Grafana Cloud dashboard list and click **New → Import**. +2. Paste the raw contents of [`supabase-grafana/dashboard.json`](https://raw.githubusercontent.com/supabase/supabase-grafana/refs/heads/main/grafana/dashboard.json). +3. When prompted for the datasource, choose the Prometheus instance that receives the Supabase metrics. + +This dashboard includes 200+ charts grouped by CPU, IO, connections, replication, WAL, and bloat indicators. + +Supabase Grafana dashboard showcasing database metrics + + +## 4. Configure alerts (optional) + +The [`docs/example-alerts.md`](https://github.com/supabase/supabase-grafana/blob/main/docs/example-alerts.md) file contains suggested alert rules (disk saturation, long-running queries, replication lag, etc.). Import the alert rules into Grafana Cloud’s Alerting UI or translate them into Grafana Cloud’s managed alert rule format. + + +## 5. Troubleshooting + +* Metrics missing? Ensure the Grafana Cloud agent can reach `https://.supabase.co` and that the selected service role key is still valid. +* 401 errors? Rotate the service role key from the [API settings page](/dashboard/project/_/settings/api-keys) and update the Grafana Cloud credentials. +* Long scrape durations? Reduce label cardinality in your Grafana queries or lower the time range to focus on recent data. + + +# Metrics API with Prometheus & Grafana (self-hosted) + + + +Self-hosting [Prometheus](https://prometheus.io/docs/prometheus/latest/installation/) and Grafana gives you full control over retention, alert routing, and dashboards. The Supabase Metrics API slots into any standard Prometheus scrape job, so you can run everything locally, on a VM, or inside Kubernetes. + + + What you can do with the Metrics API} id="how-do-i-check-when-a-user-went-through-mfa" className="border-0 px-2 py-4"> + Every Supabase project exposes a metrics feed at `https://.supabase.co/customer/v1/privileged/metrics`. Replace `` with the identifier from your project URL or from the dashboard sidebar. + + 1. Copy your project reference and confirm the base URL using the helper below. + + + + 2. Configure your collector to scrape once per minute. The endpoint already emits the full set of metrics on each request. + 3. Authenticate with HTTP Basic Auth: + + * **Username**: `service_role` + * **Password**: a service role secret (JWT) from [**Project Settings > JWT**](/dashboard/project/_/settings/jwt) or any other Secret API key from [**Project Settings > API keys** (opens in a new tab)](/dashboard/project/_/settings/api-keys) + + Testing locally is as simple as running `curl` with your service role secret: + + ```bash + curl /customer/v1/privileged/metrics \ + --user 'service_role:sb_secret_...' + ``` + + You can provision long-lived automation tokens in two ways: + + * Create an account access token once at [**Account Settings > Access Tokens**](/dashboard/account/tokens) and reuse it wherever you configure observability tooling. + * **Optional**: programmatically exchange an access token for project API keys via the [Management API ](/docs/reference/api/management-projects-api-keys-retrieve'). + + ```bash + # (Optional) Exchange an account access token for project API keys + export SUPABASE_ACCESS_TOKEN="your-access-token" + export PROJECT_REF="your-project-ref" + + curl -H "Authorization: Bearer $SUPABASE_ACCESS_TOKEN" \ + "https://api.supabase.com/v1/projects/$PROJECT_REF/api-keys?reveal=true" + ``` + + + + + Grafana also documents a [Supabase integration reference](https://grafana.com/docs/grafana-cloud/monitor-infrastructure/integrations/integration-reference/integration-supabase/). While it targets Grafana Cloud, the scrape and agent settings apply equally to self-hosted clusters and offer a community-maintained companion to this guide. + + + +## Architecture + +1. **Prometheus** scrapes `https://.supabase.co/customer/v1/privileged/metrics` every minute using HTTP Basic Auth. +2. **Grafana** reads from Prometheus and renders dashboards/alerts. +3. (Optional) **Alertmanager** or your preferred system sends notifications when Prometheus rules fire. + + +## 1. Deploy Prometheus + +Install [Prometheus](https://prometheus.io/docs/prometheus/latest/installation/) using your preferred method (Docker, Helm, binaries). Then add a Supabase-specific job to `prometheus.yml`: + +```yaml +scrape_configs: + - job_name: 'supabase' + scrape_interval: 60s + metrics_path: /customer/v1/privileged/metrics + scheme: https + basic_auth: + username: service_role + password: '' + static_configs: + - targets: + - '.supabase.co:443' + labels: + project: '' +``` + + + * Keep the scrape interval at 60 seconds to match Supabase’s refresh cadence. + * If you run Prometheus behind a proxy, make sure it can establish outbound HTTPS connections to `*.supabase.co`. + * Store secrets (service role key) with your secret manager or inject them via environment variables. + + + +## 2. Deploy Grafana + +Install Grafana (Docker image, Helm chart, or packages) and connect it to Prometheus: + +1. In Grafana, go to **Connections → Data sources → Add data source**. +2. Choose **Prometheus**, set the URL to your Prometheus endpoint (for example `http://prometheus:9090`), and click **Save & test**. + + +## 3. Import Supabase dashboards + +1. Go to **Dashboards → New → Import**. +2. Paste the contents of [`supabase-grafana/dashboard.json`](https://raw.githubusercontent.com/supabase/supabase-grafana/refs/heads/main/grafana/dashboard.json). +3. Select your Prometheus datasource when prompted. + +You now have over 200 production-ready panels covering CPU, IO, WAL, replication, index bloat, and query throughput. + +Supabase Grafana dashboard showcasing database metrics + + +## 4. Configure alerting + +* Import the sample rules from [`docs/example-alerts.md`](https://github.com/supabase/supabase-grafana/blob/main/docs/example-alerts.md) into Prometheus or Grafana Alerting. +* Tailor thresholds (for example, disk utilization, long-running transactions, connection saturation) to your project’s size. +* Route notifications via Alertmanager, Grafana OnCall, PagerDuty, or any other supported destination. + + +## 5. Operating tips + +* **Multiple projects:** add one scrape job per project ref so you can separate metrics and labels cleanly. +* **Right-sizing guidance:** pair the dashboards with Supabase’s [Query Performance report](/dashboard/project/_/observability/query-performance) and [Advisors](/dashboard/project/_/observability/database) to decide when to optimize vs upgrade. +* **Security:** rotate the service role key on a regular cadence and update the Prometheus config accordingly. + + +# Vendor-agnostic Metrics API setup + + + +The Supabase Metrics API is intentionally vendor-agnostic. Any collector that can scrape a Prometheus text endpoint over HTTPS can ingest the data. This guide explains the moving pieces so you can adapt them to AWS Managed Prometheus, Grafana Mimir, VictoriaMetrics, Thanos, or any other system. + + + What you can do with the Metrics API} id="how-do-i-check-when-a-user-went-through-mfa" className="border-0 px-2 py-4"> + Every Supabase project exposes a metrics feed at `https://.supabase.co/customer/v1/privileged/metrics`. Replace `` with the identifier from your project URL or from the dashboard sidebar. + + 1. Copy your project reference and confirm the base URL using the helper below. + + + + 2. Configure your collector to scrape once per minute. The endpoint already emits the full set of metrics on each request. + 3. Authenticate with HTTP Basic Auth: + + * **Username**: `service_role` + * **Password**: a service role secret (JWT) from [**Project Settings > JWT**](/dashboard/project/_/settings/jwt) or any other Secret API key from [**Project Settings > API keys** (opens in a new tab)](/dashboard/project/_/settings/api-keys) + + Testing locally is as simple as running `curl` with your service role secret: + + ```bash + curl /customer/v1/privileged/metrics \ + --user 'service_role:sb_secret_...' + ``` + + You can provision long-lived automation tokens in two ways: + + * Create an account access token once at [**Account Settings > Access Tokens**](/dashboard/account/tokens) and reuse it wherever you configure observability tooling. + * **Optional**: programmatically exchange an access token for project API keys via the [Management API ](/docs/reference/api/management-projects-api-keys-retrieve'). + + ```bash + # (Optional) Exchange an account access token for project API keys + export SUPABASE_ACCESS_TOKEN="your-access-token" + export PROJECT_REF="your-project-ref" + + curl -H "Authorization: Bearer $SUPABASE_ACCESS_TOKEN" \ + "https://api.supabase.com/v1/projects/$PROJECT_REF/api-keys?reveal=true" + ``` + + + + +## Components + +* **Collector** – Prometheus, Grafana Agent, VictoriaMetrics agent, Mimir scraper, etc. +* **Long-term store (optional)** – Managed Prometheus, Thanos, Mimir, VictoriaMetrics. +* **Visualization/alerting** – Grafana, Datadog, New Relic, custom code. + + +## 1. Define the scrape job + +No matter which collector you use, you need to hit the Metrics API once per minute with HTTP Basic Auth: + +```yaml +- job_name: supabase + scrape_interval: 60s + metrics_path: /customer/v1/privileged/metrics + scheme: https + basic_auth: + username: service_role + password: '' + static_configs: + - targets: + - '.supabase.co:443' + labels: + project: '' +``` + + +### Collector-specific notes + +* **Grafana Agent / Alloy:** use the [`prometheus.scrape` component](https://grafana.com/docs/grafana-cloud/monitor-infrastructure/integrations/integration-reference/integration-supabase/#manual-configuration) with the same parameters. +* **AWS Managed Prometheus (AMP):** deploy the Grafana Agent or AWS Distro for OpenTelemetry (ADOT) in your VPC, then remote-write the scraped metrics into AMP. +* **VictoriaMetrics / Mimir:** reuse the same scrape block; configure remote-write or retention rules as needed. + + +## 2. Secure the credentials + +* Store the service role key in your secret manager (AWS Secrets Manager, GCP Secret Manager, Vault, etc.). +* Rotate the key periodically via [Project Settings → API keys](/dashboard/project/_/settings/api-keys) and update your collector. +* If you need to give observability vendors access without exposing the service role key broadly, create a dedicated service key for metrics-only automation. + + +## 3. Downstream dashboards + +* Import the [Supabase Grafana dashboard](https://github.com/supabase/supabase-grafana) regardless of where Grafana is hosted. +* For other tools, group metrics by categories (CPU, IO, WAL, replication, connections) and recreate the visualizations that matter most to your team. +* Tag or relabel series with `project`, `env`, or `team` labels to make multi-project views easier. + +Supabase Grafana dashboard showcasing database metrics + + +## 4. Alerts and automation + +* Start with the [example alert rules](https://github.com/supabase/supabase-grafana/blob/main/docs/example-alerts.md) and adapt thresholds for your workload sizes. +* Pipe alerts into PagerDuty, Slack, Opsgenie, or any other compatible target. +* Combine Metrics API data with log drains, Query Performance, and Advisors to build right-sizing playbooks. + + +## 5. Multi-project setups + +* Create one scrape job per project ref so you can control sampling individually. +* If you run many projects, consider templating the scrape jobs via Helm, Terraform, or the Grafana Agent Operator. +* Use label joins (`project`, `instance_class`, `org`) to aggregate across tenants or environments. + + +# Pricing + + + +You are charged for the total size of all assets in your buckets. + + per GB-Hr ( per GB per month). You are only +charged for usage exceeding your subscription plan's quota. + +| Plan | Quota in GB | Over-Usage per GB | Quota in GB-Hrs | Over-Usage per GB-Hr | +| ---------- | ----------- | ----------------------- | --------------- | ---------------------------- | +| Free | 1 | - | 744 | - | +| Pro | 100 | | 74,400 | | +| Team | 100 | | 74,400 | | +| Enterprise | Custom | Custom | Custom | Custom | + +For a detailed explanation of how charges are calculated, refer to [Manage Storage size usage](/docs/guides/platform/manage-your-usage/storage-size). + + + If you use [Storage Image Transformations](/docs/guides/storage/serving/image-transformations), additional charges apply. + + + +# Storage Quickstart + +Learn how to use Supabase to store and serve files. + +This guide shows the basic functionality of Supabase Storage. Find a full [example application on GitHub](https://github.com/supabase/supabase/tree/master/examples/user-management/nextjs-user-management). + + +## Concepts + +Supabase Storage consists of Files, Folders, and Buckets. + + +### Files + +Files can be any sort of media file. This includes images, GIFs, and videos. It is best practice to store files outside of your database because of their sizes. For security, HTML files are returned as plain text. + + +### Folders + +Folders are a way to organize your files (just like on your computer). There is no right or wrong way to organize your files. You can store them in whichever folder structure suits your project. + + +### Buckets + +Buckets are distinct containers for files and folders. You can think of them like "super folders". Generally you would create distinct buckets for different Security and Access Rules. For example, you might keep all video files in a "video" bucket, and profile pictures in an "avatar" bucket. + + + File, Folder, and Bucket names **must follow** [AWS object key naming guidelines](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html) and avoid use of any other characters. + + + +## Create a bucket + +You can create a bucket using the Supabase Dashboard. Since the storage is interoperable with your Postgres database, you can also use SQL or our client libraries. Here we create a bucket called "avatars": + + + + 1. Go to the [Storage](/dashboard/project/_/storage/buckets) page in the Dashboard. + 2. Click **New Bucket** and enter a name for the bucket. + 3. Click **Create Bucket**. + + + + ```sql + -- Use Postgres to create a bucket. + + insert into storage.buckets + (id, name) + values + ('avatars', 'avatars'); + ``` + + + + ```js + // Use the JS library to create a bucket. + + const { data, error } = await supabase.storage.createBucket('avatars') + ``` + + [Reference.](/docs/reference/javascript/storage-createbucket) + + + + ```dart + void main() async { + final supabase = SupabaseClient('supabaseUrl', 'supabaseKey'); + + final storageResponse = await supabase + .storage + .createBucket('avatars'); + } + ``` + + [Reference.](https://pub.dev/documentation/storage_client/latest/storage_client/SupabaseStorageClient/createBucket.html) + + + + ```swift + try await supabase.storage.createBucket("avatars") + ``` + + [Reference.](/docs/reference/swift/storage-createbucket) + + + + ```python + response = supabase.storage.create_bucket('avatars') + ``` + + [Reference.](/docs/reference/python/storage-createbucket) + + + + +## Upload a file + +You can upload a file from the Dashboard, or within a browser using our JS libraries. + + + + 1. Go to the [Storage](/dashboard/project/_/storage/buckets) page in the Dashboard. + 2. Select the bucket you want to upload the file to. + 3. Click **Upload File**. + 4. Select the file you want to upload. + + + + ```js + const avatarFile = event.target.files[0] + const { data, error } = await supabase.storage + .from('avatars') + .upload('public/avatar1.png', avatarFile) + ``` + + [Reference.](/docs/reference/javascript/storage-from-upload) + + + + ```dart + void main() async { + final supabase = SupabaseClient('supabaseUrl', 'supabaseKey'); + + // Create file `example.txt` and upload it in `public` bucket + final file = File('example.txt'); + file.writeAsStringSync('File content'); + final storageResponse = await supabase + .storage + .from('public') + .upload('example.txt', file); + } + ``` + + [Reference.](https://pub.dev/documentation/storage_client/latest/storage_client/SupabaseStorageClient/createBucket.html) + + + + +## Download a file + +You can download a file from the Dashboard, or within a browser using our JS libraries. + + + + 1. Go to the [Storage](/dashboard/project/_/storage/buckets) page in the Dashboard. + 2. Select the bucket that contains the file. + 3. Select the file that you want to download. + 4. Click **Download**. + + + + ```js + // Use the JS library to download a file. + + const { data, error } = await supabase.storage.from('avatars').download('public/avatar1.png') + ``` + + [Reference.](/docs/reference/javascript/storage-from-download) + + + + ```dart + void main() async { + final supabase = SupabaseClient('supabaseUrl', 'supabaseKey'); + + final storageResponse = await supabase + .storage + .from('public') + .download('example.txt'); + } + ``` + + [Reference.](/docs/reference/dart/storage-from-download) + + + + ```swift + let response = try await supabase.storage.from("avatars").download(path: "public/avatar1.png") + ``` + + [Reference.](/docs/reference/swift/storage-from-download) + + + + ```python + response = supabase.storage.from_('avatars').download('public/avatar1.png') + ``` + + [Reference.](/docs/reference/python/storage-from-download) + + + + +## Add security rules + +To restrict access to your files you can use either the Dashboard or SQL. + + + + 1. Go to the [Storage](/dashboard/project/_/storage/buckets) page in the Dashboard. + 2. Click **Policies** in the sidebar. + 3. Click **Add Policies** in the `OBJECTS` table to add policies for Files. You can also create policies for Buckets. + 4. Choose whether you want the policy to apply to downloads (SELECT), uploads (INSERT), updates (UPDATE), or deletes (DELETE). + 5. Give your policy a unique name. + 6. Write the policy using SQL. + + + + ```sql + -- Use SQL to create a policy. + + create policy "Public Access" + on storage.objects for select + using ( bucket_id = 'public' ); + ``` + + + +*** + +{/* Finish with a video. This also appears in the Sidebar via the "tocVideo" metadata */} + +
+