Checkpoint 1 · t070 Scale Analysis

Will the card catalog blow out at 100,000 users?

You asked: "if I have 100K users, won't the t070 table blow out fast? Maybe the plan was one t070 per user, with the catalog on a replicated table." We went to the live database and the two decision records that actually specced this (ADR-083, ADR-086) and worked out exactly which table grows with what. Short version: the catalog was never going to blow out from users — it grows with content. The table that grows with users is a different one, and that one is the normal, boring kind of big.

Source: BRIEF-2026-07-06-001 No blowout before ~10,000 users One real decision (R1) Two cheap fixes recommended now
Checkpoints Latest →
The growth story

Three tables, three different growth curves

Plain-English version of what actually scales with what.
What grows with what
t070 · curated catalog
Grows with languages and words, NOT users. Today: 10 MB. At 10 fully-enriched languages: ~6–9 GB total. Add a millionth user and this number doesn't move.
t310 · progress
Grows with users × cards studied. At 100K users this lands at 50–150 GB — big, but the boring, well-understood kind of big. The right indexes already exist for it.
Custom content (inside t070)
The one genuinely user-driven piece. One profile (the "Bodhisattva Vows" content-study test) added ~105 rows for one uploaded document — that's the template for "upload a document, study it."
The numbers

Does custom content blow it out?

Three adoption scenarios at 100,000 users — how many people upload their own study documents, and how much that adds to the catalog.
Adoption @ 100K users Rows added Catalog weight added Verdict
5% author 1 document ~0.5M rows ~4 GB Fine — just add one index
25% author 2 documents ~5M rows ~40 GB Action threshold — custom outnumbers curated content 50:1 in its partition
100% author 3 documents ~30M rows ~250 GB Genuinely stressed — needs its own storage

Bottom line: no blowout before roughly 10,000 users, even in the aggressive scenario. Today's job is two cheap safeguards, not a rebuild.

Answering your memory

What was actually specced?

No per-user tables, and no replicated catalog, were ever written down anywhere.

Two decisions already cover this ground:

ADR-083 (your own ruling from 2026-07-02) put curated and custom content in one table, distinguished by an owner column, with row-level security to keep one user's uploads private from another.

ADR-086 landed the columns for that design but deliberately postponed switching on the privacy rule until the pre-launch security gate (the same "F3" gate flagged in the July 2 schema audit). Until that switch flips, custom rows are technically readable by anyone — that's a known, already-tracked launch-gate item, not something new this analysis found.

Neither ADR ever proposed a table-per-user or a replicated catalog. The healthy version of the "replicated catalog" instinct is a read replica — a real Postgres feature, available later if read traffic (not table size) ever becomes the bottleneck. That's a different problem than size, and not needed today.

Recommendation

Do now vs. wait for

1
Add the missing index. There's currently no database index on the "who owns this row" column — needed for the privacy rule and for fast per-user loads. One small migration, no product change.
2
Add a filter discipline. Every place that scans the catalog for enrichment/production work should explicitly say "curated content only" — cheap now, prevents a slow silent slowdown later as custom content grows.
3
Then wait. Nothing else needed below 10,000 users. Re-check at ~1 million custom rows in one language (~10K uploaded documents); actually rebuild storage only if it nears ~5 million rows — still a fast, minutes-long operation at that point. The progress table (t310) gets its own separate, standard partitioning plan around 100 million rows.
The one real fork

Decision needed

Everything else above is a recommendation already in motion. This is the one choice that's actually yours to make.
R1
Where should user-uploaded study content live long-term?
Option A (recommended): keep custom content inside t070 permanently, with a pre-built "escape hatch" — only rebuild it into its own partition if custom rows in one language ever near ~5 million. Cheap now, and we may never need the rebuild.

Option B: build the dedicated custom-content partition now, while the rebuild is still a fast, minutes-long job. Costs real engineering time today for a problem that may not show up for years, and the right shape depends on adoption facts we don't have yet.
Decided by Frank
Loose thread

The still-open skill-family checkpoint

This analysis needed exactly the discipline those skills would provide.

There's an older, still-unanswered checkpoint — "Database Design for Mere Mortals" (5-skill family) — and it's not moot. This analysis needed exactly those five database-design skills (keys, partitioning, access paths, growth-rate reasoning) and found they were never actually landed in the repo — they're still sitting in scratch, waiting on a go-ahead. The reasoning here was done manually instead. Worth a go/no-go so that skill family either lands for real or gets consciously dropped.

Sources

Cross-links

Full analysis with numbers, live-schema evidence, and assumptions: BRIEF-2026-07-06-001.

Governing decisions: ADR-083 (one-table registry + owner/RLS design) · ADR-086 (columns landed, privacy switch deferred to the F3 launch gate).

Related launch-gate context: BRIEF-2026-07-02-001 (whole-schema integrity audit — same F3 gate).