Commit Graph
399 Commits
Author SHA1 Message Date
steve-chavez ad790baefb test: explain verbose reveals query identifier
This also requires enabling shared_preload_libraries=pg_stat_statements.
Really we only need compute_query_id=on, but pg_stat_statements is
useful for other tests and it already enables compute_query_id (since
it's `auto` by default).
2026-06-06 06:47:33 -05:00
Wolfgang Walther cb6fc55a2d chore(deps): update nixpkgs, stackage and hackage pins 2026-06-05 20:29:48 +00:00
Wolfgang Walther b114bb9395 nix: replace silver-searcher with fd
The former has been removed from Nixpkgs and won't be available on the
next bump.
2026-06-05 20:29:48 +00:00
Wolfgang Walther 1d6e0bd35f nix(loadtest): report percentage change
This reports the percentage change between the current head branch and
the main branch, which is exactly the number we'll want to make our
decisions on "success or fail" on.

CI failures will initially be reported for regressions of 5% or more on
an individual number.
2026-06-01 20:49:35 +00:00
Wolfgang Walther ff92846e64 nix(loadtest): report multiple percentiles at once
We can look at the data over time and see which percentile works best
for our purpose.
2026-06-01 20:49:35 +00:00
Wolfgang Walther 640039a180 nix(loadtest): move errors into mixed
Because we separate loadtest results per URL now, we can move the error
tests into the regular mixed bag of loadtests - we will be able to tell
from the misspelled URLs when we hit a regression in that area.

We should be able to do similar things for JWT tests, but we'll need
more infrastructure here.
2026-06-01 20:49:35 +00:00
Wolfgang Walther 59dffc258a nix(loadtest): report latency instead of rate
We previously used "rate", i.e. number of requests per second, as the
primary metric to judge loadtest results. However, this has always been
varying from run to run quite a bit, especially in CI where other jobs
possibly run on the same VM host.

The run-to-run variance has massively increased after splitting the
results up per request. Example run in CI with rate on the PR
introducing this change (on which we would expect no change at all):

| rate [1/s]                         |   main |   head |    Δ |
|:-----------------------------------|-------:|-------:|-----:|
| /                                  |    9.4 |    9.5 |   1% |
| /actors                            |  870.4 | 1023.0 |  18% |
| /actors?actor=eq.1                 |  188.5 |  198.6 |   5% |
| /actors?actor=eq.1&columns=name    |  197.3 |  167.1 | -15% |
| /actors?select=*,roles(*,films(*)) |  153.9 |  144.9 |  -6% |
| /films?columns=id,title            |  157.9 |  182.6 |  16% |
| /films?columns=id,title,year,...   |   87.0 |   87.1 |   0% |
| /roles                             |  204.5 |  267.3 |  31% |
| /rpc/call_me                       |  231.3 |  208.8 | -10% |
| /rpc/call_me?name=John             |  212.2 |  201.7 |  -5% |

From the data we can easily tell that the very reason that rate as a
paramter has only worked, so far, because the data was *heavily*
dominated by the requests on the root endpoint for OpenAPI. The longer
duration makes the request much less vulnerable for concurrent activity.
For all other requests its essentially not possible to judge the effect
of a PR this way.

One way to counter this would be to massively increase the time the
loadtest runs. More samples will result in a smoother average. However,
that's not practical for usability of CI. In the original PR #1812 I
already evaluated using the *minimum latency* as the most reliable
criteriumi, but this has never really caught on. The theory behind this
is: The variation in timings between requests is happening because of
concurrent activity, priority chosen by the scheduler, availability of
resources and such - all factors *outside* our control, and *irrelevant*
to the Haskell code we're writing.

Using the minimum latency is an estimation of how fast the code can run
*in the best case*. This might not be a number relevant for production,
but it's much more directly related to the code we write.

Here's to show how variation becomes *much* smaller with minimum latency
as the parameter:

| min latency [μs]                   |     main |   head |    Δ |
|:-----------------------------------|---------:|-------:|-----:|
| /                                  |   1275.3 | 1263.6 |  -1% |
| /actors                            |     10.0 |    9.9 |  -1% |
| /actors?actor=eq.1                 |     50.7 |   48.3 |  -5% |
| /actors?actor=eq.1&columns=name    |     54.1 |   54.0 |   0% |
| /actors?select=*,roles(*,films(*)) |     63.2 |   61.9 |  -2% |
| /films?columns=id,title            |     51.1 |   50.7 |  -1% |
| /films?columns=id,title,year,...   |    121.9 |  121.8 |   0% |
| /roles                             |     42.9 |   42.6 |  -1% |
| /rpc/call_me                       |     45.6 |   45.4 |   0% |
| /rpc/call_me?name=John             |     44.4 |   44.2 |   0% |

Since we're separating results per request now, we can only sensibly
focus on *one* parameter - otherwise this would get really clunky
UI-wise. Especially for automated CI failures, minimum latency is the
logical choice.

This commit starts using minimum latency, i.e. P0, but any percentile
should be an improvement over the status quo. A later commit will change
to a different P-value.
2026-06-01 20:49:35 +00:00
Wolfgang Walther 8a9f98371e nix(loadtest): group results by status, method and URL
Different requests hit different code paths and perform very
differently. By looking at each request type separately, we should be
able to get a much better idea of what kind of change in performance
we're looking at and where the root cause might be.

It will hopefully also allow us to migrate some of the other test-cases
into the main loadtest.
2026-06-01 20:49:35 +00:00
Wolfgang Walther 5cdf2e0569 nix(loadtest): remove noise from report
Ultimately, we only look at the `rate` column, so we can just as well
remove all other columns.

This makes the next step, when we split results by request type, much
less noisy.
2026-06-01 20:49:35 +00:00
Taimoor ZaeemandSteve Chavez e1d547623e nix(docs): print message to console on script runs
It's not immediately visible that these scripts are run when
doing `postgrest-docs-check`.

Signed-off-by: Taimoor Zaeem <taimoorzaeem@gmail.com>
2026-05-27 15:23:59 -05:00
Wolfgang Walther 61da5dd88b nix(loadtest): prevent timing errors for worst-case JWT test
Instead of taking wild guesses at the runtime of the target generation
itself, we're just making sure to reset the system time to a fixed value
when we ultimately start PostgREST. This allows us to create the right
JWT expiry values ahead of time.
2026-05-18 16:23:37 +00:00
Wolfgang Walther d9f73ac71b nix(loadtest): remove duplicate line 2026-05-18 16:23:37 +00:00
Wolfgang Walther 4f9bc89ab2 nix(loadtest): remove outdated PGRST_DB_URI default
This was required for v9 and earlier, but these don't build with the
current nix invocation anymore anyway. Even loadtesting against v10 does
not work, because `--version` is used in one of the wait scripts and
this was only added in v11.2.

So no need to pretend we'd support comparing against older versions.
2026-05-18 15:18:05 +02:00
Wolfgang Walther c7260bddab test: consistently analyze tables exactly once
Disabling the autovacuum daemon should also help reproducibility in
theory, although I don't know of any cases where we hit a problem with
that.

VACUUM changes the order of rows that PostgreSQL returns for some table
without explicit ordering, thus doing the latter to make it consistently
reproducible.

After ANALYZE estimates are 100% exact for the moment, so some requests
which returned 206 Partial Response now return 200 instead. The fact
that PostgREST returns 206 on an unfiltered endpoint can probably be
considered a bug.
2026-05-17 20:03:15 +00:00
Wolfgang Walther abe3e511bf nix(postgrest-with-pg-...): use postgresql.conf instead of CLI arguments
This is easier to reason about and easier to extend. Also removes a tiny
bit of repetition.
2026-05-17 20:03:15 +00:00
steve-chavez 70327cf869 test: negative pgrst_db_pool_available in metrics
Proves the failure on https://github.com/PostgREST/postgrest/issues/4622.

This doesn't require additional test infra, only nginx. Taking advantage
of the `stream {}` context which is also compatible with unix socket
besides TCP.
2026-05-17 12:58:58 -05:00
Taimoor Zaeem 4c04572783 nix(chore): add commit prefix in release commit message
We should follow our commit convention.

Signed-off-by: Taimoor Zaeem <taimoorzaeem@gmail.com>
2026-05-06 23:26:06 +05:00
steve-chavez e39740cca3 nix: allow empty PGRST_DB_ANON_ROLE on postgrest-run
So we can do `PGRST_DB_ANON_ROLE="" postgrest-run` since empty string has
meaning. argbash conflates both unset and empty string so this requires
a workaround.
2026-05-05 17:32:50 -05:00
Laurence Isla 41b86fffa5 fix: no longer retries the transaction on 40001 errors 2026-04-27 14:30:10 -05:00
Taimoor ZaeemandWolfgang Walther bf758698b3 fix: login with uppercase and mixed case role names
PostgREST failed when querying role settings where current
role name contained uppercase letters. This commit resolves
it by quoting the CURRENT_USER.

Signed-off-by: Taimoor Zaeem <taimoorzaeem@gmail.com>
2026-04-27 09:19:26 +00:00
Wolfgang WaltherandMichal Kleczek a5cc457875 chore(deps): update hasql to 1.9.3.1
Michael and I arrived at mostly the same things independently. Took some
of his, some of mine.

Co-authored-by: Michal Kleczek <michal@kleczek.org>
2026-04-27 09:12:31 +00:00
Michał KłeczekandSteve Chavez baebacf3db fix: shutdown should wait for in flight requests
Upgraded warp to 3.4.13 which fixed https://github.com/yesodweb/wai/issues/853
Changed interrupt handling so that instead of killing the main thread, listening sockets are closed which triggers warp graceful shutdown.
2026-04-20 16:19:13 -05:00
Wolfgang Walther 3b1373ec02 chore: update the nix upgrade docs
These have been outdated for a while, not only because we're now using
flake.nix, but also in various other places.

Resolves #4816
2026-04-20 19:29:26 +00:00
Wolfgang WaltherandMichal Kleczek 1676314fc3 nix: build with GHC 9.12.3
Jumping past GHC 9.6, 9.8 and 9.10 immediately, because these versions
do not successfully build the static binary with TemplateHaskell and
iserv-proxy, yet.

Michal wrote the changes to hsie.

Co-authored-by: Michal Kleczek <michal@kleczek.org>
2026-04-19 17:53:48 +00:00
Wolfgang Walther 03f7234360 ci: test against PostgreSQL 18 2026-04-19 13:16:55 +00:00
Wolfgang Walther 051b4799de chore(deps): update nixpkgs to latest nixpkgs-unstable
This allows building TemplateHaskell with GHC 9.6+ via iserv-proxy.
2026-04-19 13:16:55 +00:00
Wolfgang Walther 1b74b93466 remove: drop support for PostgreSQL 13
PostgreSQL 13 has been EOL since November 2025 and will not be available
in the next Nixpkgs bump anymore.
2026-04-19 13:16:55 +00:00
Wolfgang Walther 9ed7f52685 nix: put tmpdirs directly into /tmp to fix long unix socket paths
I'm not sure whether that's Lix specific, but when I enter nix-shell, I
get quite a long TMPDIR, which results in all postgrest-with-pg-XX
scripts failing, because the unix socket path is too long. If TMPDIR was
not set, mktemp would fall back to /tmp, so we can just do that in any
case, which guarantees a short path in every case.
2026-04-18 20:53:21 +02:00
Wolfgang Walther dfb3602318 nix: remove left-over comment 2026-04-18 20:53:20 +02:00
Taimoor ZaeemandSteve Chavez 12ef63370b nix(test): add test suite for observability tests
- Create separate test suite for observability tests

- Create wrapper script `postgrest-test-observability`

- Add to CI and `postgrest-check`

- Move JWT cache tests under observability tests

Signed-off-by: Taimoor Zaeem <taimoorzaeem@gmail.com>
2026-03-19 10:38:42 -05:00
steve-chavezandWolfgang Walther af4c4157f5 nix: remove uneeded slocat
slocat was introduced to test pipeline mode (see https://github.com/PostgREST/postgrest/pull/2682),
but pipeline mode was not merged https://github.com/PostgREST/postgrest/pull/2707.

So it's really not needed on the loadtests.
2026-03-13 18:56:31 +00:00
Taimoor ZaeemandSteve Chavez f5b9ed28db nix(chore): remove defunct config in loadtest.nix
`PGRST_JWT_CACHE_MAX_LIFETIME` is defunct since #4084 is merged.

Signed-off-by: Taimoor Zaeem <taimoorzaeem@gmail.com>
2026-03-09 15:46:23 -05:00
steve-chavez abe414ad88 nix: print how to tail the server logs
For easier debugging during loadtests.

Also prefix the echo traces for the postgrest-with-pgrst command.
2026-02-12 20:18:08 -05:00
Kian-Meng AngandSteve Chavez f5c7cde9b7 docs: fix typos
Found via `codespell -S test -L notin,nam,plantext,cryto,corelation,inout,ot`
2026-01-06 05:24:51 +08:00
steve-chavez 76e0e1fbff nix: fix sleep default on postgrest-with-pgrst
The sleep was always applying since it had a default.
2026-01-02 06:11:07 +08:00
steve-chavez b8ca1bb04c nix: add new loadtest for errors
Also included it in CI.
2025-12-23 15:00:24 -05:00
steve-chavez 57c5ff5db3 nix: show wait time for fixture loading 2025-12-23 15:00:24 -05:00
steve-chavez 2b83dcc794 nix: sleep param for withPgrst 2025-12-23 15:00:24 -05:00
steve-chavez 7c3bccf4ba nix: show wait time on withPgrst 2025-12-23 15:00:24 -05:00
steve-chavez d2aa6c1b8a nix: timeout param for withPgrst 2025-12-23 15:00:24 -05:00
Taimoor ZaeemandSteve Chavez a329bca16b nix: add config file for hlint
Adds a config file for hlint containing arguments and
custom warnings.

Signed-off-by: Taimoor Zaeem <taimoorzaeem@gmail.com>
2025-12-22 14:19:46 -05:00
steve-chavez 8f34afd66e nix: jwt loadtest chain commands and split rsa gen
Chaining the target generation command after the build is done ensures
that if a build takes too long, the dynamic target generation for vegeta
won't cause 401 Unauthorized errors due to already expired JWTs.

Also split the rsa materials writing to another python program for
easier maintenance.
2025-12-16 21:15:28 -05:00
steve-chavez 4cdc4c4861 nix: show build time on postgrest-with-pgrst 2025-12-16 21:15:28 -05:00
steve-chavez 050554e2bb nix: fail jwt loadtest in case of 401
Also print last unauthorized body
2025-12-16 21:15:28 -05:00
steve-chavez 99b8246d6e nix: add --method for postgrest-loadtest
Currently the `postgrest-loadtest -k jwt-*` loadtests use the OPTIONS method,
which is good for isolating the perf changes for JWT auth.

But using GET is more accurate for actual perf improvements,
since it actually hits the database.

This adds a method argument for postgrest-loadtest, so GET can be used like:

```
postgrest-loadtest -k jwt-hs --method GET
```

CI is not changed, this is mostly useful for manually checking variance.
2025-12-12 14:46:46 -05:00
steve-chavez 90bf1762ae nix: rename genTargetsHs to genTargets
Previous name wasn't accurate as RSA is used as well.
2025-12-12 14:46:46 -05:00
Taimoor ZaeemandSteve Chavez 35de13eebd test(io): move fixtures to fixtures/ directory
Signed-off-by: Taimoor Zaeem <taimoorzaeem@gmail.com>
2025-11-27 17:08:03 -05:00
Taimoor ZaeemandSteve Chavez 3baa6b0063 test(io): rename fixtures.sql to load.sql
Signed-off-by: Taimoor Zaeem <taimoorzaeem@gmail.com>
2025-11-27 17:08:03 -05:00
Andrei DziahelandGitHub 6d462f762e nix: override PGRST_CMD for postgrest-loadtest from env
Enables `PGRST_CMD=postgrest-profiled-run postgrest-loadtest` running
loadtest against profiled executable, which wasn't available before
2025-11-25 19:46:23 +00:00
Taimoor ZaeemandGitHub 802cce9a28 nix(shell): remove postgrest/ directory prefix when running pg (#4502)
When running postgres from nix-shell, nix creates a directory
structure like `postgrest/postgrest-with-pg-17-XXX` in the `/tmp`
directory. This commit removes the extra `postgrest/` prefix to
shorten length of absolute path length of filenames.

Signed-off-by: Taimoor Zaeem <taimoorzaeem@gmail.com>
2025-11-25 15:54:25 +00:00