You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
chore(infra): do not partition AuditEvents by time — record why, and what to do instead #505
Parked from the #494 review, so the reasoning is not rediscovered.
Question
AuditEvents is append-only with no purge sweep, so it only grows. #494 adds ~1 row per daily entry per day (DailyEntry.Create + DailyEntry.Submit). Should we get ahead of it by range-partitioning the table by month?
Answer: no, and not merely "not yet"
Time partitioning is the wrong axis for this table. Partition pruning only helps a query that filters on the partition key. The dominant read — AuditEventRepository.GetProvenanceAsync, run on every Flocks / Egg grades / Daily entries / Sales / Expenses page load — filters on AccountId + EntityType + EntityId and carries no date predicate at all. Partitioning by month converts one index lookup on IX_AuditEvents_AccountId_EntityId into one lookup per partition, getting worse every month. It would degrade the exact query #494 introduced.
Three further costs, none of them the deciding one:
Postgres requires the partition key in every unique constraint, so the PK moves from Id to (Id, OccurredAtUtc). Converting an existing table means create-new + copy + rename, not an ALTER.
~2 rows per flock per day. 10 flocks -> ~7.3k rows/year; 100 flocks -> ~73k rows/year, roughly 20 MB/year. Not a problem at any plausible farm size.
If it ever does bite, in order
Archive or roll up rows older than the retention the farm actually needs.
Partition by AccountId — the column the provenance query does filter on, so pruning would apply. Only meaningful once the deployment is genuinely multi-tenant.
Separate, and real
The Audit page pages with OFFSET, which degrades on deep pages as the table grows. Independent of partitioning and of #494; worth keyset pagination on its own merits if it ever shows up in practice.
Activity
docs: soften an overstated partition-cost claim in the #505 record (#505
docs: caveat the #505 record's archival suggestion against breaking p…
chore(infra): record why AuditEvents is not time-partitioned (#522)
docs: keep cross-directory rules in root; route every trigger path in…
docs: close round-2 routing gaps in the scoped rule index