Skip to content

[Onyx] Investigate QuotaExceededError: The current transaction exceeded its quota limitations. storage error #87863

Closed

Description

@fabioh8010

Coming from #87844.

Summary

Let's investigate the following Onyx storage error: QuotaExceededError: The current transaction exceeded its quota limitations., which accounts for 865,703 (25.7%) of the 3,364,645 analysed errors during a time span of 1 month. Full details about the investigation and methodology are in #87844.

Platforms Top Methods
Desktop Firefox (865K — 100%) setWithRetry (865K)
Retries Exhausted Evictions No Eviction Quota Checks >= 95% Full Mean % Full Quota Check Failed
6,089 859,566 0 859,276 0 0.0% 0
  • 859,276 quota checks with mean 0.0% full — Firefox reports quota exceeded even when overall usage is negligible. The exact quota model (per-transaction, per-write, or other) is unclear from the data alone
  • Firefox-exclusive error — different quota behavior from Chromium and Safari
  • Eviction is triggered frequently, and relatively few requests end up exhausting retries (6,089), suggesting eviction generally helps resolve this error

Action Items

  • Investigate with Sentry, VictoriaLogs and Fullstory to understand user scenarios where this happens — what kind of data is being written when Firefox rejects the transaction?
  • Investigate what Firefox's exact quota/transaction limit is and whether we are writing values that are too large for it

Activity

  1. fabioh8010 commented on May 12, 2026

    @fabioh8010
    ContributorAuthor

    There was a PR created here Expensify/react-native-onyx#781, but I think we should close it until we have better investigations and picture about how we want to move here. Also Jakub is no longer at Callstack so it's difficult to handle the PR this way.

  2. sosek108 commented on May 29, 2026

    @sosek108
    Contributor

    Hi, I'll be continuing investigation here

  3. LukasMod commented on May 29, 2026

    @LukasMod
    Contributor

    I did some investigation before my OOO to help @sosek108 on this:

    Local repro (Firefox origin storage cap)

    I reproduced production-like Onyx QuotaExceededError logs in Firefox by lowering the browser’s origin storage quota (IndexedDB budget for the site — not the user’s OS disk free space) via about:config:

    1. Open Firefox.
    2. Go to about:config.
    3. Set dom.quotaManager.temporaryStorage.fixedLimit to a small value (on my build the pref is in KB; effective cap ≈ value × 1024 bytes — fully quit Firefox after changing it).
    4. Quit Firefox completely (e.g. Dock → Quit). Closing the window alone is not enough for the pref to apply.
    5. Reopen Firefox, open Expensify, and watch the console.

    Example console output:

    [Onyx] Out of storage. But found no acceptable keys to remove. Error: QuotaExceededError: The current transaction exceeded its quota limitations
    [info] [Onyx] Storage Quota Check -- bytesUsed: 30731014 bytesRemaining: 726266. Original error: QuotaExceededError: The current transaction exceeded its quota limitations.
    

    Here bytesRemaining is small because navigator.storage.estimate() reports room left in the browser’s per-origin quota, which we artificially capped — not because the machine’s hard drive is full.


    Findings

    1. The issue affects few users who generate almost all error-log volume (see tables below).

    2. In FullStory, errors started after the tab was idle for several minutes while Pusher updates continued.

      • Hypothesis A (browser / Onyx data): the per-origin IndexedDB budget for Expensify fills over time from background sync (idle tab + Pusher / onyxData writes) until Firefox rejects further writes — not necessarily from active Spend/Search use.
      • Hypothesis B (OS disk): while the tab is idle, the user (or another app) fills the machine’s disk. IndexedDB still needs free filesystem space to grow; writes can fail even when our logs show a large bytesRemaining in navigator.storage.estimate(), because that API measures the browser’s origin quota, not “GB free on the SSD.” We cannot see OS free space from the web app; this path is plausible for user-specific repros but not proven by current prod logs (most samples show ~0.5% of origin quota used and ~10 GB bytesRemaining).
    3. I could not reproduce on a normal origin quota pool by writing large payloads locally (single large writes or bulk multiSet) — synthetic Onyx size alone was not enough on my machine. That does not rule out Hypothesis A at real account scale, or Hypothesis B if disk pressure happened on the user’s machine but not in my test environment.

    4. With the capped origin quota pref, opening the Spend tab triggered a retry/eviction loop (possibly unbounded) — likely how some sessions produced 150k+ similar log lines.

    5. Open question — bytesRemaining vs behavior: For many affected users, Storage Quota Check does not show a nearly full browser quota. Example from production:

      Storage Quota Check -- bytesUsed: 52716687 bytesRemaining: 10684701553.
      

      With fixedLimit, the same log line shows low bytesRemaining (aligned with the cap). In production, bytesRemaining is often ~10 GB while writes still fail with the same error string. Unclear whether we should treat bytesRemaining as ground truth, or whether Firefox enforces a different limit than estimate() reflects (e.g. per-transaction limit, or timing vs eviction).


    User concentration (anonymized) — last 30 days

    Query: any log line containing The current transaction exceeded its quota limitations (includes Failed to save, eviction, quota check, etc.).

    Total: 17,324 events · 15 users with email · 1 row without email

    User Events (30d) % of all events
    User 1 5,808 33.5%
    User 2 5,367 31.0%
    User 3 1,688 9.7%
    User 4 766 4.4%
    User 5 643 3.7%
    Rest (11 users) 3,052 17.6%
    Total 17,324 100%

    Example prod quota line: bytesUsed: 51466333, bytesRemaining: 10685951907 → ~0.5% of reported origin quota used — errors still fire.

    Interpretation: High event count comes from few sessions (Users 1–2 ≈ 65% in 30d).


    User concentration (anonymized) — last 2 months (Apr spike; not primary focus)

    Total: 364,216 events · dominated by 2026-04-18 and 2026-04-21. Top 2 = 87.0% — different accounts than the 30-day leaders above.

    User Events (2 mo) % of all events
    Spike user A 167,725 46.1%
    Spike user B 149,269 41.0%
    Spike user C 10,938 3.0%
    Spike user D 8,041 2.2%
    User 1 (30d rank 1) 5,808 1.6%
    User 2 (30d rank 2) 5,367 1.5%
    User 3 (30d rank 3) 3,493 1.0%
    User 10 (30d rank 10) 198 0.1%
    All others (2 mo) < 3,000 each < 1% each

    Firefox users from last 7 days

    Metric Value
    Firefox users with any [App] log 2,555
    Users with ≥1 transaction exceeded line 3

    Next steps

    We may not be able to eliminate these errors entirely — they appear user-specific. Most Firefox users never hit them.
    Still, we can reduce noise, improve diagnostics, and degrade more gracefully when storage writes fail.

  4. sosek108 commented on Jun 1, 2026

    @sosek108
    Contributor

    Update posted here: #87873 (comment)

  5. sosek108 commented on Jun 3, 2026

    @sosek108
    Contributor

    Let's close this as duplicate of #87873 (comment)
    cc: @Julesssss

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions