Skip to content

fix(data): raise the user cap so a healthy refresh clears the retention floor - #164

Merged
Sagargupta16 merged 1 commit into
mainfrom
fix/refresh-user-cap
Sep 5, 2026
Merged

Sagargupta16 merged 1 commit into
mainfrom
fix/refresh-user-cap

Conversation

@Sagargupta16

Copy link
Copy Markdown
Owner

The 2026-09-05 scheduled run failed. The guard was right; my cap was wrong.

What actually happened

Successfully processed: 5460
No contest history:     2540
Fetch failures:         0        <- zero
Total training records: 197991
Existing records: 244950 (this run keeps 80.8%)
ERROR - Refusing to overwrite ... (80.8%, under the 95% floor)

Zero fetch failures. Nothing was throttled, nothing errored -- the run was completely healthy and still could not reach the committed record count.

Root cause: I sized the cap on a guess

DEFAULT_MAX_USERS assumed a ~90% contribution rate. Measured from this run:

Attempted 8,000
Contributed records 5,460
No contest history at all 2,540
Real contribution rate 68.2%
Records per contributor ~36.3

Roughly a third of usernames.json belongs to accounts that never entered a contest. At 68.2%, 8,000 attempts caps out around 198K records against 245K committed -- so every scheduled run would have failed indefinitely, not just this one.

Fix: 12,000, chosen from the measured numbers

attempts contributors records size
8,000 5,460 197,991 43.7 MB under the committed dataset
10,000 6,825 247,489 54.6 MB clears it by only 1%
12,000 8,190 296,986 65.5 MB 21% headroom
14,000 9,555 346,484 76.4 MB nearing the 90 MB warning

12,000 leaves enough room above the floor that ordinary variance will not abort a run, and stays well under GitHub's 100 MB per-file hard limit (which allows ~18,300 attempts). The constant now carries this table inline so the next adjustment starts from data.

The 95% floor is unchanged. Lowering it would let the dataset shrink permanently, which is the exact outcome it exists to prevent.

Also: the abort message blamed the wrong thing

It said "0 of 8000 fetches failed, which usually means LeetCode throttled the run" -- on a run with no failures. That sends you chasing a phantom throttle. It now branches:

  • with failures: points at throttling, suggests a re-run
  • with none: states plainly that throttling is not the cause, that --users is too low, and that the fix is raising the cap rather than lowering the floor

Verification

11 checks, all passing:

  • healthy undershoot -> aborts, data.json untouched, message names the cap and explicitly does not claim a throttle
  • genuinely throttled run -> message names throttling and suggests a re-run
  • DEFAULT_MAX_USERS is 12000, DEFAULT_MIN_RETENTION still 0.95

ruff and black clean. uv.lock relocked for the version bump so uv sync --locked still passes (that bit me on the last PR).

…on floor

The 2026-09-03 scheduled run failed, and the guard was right while the cap was
wrong. That run fetched all 8,000 users with ZERO failures, collected 197,991
records against the 244,950 committed, and tripped the 95% floor at 80.8%.

DEFAULT_MAX_USERS was sized on an assumed ~90% contribution rate. The measured
rate is 68.2%: 5,460 of 8,000 users contributed records and 2,540 have no contest
history at all, so roughly a third of usernames.json belongs to accounts that
never entered a contest. At that rate 8,000 attempts cannot reach the committed
record count, so every scheduled run would have failed indefinitely.

Raised to 12,000: ~8,190 contributors, ~297K records, ~65 MB. That clears the
committed dataset by 21%, leaving headroom so ordinary variance does not abort,
and stays well below GitHub's 100 MB per-file limit (which allows ~18,300
attempts). The constant now carries the measured table so the next adjustment
starts from data instead of a guess.

Also fixes the abort message, which blamed throttling on a run with no failures:
"0 of 8000 fetches failed, which usually means LeetCode throttled the run". It
now branches. With failures it points at throttling and suggests a re-run. With
none it states that throttling is not the cause, that --users is too low, and
explicitly says to raise the cap rather than lower the floor.

The floor itself is unchanged at 95%. Lowering it would have let the dataset
shrink permanently, which is the outcome it exists to prevent.

Verified with 11 checks covering both message branches: a healthy undershoot
aborts, leaves data.json untouched, and names the cap; a throttled run names
throttling and suggests a re-run. ruff and black clean, uv.lock relocked for the
version bump so `uv sync --locked` still passes.
@sonarqubecloud

sonarqubecloud Bot commented Sep 5, 2026

Copy link
Copy Markdown

@Sagargupta16
Sagargupta16 merged commit fc71dc6 into main Sep 5, 2026
5 checks passed
@Sagargupta16
Sagargupta16 deleted the fix/refresh-user-cap branch September 5, 2026 14:21
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.

1 participant