PostgREST reads a configuration file to determine information about the database and how to serve client requests. There is no predefined location for this file, you must specify the file path as the one and only argument to the server:

./postgrest /path/to/postgrest.conf


Configuration can be reloaded without restarting the server. See Configuration Reloading.

The configuration file must contain a set of key value pairs. At minimum you must include these keys:

# postgrest.conf

# The standard connection URI format, documented at
db-uri       = "postgres://user:pass@host:5432/dbname"

# The name of which database schema to expose to REST clients
db-schema    = "api"

# The database role to use when no client authentication is provided.
# Can (and should) differ from user in db-uri
db-anon-role = "anon"

The user specified in the db-uri is also known as the authenticator role. For more information about the anonymous vs authenticator roles see the Overview of Role System.

Here is the full list of configuration parameters.

Name Type Default Required
db-uri String   Y
db-schema String   Y
db-anon-role String   Y
db-pool Int 10  
db-pool-timeout Int 10  
db-extra-search-path String public  
db-channel String pgrst  
db-channel-enabled Boolean True  
db-prepared-statements Boolean True  
db-tx-end String commit  
db-config Boolean True  
db-embed-default-join String left  
db-use-legacy-gucs Boolean True  
server-host String !4  
server-port Int 3000  
server-unix-socket String    
server-unix-socket-mode String 660  
log-level String error  
openapi-mode String follow-privileges  
openapi-server-proxy-uri String    
jwt-secret String    
jwt-aud String    
secret-is-base64 Boolean False  
max-rows Int  
pre-request String    
app.settings.* String    
role-claim-key String .role  
raw-media-types String    


The standard connection PostgreSQL URI format. Symbols and unusual characters in the password or other fields should be percent encoded to avoid a parse error. If enforcing an SSL connection to the database is required you can use sslmode in the URI, for example postgres://user:pass@host:5432/dbname?sslmode=require.

When running PostgREST on the same machine as PostgreSQL, it is also possible to connect to the database using a Unix socket and the Peer Authentication method as an alternative to TCP/IP communication and authentication with a password, this also grants higher performance. To do this you can omit the host and the password, e.g. postgres://user@/dbname, see the libpq connection string documentation for more details.

On older systems like Centos 6, with older versions of libpq, a different db-uri syntax has to be used. In this case the URI is a string of space separated key-value pairs (key=value), so the example above would be "host=host user=user port=5432 dbname=dbname password=pass".

Choosing a value for this parameter beginning with the at sign such as @filename (e.g. @./configs/my-config) loads the secret out of an external file.


The database schema to expose to REST clients. Tables, views and stored procedures in this schema will get API endpoints.

db-schema = "api"

This schema gets added to the search_path of every request.

List of schemas

You can also specify a list of schemas that can be used for schema-based multitenancy and api versioning by Switching Schemas. Example:

db-schema = "tenant1, tenant2"

If you don’t Switch Schemas, the first schema in the list(tenant1 in this case) is chosen as the default schema.

Only the chosen schema gets added to the search_path of every request.


Never expose private schemas in this way. See Schema Isolation.


The database role to use when executing commands on behalf of unauthenticated clients. For more information, see Overview of Role System.


Number of connections to keep open in PostgREST’s database pool. Having enough here for the maximum expected simultaneous client connections can improve performance. Note it’s pointless to set this higher than the max_connections GUC in your database.


Time to live, in seconds, for an idle database pool connection. If the timeout is reached the connection will be closed. Once a new request arrives a new connection will be started.


Extra schemas to add to the search_path of every request. These schemas tables, views and stored procedures don’t get API endpoints, they can only be referred from the database objects inside your db-schema.

This parameter was meant to make it easier to use PostgreSQL extensions (like PostGIS) that are outside of the db-schema.

Multiple schemas can be added in a comma-separated string, e.g. public, extensions.


The name of the notification channel that PostgREST uses for Schema Cache Reloading and configuration reloading.


When this is set to true, the notification channel specified in db-channel is enabled.

You should set this to false when using PostgresSQL behind an external connection pooler such as PgBouncer working in transaction pooling mode. See this section for more information.


Enables or disables prepared statements.

When disabled, the generated queries will be parameterized (invulnerable to SQL injection) but they will not be prepared (cached in the database session). Not using prepared statements will noticeably decrease performance, so it’s recommended to always have this setting enabled.

You should only set this to false when using PostgresSQL behind an external connection pooler such as PgBouncer working in transaction pooling mode. See this section for more information.


Specifies how to terminate the database transactions.

# The transaction is always committed
db-tx-end = "commit"

# The transaction is committed unless a "Prefer: tx=rollback" header is sent
db-tx-end = "commit-allow-override"

# The transaction is always rolled back
db-tx-end = "rollback"

# The transaction is rolled back unless a "Prefer: tx=commit" header is sent
db-tx-end = "rollback-allow-override"


Enables the in-database configuration.


Determines the default embedding type between tables or views when none is specified in the request. For more info, see Top Level Filtering.

# Embeds using LEFT JOIN
db-embed-default-join = "left"

# Embeds using INNER JOIN
db-embed-default-join = "inner"


Determine if GUC request settings for headers, cookies and jwt claims use the legacy names (string with dashes, invalid starting from PostgreSQL v14) with text values instead of the new names (string without dashes, valid on all PostgreSQL versions) with json values.

On PostgreSQL versions 14 and above, this parameter is ignored.


Where to bind the PostgREST web server. In addition to the usual address options, PostgREST interprets these reserved addresses with special meanings:

  • * - any IPv4 or IPv6 hostname
  • *4 - any IPv4 or IPv6 hostname, IPv4 preferred
  • !4 - any IPv4 hostname
  • *6 - any IPv4 or IPv6 hostname, IPv6 preferred
  • !6 - any IPv6 hostname


The TCP port to bind the web server.


Unix domain socket where to bind the PostgREST web server. If specified, this takes precedence over server-port. Example:

server-unix-socket = "/tmp/pgrst.sock"


Unix file mode to be set for the socket specified in server-unix-socket Needs to be a valid octal between 600 and 777.

server-unix-socket-mode = "660"


Specifies the level of information to be logged while running PostgREST.

# Only startup and db connection recovery messages are logged
log-level = "crit"

# All the "crit" level events plus server errors (status 5xx) are logged
log-level = "error"

# All the "error" level events plus request errors (status 4xx) are logged
log-level = "warn"

# All the "warn" level events plus all requests (every status code) are logged
log-level  "info"

Because currently there’s no buffering for logging, the levels with minimal logging(crit/error) will increase throughput.


Specifies how the OpenAPI output should be displayed.

# Follows the privileges of the JWT role claim (or from db-anon-role if the JWT is not sent)
# Shows information depending on the permissions that the role making the request has
openapi-mode = "follow-privileges"

# Ignores the privileges of the JWT role claim (or from db-anon-role if the JWT is not sent)
# Shows all the exposed information, regardless of the permissions that the role making the request has
openapi-mode = "ignore-privileges"

# Disables the OpenApi output altogether.
# Throws a `404 Not Found` error when accessing the API root path
openapi-mode = "disabled"


Overrides the base URL used within the OpenAPI self-documentation hosted at the API root path. Use a complete URI syntax scheme:[//[user:password@]host[:port]][/]path[?query][#fragment]. Ex.

  "swagger": "2.0",
  "info": {
    "version": "",
    "title": "PostgREST API",
    "description": "This is a dynamic API generated by PostgREST"
  "host": "",
  "basePath": "/",
  "schemes": [


The secret or JSON Web Key (JWK) (or set) used to decode JWT tokens clients provide for authentication. For security the key must be at least 32 characters long. If this parameter is not specified then PostgREST refuses authentication requests. Choosing a value for this parameter beginning with the at sign such as @filename loads the secret out of an external file. This is useful for automating deployments. Note that any binary secrets must be base64 encoded. Both symmetric and asymmetric cryptography are supported. For more info see Asymmetric Keys.


Specifies the JWT audience claim. If this claim is present in the client provided JWT then you must set this to the same value as in the JWT, otherwise verifying the JWT will fail.


When this is set to true, the value derived from jwt-secret will be treated as a base64 encoded secret.


A hard limit to the number of rows PostgREST will fetch from a view, table, or stored procedure. Limits payload size for accidental or malicious requests.


A schema-qualified stored procedure name to call right after switching roles for a client request. This provides an opportunity to modify SQL variables or raise an exception to prevent the request from completing.


Arbitrary settings that can be used to pass in secret keys directly as strings, or via OS environment variables. For instance: app.settings.jwt_secret = "$(MYAPP_JWT_SECRET)" will take MYAPP_JWT_SECRET from the environment and make it available to postgresql functions as current_setting('app.settings.jwt_secret').


A JSPath DSL that specifies the location of the role key in the JWT claims. This can be used to consume a JWT provided by a third party service like Auth0, Okta or Keycloak. Usage examples:

# {"postgrest":{"roles": ["other", "author"]}}
# the DSL accepts characters that are alphanumerical or one of "_$@" as keys
role-claim-key = ".postgrest.roles[1]"

# {"": { "key": "author }}
# non-alphanumerical characters can go inside quotes(escaped in the config value)
role-claim-key = ".\"\".key"


This serves to extend the Media Types that PostgREST currently accepts through an Accept header.

These media types can be requested by following the same rules as the ones defined in Binary Output.

As an example, the below config would allow you to request an image and a XML file by doing a request with Accept: image/png or Accept: text/xml, respectively.

raw-media-types="image/png, text/xml"

Environment Variables

You can also set these configuration parameters using environment variables. They are capitalized, have a PGRST_ prefix, and use underscores. For example: PGRST_DB_URI corresponds to db-uri and PGRST_APP_SETTINGS_* to app.settings.*.

Configuration Reloading

To reload the configuration without restarting the PostgREST server, send a SIGUSR2 signal to the server process.

killall -SIGUSR2 postgrest

This method does not reload Environment Variables and it will not work for reloading a Docker container configuration. In these cases, you need to restart the PostgREST server or use the In-Database Configuration as an alternative.


The following settings will not be reread when reloading the configuration. You will need to restart PostgREST in that case.

In-Database Configuration

By adding settings to the authenticator role (see Overview of Role System), you can make the database the single source of truth for PostgREST’s configuration. This is enabled by db-config.

For example, you can configure db-schema and jwt-secret like this:

ALTER ROLE authenticator SET pgrst.db_schema = "tenant1, tenant2, tenant3"

Note that underscores(_) need to be used instead of dashes(-) for the in-database config options.


For altering a role in this way, you need a SUPERUSER. You might not be able to use this configuration mode on cloud-hosted databases.

When using both the configuration file and the in-database configuration, the latter takes precedence.


If direct connections to the database are allowed, then it’s not safe to use the in-db configuration for storing the jwt-secret. The settings of every role are PUBLIC - they can be viewed by any user that queries the pg_catalog.pg_db_role_setting table. In this case you should keep the jwt-secret in the configuration file or as environment variables.

In-database configuration reloading

To reload the in-database configuration from within the database, you can use a NOTIFY command.

NOTIFY pgrst, 'reload config'

The "pgrst" notification channel is enabled by default. For configuring the channel, see db-channel and db-channel-enabled.