Skip to content

v0.27.0

Choose a tag to compare

@github-actions github-actions released this 22 Oct 17:13
· 37 commits to main since this release

Read workers take connections themselves

v0.27.0 is about reads under load. On Linux each read worker now listens on the server's port too, so record reads no longer all pass through one thread. List totals no longer count the whole table after every write, and a search with no sort stops at the page instead of ranking every match.

Changes

  • Read workers accept connections (Linux). The kernel spreads connections over the main thread and the read workers. A worker serves list and get-one itself and passes everything else (writes, auth, admin, files, SSE, realtime, custom routes) to the main thread over loopback, with the client's address, so per-client limits and trusted proxies work as before. Measured in Docker with 4 workers on 6 cores: single-record fetches went from 38.6k to 112k req/s and 38 KB list pages from 7.2k to 29.7k req/s; writes alone are 3% slower. On by default on Linux; macOS and Windows keep the old path. VAULTBASE_WORKER_LISTENERS=0 turns it off.
  • List totals come from a stored row count. A list with no filter reads its totalItems from a count kept by triggers in the same transaction as each insert and delete, so it stays exact for writes from the API, hooks or raw SQL. Under steady writes every list used to count the whole table again. Filtered lists, rules that add a condition and searches count as before. SQLite only.
  • Search is newest first unless you ask for relevance. A ?search= with no sort returns the newest matches and stops at the page (a word in every one of 100k records: 3.3 ms over HTTP, from 67 ms). Pass sort=@rank for relevance order as before. A search's totalItems is counted on the search index.
  • Record reads are forwarded to a worker ahead of the request pipeline, a few percent less work on the main thread for each one.

Fixes

  • Reads served by read workers skipped the rate limiter. Since read workers became the default in 0.22.0, list and get-one requests answered by a worker were never counted. They are counted again.

Upgrade notes

  • Reads count toward rate limits again. The default rule allows 300 requests per 10 seconds per client address on /api/*. Behind a reverse proxy, set VAULTBASE_TRUSTED_PROXIES (or security.trusted_proxies) so each client is counted by its own address; otherwise every client shares the proxy's. Raise or change the rules in Settings → Rate limiting if your clients read more than that.
  • Search order changed. Clients that relied on relevance order with no sort should pass sort=@rank.
  • The first start counts each record table once to set up its stored row count (a vaultbase_row_counts table and two vb_rowcount_* triggers per table). On a large table that start takes a little longer than usual.
  • On Linux, the read workers bind the server's port as well, and the main thread opens a listener on a random 127.0.0.1 port for what they pass to it. A slow request on a worker (a search, a filter on an unindexed field) now holds up the other requests on that worker's connections; VAULTBASE_WORKER_LISTENERS=0 restores the previous behaviour.

Full Changelog: v0.26.5...v0.27.0