Performance Tuning

The Supabase platform automatically optimizes your Postgres database to take advantage of the compute resources of the tier your project is on. However, these optimizations are based on assumptions about the type of workflow the project is being utilized for, and it is likely that better results can be obtained by tuning the database for your particular workflow.

Optimizing the number of connections#

By default, the number of connections allowed to Postgres and PgBouncer is configured based on the resources available to the database.

Compute Add-onPostgresql connectionsPGBouncer connections

If the number of connections is insufficient, you will receive the following error upon connecting to the DB:

1$ psql -U postgres -h ...
2FATAL: remaining connection slots are reserved for non-replication superuser connections

In such a scenario, you can consider:

Configuring clients to use fewer connections#

You can use the pg_stat_activity view to debug which clients are holding open connections on your DB. pg_stat_activity only exposes information on direct connections to the database. Information on the number of connections to pgbouncer is available via the metrics endpoint.

Depending on the clients involved, you might be able to configure them to work with fewer connections (e.g. by imposing a limit on the maximum number of connections they're allowed to use), or shift specific workloads to connect via pgbouncer instead. Transient workflows, which can quickly scale up and down in response to traffic (e.g. serverless functions), can especially benefit from using a connection pooler rather than connecting to the DB directly.

Allowing higher number of connections#

You can configure Postgres by executing the following statement, followed by a server restart:

1alter system set max_connections = '<val-here>';

Note that the default configuration used by the Supabase platform optimizes the database to maximize resource utilization, and as a result, you might also need to configure other options (e.g. work_mem, shared_buffers, maintenance_work_mem) in order to tune them towards your use-case, and to avoid causing instability in your database.

Once overridden, the Supabase platform will continue to respect your manually configured value (even if the add-on size is changed), unless the override is removed with the following statement, followed by a server restart:

1alter system reset max_connections;
2alter system reset <other-overridden-conf>;

Configuring the number of PgBouncer connections is not supported at this time.

Examining Query Performance#

Every Supabase project has the pg_stat_statements extension enabled by default. This extension records query execution performance details and is the best way to find queries that take the most time to execute. This information can be combined with the Postgres query plan analyzer to develop more efficient queries.

Obtaining information from pg_stat_statements:

1select mean_exec_time + stddev_exec_time, * from pg_stat_statements order by 1 desc;

Using the query plan analyzer on your expensive queries:

1explain analyze <query-statement-here>;

Be careful using explain analyze with insert/update/delete queries, because the query will actually run, and could have unintended side-effects.

Using the query plan analyzer to optimize your queries is a large topic, with a number of online resources available:

You can pair the information available from pg_stat_statements with the detailed system metrics available via your metrics endpoint to better understand the behavior of your DB and the queries you're executing against it.