Skip to content

docs(browser): add storage limits and persistence guidance - #84

Open
harish18092002 wants to merge 1 commit into
libredb:mainfrom
harish18092002:docs/browser-storage-limits
Open

docs(browser): add storage limits and persistence guidance#84
harish18092002 wants to merge 1 commit into
libredb:mainfrom
harish18092002:docs/browser-storage-limits

Conversation

@harish18092002

@harish18092002 harish18092002 commented Aug 31, 2026

Copy link
Copy Markdown

What and why

Closes #63.

docs/BROWSER.md explained how OPFS works — sync access handles, the Worker requirement, the
flush() durability caveat — but a developer asking "how big can my database be in a browser, and
will it survive?" had no page to read. The only guidance was two sentences in a gotchas bullet,
which left four misconceptions unaddressed:

  • OPFS confused with the 5-10 MB localStorage limit, which belongs to a different storage system
    with its own separate quota.
  • persist() assumed to guarantee persistence, when it is a request whose boolean result has to be
    checked.
  • Free quota assumed to equal usable database size, when the engine is memory-bound well below it.
  • WAL history assumed to cost nothing, when it is what actually consumes the quota.

Every claim in the new section is traceable to the implementation, existing project docs, or an
authoritative browser reference (MDN, WebKit).

How it works

Adds ## 7. Storage limits and persistence to docs/BROWSER.md (7.1-7.7), renumbering "Which mode
should I use?" to section 8. It opens by separating the three ceilings people conflate — memory, WAL
growth, and the origin's quota — then covers each:

  • 7.1 Quota — the Storage Standard pool shared with IndexedDB and the Cache API, with a
    per-browser table labelled as browser policy rather than contract, including Firefox's 10 GiB
    best-effort cap and WebKit's reduced quota for embedded web content.
  • 7.2 estimate() — a Worker-safe example, plus the two caveats: the values are deliberately
    imprecise, and usage covers the whole origin, not just the .libredb file.
  • 7.3 Persistence and eviction — best-effort vs persistent, and Safari's seven-day deletion of
    script-written storage, which for a database is a larger risk than quota.
  • 7.4 Quota exhaustion — the failure chain from write() to LibreDbError, and a catch
    example narrowing on code === "FAILED" then cause.name === "QuotaExceededError".
  • 7.5 WAL growth — quota spent on history rather than live data, and the trap that deleting
    records makes the file larger. Links Add WAL compaction to reclaim space and bound recovery time #12.
  • 7.6 Memory — the ceiling that actually binds, with steady-state vs peak cost at open. Links
    [P3][kernel] Stream recovery record-by-record to bound open() memory #64.
  • 7.7 Worked example — an offline-first app at 450 MB live behind a 2.2 GB file, walked through
    all five concerns.

Two points worth reviewer attention:

The persist() example is on the main thread, not in the Worker. The issue asks for the call i
the Worker setup example, but StorageManager.persist() is [Exposed=Window] and is not available
in workers — putting it in db.worker.ts would document an API that does not exist there. It sits
in the main-thread half of the section 4.2 setup with the reason stated inline, and the
worker-exposed persisted() / estimate() are shown alongside.

Section 7.4 links rather than restates. It describes only what the browser contributes — a
QuotaExceededError arriving on the commit path — and defers to RELIABILITY.md for why the latch
exists, so the durability contract keeps one home.

Two figures also differ from the issue body after checking the sources: Firefox best-effort quota i
the smaller of ~10% of disk or 10 GiB (the cap matters for a database), and Safari home-screen
web apps are not exempt from the seven-day rule — per WebKit they keep their own counter of days of
use, which using the app resets.

Also fixes a 404 link in section 2 that pointed at libredb/libredb instead of
libredb/libredb-database.

src/core.ts, src/adapter/opfs.ts, and every test are untouched. The behaviour documented in 7.4
already exists and is already covered — the latch refusing reads as well as writes is asserted in
src/core.hardening.test.ts.

Checklist

  • bun run gate passes locally (typecheck, format, lint, knip, build, size, test).
  • Tests are added or updated to cover the change (coverage is held at 100%).
    Not applicable: documentation only, no source change. The gate still reports 348 passing test
    and 100% line/function coverage.
  • A changeset is added for user-facing changes (bun run changeset).
    Intentionally omitted, per the issue's acceptance criteria: only dist/ is published, so docs
    never reach the package.
  • Docs updated if behavior or the public API changed.
  • English only, no emoji, Conventional Commit PR title.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[P2][docs] Browser storage guidance: quotas, persist(), eviction, and the memory ceiling

1 participant