Changes
HTTP Server
-
Graceful shutdown by @mkleczek, @Vlix in #4702
-
server-reuseport allows starting multiple PostgREST instances using the same port on supported platforms by @mkleczek in #4703, #4694
Performance
-
Optimize schema cache domain type resolution by using pg_basetype on PostgreSQL 17+ by @joelonsql in #4567
-
Prefer: count=exact no longer does a double count on requests that do not use ranges or
db-max-rowsby @laurenceisla in #3957 -
Prefer: timezone no longer requires the schema cache by @steve-chavez in #5100
- Previously this required caching pg_timezone_names which was slow in some systems
Integrations
- PostgREST is now tested to work with OrioleDB in #4845 by @wolfgangwalther
JWT
- JWT Role Extraction is now more flexible, supporting the standard JSON Path defined in RFC 9535 by @taimoorzaeem in #4984
API
-
Prefer: timezone now supports numeric offsets like
05:00or-4by @steve-chavez in #5100 -
Fix unexpected results when embedding and filtering the same table more than once by @laurenceisla in #4075
- You need to set url-use-legacy-target-names to
false.
- You need to set url-use-legacy-target-names to
-
Deprecate filters, orders and limits with the name of an embedded table when it has an alias by @steve-chavez, @laurenceisla in #4075
- e.g.
?select=alias:table(*)&table.id=eq.1will not be possible anymore, use?select=alias:table(*)&alias.id=eq.1instead. - You will see a warning in the logs and a
Warningheader on the client response when this happens. - You can disable this behavior now by setting
url-use-legacy-target-names = false.
- e.g.
-
Fix automatic transaction retries on
40001 (serialization_failure)errors to prevent replication lag by @laurenceisla in #3673
Observability
- GHC runtime metrics by @mkleczek in #4862
- client-error-verbosity to customize responses error verbosity by @taimoorzaeem in #4088, #3980, #3824
- log-level config is now reloadable by @taimoorzaeem in #5113
- Log error when
db-schemasconfig contains schemapg_catalogorinformation_schemaby @taimoorzaeem in #4359 - Log schema cache queries timings on
log-level=debugby @steve-chavez in #4805
Admin Server
- admin-server-unix-socket/admin-server-unix-socket-mode to run the admin server on a unix socket by @wolfgangwalther in #5003
- Fix responding with
Something went wrongon Admin server when under EMFILE by @mkleczek in #5077
Deployment
- Make executable for aarch64-linux static instead of Ubuntu-based by @wolfgangwalther in #4193
- Docker image for aarch64-linux is now built from scratch instead of being Ubuntu-based by @wolfgangwalther in #4193
- Besides Docker Hub, docker images are now published to Github Container Registry by @wolfgangwalther in #2836
Schema Cache
- Fix requests failing when the schema cache fails to reload, when this happens PostgREST will continue serving requests in "best effort" by @mkleczek in #4873 #4869
- Fix reporting 503s errors unnecessarily while the schema cache is loading at startup by @mkleczek in #4880
- Fix schema cache dump missing RPC transaction isolation level by @taimoorzaeem in #5079
Listener
- Fix config
db-channel-enablednot reloading by @taimoorzaeem in #4894
Migration to v16
-
Drop support for PostgreSQL EOL version 13 by @wolfgangwalther in #4193
- PostgreSQL 13 end of life was on 2025 (ref)
- Upgrade your PostgreSQL version to at least 14 to use this new PostgREST version.
-
Fail at startup when
db-schemascontains schemapg_catalogorinformation_schemaby @taimoorzaeem in #4359- Previously it failed at runtime with
PGRST205on requests related to these schemas. - Remove
pg_catalogandinformation_schemafromdb-schemas.
- Previously it failed at runtime with
-
Prefer: timezoneno longer complies withhandling=lenientand instead always fails by @steve-chavez in #5128- Supporting this required caching
pg_timezone_names, which was expensive. - Ensure your requests always have a valid timezone.
- Supporting this required caching
-
jwt-role-claim-keyno longer uses the JSPath DSL and instead uses JSON Path by @taimoorzaeem in #4984- Now all config values must start with
$character.
Example:.roles.read->$.roles.read - Keys with special characters, with the exception of
_char must be quoted.
Example:.roles.write-role->$.roles["write-role"] - String comparison operators (
^==,==^and*==) are replaced with regular expression search.
Example:.roles[?(@ ^== "postgrest_test_")]->$.roles[?search(@, "^postgrest_test_")] - Update the
jwt-role-claim-keyvalue accoring to the above rules. Also see the syntax reference: RFC 9535.
- Now all config values must start with