Skip to main content

redb_cache_bytes

Function redb_cache_bytes 

Source
pub fn redb_cache_bytes() -> Result<usize>
Expand description

The page-cache ceiling for one repository’s redb database, in bytes.

§Why this exists at all

redb::Database::create(path) is Builder::new().create(path), and Builder::new ends with set_cache_size(1024 * 1024 * 1024) — redb-2.6.3 db.rs:1140. One GiB, per database, by default, split 90 % read / 10 % write by set_cache_size (db.rs:1184), so the stock ceiling is 1 GiB per repository and a long-lived server holding N repositories has N times that.

§“Two databases per repository” was stale, and it cost a wrong diagnosis

This paragraph said “a store opens two of them, so the stock ceiling is 2 GiB per repository” until 2026-08-31. A store opens one. GitStore::open_with_arms constructs exactly one ObjectReadStack — objects.tail — and tests/fd_per_store.rs counts exactly one objects.tail descriptor per store and asserts the total is three. The second database was the exploded table’s, and it stopped being a redb when §14 moved that tier to append-only Arrow IPC (crate::exploded_arrow); the sentence outlived it.

It is recorded rather than quietly deleted because a stale doc is a second truth and this one was believed: gunnar/.nornir/stinky.md S-079 doubled this figure to 128 MiB per store on the strength of it, and built an explanation of a live appliance’s 10 G on top. See S-082 for the measurement that refuted it.

It is a ceiling and not a reservation, so a small repository never noticed. MEASURED 2026-08-10 (t14s, h2h-linear-sha1-2048c-1024f-16k, a 1 078 472 704-byte objects.exploded): a single clone parked 594 MB resident and kept it for the life of the process, because the pages a full-file traversal touched all fit under the ceiling and nothing evicted them.

§How the default was chosen

A B-tree read cache earns its keep on the interior nodes, which every lookup re-touches, and earns nothing on a single sequential pass over the leaves, which is what a refold is. The interior levels of a 4 KiB-page B-tree over that 1.078 GB table are ~7 MB; 64 MiB holds all of them nine times over and leaves 6.4 MiB of write cache, which is more than one absorb batch dirties. Measured against the 1 GiB default on the clone path it costs nothing and returns most of the resident set — see the sweep in agentAA-report.md.

§This is the one environment read that is not an arm

Every other variable in this module selects an implementation and therefore changes what the store promises, which is why GitStore::open deliberately reads none of them. This one selects nothing: it is a memory ceiling, every arm behaves identically under any value of it, and the bytes on disk are the same either way. So it is read on the open path — an operator who has to cap a server’s footprint cannot be told to use a different constructor.

An unparseable or zero value is an error, for the same reason a misspelled arm is: a silent fallback would let an operator believe a measurement came from a ceiling that was never applied.