Skip to content

skip chunk quota checks for superusers - #12

Merged
christophwitzko merged 1 commit into
mainfrom
codex/skip-superuser-chunk-quota
Aug 4, 2026
Merged

christophwitzko merged 1 commit into
mainfrom
codex/skip-superuser-chunk-quota

Conversation

@alexandrusavin

Copy link
Copy Markdown

Summary

  • Skip the per-owner chunk count and chunk-quota comparison when an ingestion owner is a superuser.
  • Resolve the owner and quota settings once per ingestion instead of once per chunk.
  • Preserve the existing quota and limits_overrides["max_chunks"] behavior for normal R2R users.
  • Add regression tests proving that superuser ingestion does not call list_chunks, while normal-user ingestion still does.

Exact issue

Monoloom does not use R2R ownership for file permissions. It filters searches with the UUIDs of files and notes that the caller may access. Because Monoloom does not authenticate individual users to R2R, every stored chunk belongs to R2R's default admin user.

The Ruinart database confirmed:

  • R2R had one active user, the default admin, and it was a superuser.
  • Stored chunks used that superuser as their owner_id.
  • Each file or note ingestion entered store_embeddings, which called list_chunks(limit=1, filters={"owner_id": ...}) to enforce default_max_chunks_per_user.

That call generated query fingerprint -2001702420117276229:

SELECT
    id,
    document_id,
    owner_id,
    collection_ids,
    text,
    metadata,
    COUNT(*) OVER() AS total_entries
FROM r2r_default.chunks
WHERE owner_id = $1
LIMIT $2
OFFSET $3

LIMIT 1 does not make this cheap: PostgreSQL must process all chunks for that owner to calculate COUNT(*) OVER(). The query also carries the wide text and metadata columns through that operation. Since all Monoloom chunks have the same owner, every ingestion counted the entire chunk corpus.

Increasing default_max_chunks_per_user would not help because the count query runs before R2R reads and compares the configured limit.

Incident evidence

This was observed during the Ruinart 504 incident.

Azure Query Store for 2026-08-03 15:30:14–15:45:14 UTC, which overlaps the incident report at 15:38 UTC, recorded:

  • 53 executions of fingerprint -2001702420117276229.
  • 90.7 seconds average execution time.
  • 209.7 seconds maximum execution time.
  • About 17.65 million temporary blocks read and the same number written across those executions.

At PostgreSQL's 8 KiB block size, that is approximately 2.54 GiB read and 2.54 GiB written per execution on average, or roughly 5.08 GiB of temporary I/O per quota check.

A nearby 15-minute window recorded 52 executions averaging 147.1 seconds, with a maximum of 239.1 seconds.

The browser polling storm investigated in the Slack thread amplified overall load, but it did not create this SQL. This query came from ingestion-side quota bookkeeping and can recur under concurrent indexing even after polling is reduced.

Why this fix

R2R's document API already skips its route-level quota preflight for superusers. The ingestion service did not apply the same exemption and still counted every chunk before storing embeddings.

This change makes the ingestion path consistent with the API path:

  • Superuser owner: store embeddings without the unused owner-quota count.
  • Normal owner: keep the existing count, configured limit, and per-user override behavior.

This does not change Monoloom permissions or R2R access filtering.

Validation

pytest -q tests/unit/app/test_routes.py tests/unit/app/test_config.py tests/unit/ingestion/test_ingestion_service.py
32 passed, 9 skipped

ruff check, ruff format --check, and git diff --check also pass.

Deployment follow-up

After merging this PR:

  1. Build and push a new dated interloom.azurecr.io/r2r image.
  2. Update Monoloom's pinned R2R image version.
  3. Deploy it to Ruinart.
  4. Confirm that fingerprint -2001702420117276229 no longer appears during file or note ingestion.

A separate defense-in-depth improvement can replace the general COUNT(*) OVER() implementation with a narrow count query for deployments that use normal R2R user quotas.

@alexandrusavin
alexandrusavin marked this pull request as ready for review August 3, 2026 16:53
@christophwitzko
christophwitzko merged commit ffb2560 into main Aug 4, 2026
2 checks passed
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.

2 participants