Background & current state
High-volume tables (participants, indexed events, audit logs) grow unbounded across many campaigns. Large monolithic tables degrade query latency and bloat indexes. No partitioning exists.
Goal
Partition high-volume tables (by campaign_id and/or time range) so hot queries use partition pruning and old data can be archived/dropped cheaply.
Technical design
- Postgres declarative partitioning:
PARTITION BY LIST (campaign_id) or RANGE (created_at) for events/audit; automated partition creation for new ranges.
- Migrations to convert existing tables (create partitioned table, backfill, swap) with zero/low downtime.
- Validate plans with
EXPLAIN ANALYZE (pruning confirmed).
Edge cases
- Existing data migration → online backfill + swap; document downtime.
- Cross-partition queries → ensure indexes support them.
- Partition explosion (too many campaigns) → use hash sub-partitioning or time-based for events.
- Retention: drop old time partitions instead of
DELETE.
Task breakdown
Acceptance criteria
Testing & verification
EXPLAIN ANALYZE assertions in tests; migration up/down round-trip.
Out of scope
Dependencies / related
- Complements NEW-024 (events), NEW-034.
Difficulty: medium · Effort: M · infra + performance
Background & current state
High-volume tables (participants, indexed events, audit logs) grow unbounded across many campaigns. Large monolithic tables degrade query latency and bloat indexes. No partitioning exists.
Goal
Partition high-volume tables (by
campaign_idand/or time range) so hot queries use partition pruning and old data can be archived/dropped cheaply.Technical design
PARTITION BY LIST (campaign_id)orRANGE (created_at)for events/audit; automated partition creation for new ranges.EXPLAIN ANALYZE(pruning confirmed).Edge cases
DELETE.Task breakdown
Acceptance criteria
Testing & verification
EXPLAIN ANALYZEassertions in tests; migration up/down round-trip.Out of scope
Dependencies / related
Difficulty: medium · Effort: M · infra + performance