Skip to content

catalog: user history/ratings mirror rewritten in full each sync — unbounded growth #1047

Description

@electather

Module: catalog · Dimension: perf · Severity: medium · Location: apps/server/src/catalog/service/user-mirrors.ts:143

Problem

appendMirrorRows reads the entire existing events JSON blob for a user (userHistoryMirror/userRatingsMirror.events, schema at apps/server/src/db/schema/catalog/catalog.ts:96, mode 'json', no size cap), merges via uniqBy([...prior, ...next]) (mergeHistory/mergeRatings, lines 157-163), and writes the full merged array back as one JSON column on every run of the every-6-hours user_mirror_sync job (apps/server/src/catalog/jobs/user-mirror-sync.ts, schedule '0 */6 * * *').

Why it matters

For a long-lived user with years of watch history (thousands to tens of thousands of events), every sync does an O(n) dedupe scan over the full history and rewrites the entire growing blob to SQLite every 6 hours forever — cost per sync increases monotonically with account age and there is no trimming/pagination of the events array.

Suggested fix

Cap or archive old events (e.g. keep only last N events or events within a retention window) when merging, or move to an append-only events table instead of a single JSON blob column so writes are O(new events) not O(total history).

Fable-panel validated: 2/3 votes.


Filed from automated per-module audit workflow (Opus/Sonnet research → Fable-panel decision). Unverified by a human — triage before acting.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions