- Add graceful shutdown for HTTP server
- Add server-reuseport configuration to allow starting multiple PostgREST instances using the same port on supported platforms
- Add support for JSON Path RFC 9535 in JWT Role Extraction
- Add numeric offsets like 05:00 or -4 to Prefer: timezone
- Add Vary header to responses
- Add GHC runtime metrics for observability
- Add client-error-verbosity configuration to customize response error verbosity
- Add admin-server-unix-socket and admin-server-unix-socket-mode to run the admin server on a unix socket
- Publish Docker images to Github Container Registry in addition to Docker Hub
- Optimize schema cache domain type resolution by using pg_basetype on PostgreSQL 17+
- Prefer: count=exact no longer does a double count on requests that do not use ranges or db-max-rows
- Prefer: timezone no longer requires the schema cache
- Make aarch64-linux executable static instead of Ubuntu-based
- Build aarch64-linux Docker image from scratch instead of Ubuntu-based
- log-level configuration is now reloadable
- Fix unexpected results when embedding and filtering the same table more than once
- Fix automatic transaction retries on serialization_failure errors to prevent replication lag
- Fix responding with Something went wrong on Admin server when under EMFILE
- Fix requests failing when the schema cache fails to reload by continuing to serve requests in best effort mode
- Fix reporting 503 errors unnecessarily while the schema cache is loading at startup
- Fix schema cache dump missing RPC transaction isolation level
- Fix config db-channel-enabled not reloading
- Drop support for PostgreSQL 13
- Deprecate filters, orders and limits with the name of an embedded table when it has an alias
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.
-
Add
Varyheader to responses by @develop7 in #4609 -
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