perf(bracket): drop per-click PUT /v1/picks save#285
Merged
Conversation
Tim noticed every flag tap was firing a PUT /v1/picks/<user>/<match> in DevTools. Under TV-spike load (1000+ concurrent users rapidly clicking 5 picks/sec each = 5000 RPS) that would saturate the single-process game-service event loop, even though each request is fire-and-forget client-side. Removed: - persistPickToServer() callback (was wrapping savePerMatchPick) - Both call sites: onChangeMatch + onChangeKnockout - savePerMatchPick import (now dead from this file) Durability now flows through three paths, all of which were already in place: 1. update() writes the full bracket to localStorage on every pick 2. BracketAutoSave's 30s interval bulk-saves when dirty (PR #282) 3. The explicit Save button at the end of the bracket page The autosave's lastSavedSig wasn't being bumped by the per-match endpoint anyway, so the floating Save button now reliably reflects unsaved state on every pick instead of always-clean. Load profile change (rough): Before: 1000 users × 5 picks/sec = 5,000 RPS sustained. After: 1000 users × 1/30 per save = 33 RPS sustained. 150x reduction in pick-driven traffic. Headroom for ~150k concurrent users at the same game-service capacity, vs ~1k before. Tim 2026-06-05. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: Tim Thomas <0800tim@gmail.com>
0800tim
added a commit
that referenced
this pull request
Jun 4, 2026
Brings perf/drop-per-match-pick-save across so the dev surface matches what Tim verifies before prod sign-off.
Auto-triage: GREEN — auto-triage clearRisk score: 0/100
No flags raised by the automated scanners. A human reviewer will still take a look. Labels applied: Posted by |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Tim noticed every flag tap was firing a PUT
/v1/picks/<user>/<match>in DevTools. Under TV-spike load (1000+ concurrent users × 5 picks/sec) that would saturate the single-process game-service event loop, even though the request is fire-and-forget client-side.Removed both per-match call sites in BracketBuilder (
onChangeMatch+onChangeKnockout) plus thepersistPickToServercallback and thesavePerMatchPickimport. Durability now flows through:update()writes the full bracket to localStorage on every pick (no change).BracketAutoSave's 30s interval bulk-saves when dirty (PR feat(bracket): dirty-detect + floating save + 30s autosave #282).The autosave
lastSavedSigwas never bumped by the per-match endpoint, so dropping it actually fixes the dirty-detect — the floating Save button will now reliably appear after the first edit instead of being competed-with by the silent per-match path.Load profile change (rough numbers):
🤖 Generated with Claude Code