Skip to content

Architecture: no data retention policy or archival for check_runs—table will grow indefinitely #44

@tkadauke

Description

@tkadauke

Description

check_runs records are created every time a health check executes. With the default interval of 1 minute per check, a single health check generates 1,440 records per day. The table has no time-based partitioning, no archival strategy, and no automatic purge.

The has_many :check_runs, dependent: :destroy association in HealthCheck means deleting a check cascades to all runs—but a health check that has been running for a year with a 1-minute interval has 525,600 rows that must all be deleted in a single transaction.

Impact

  • Table grows ~1M rows per check per year with 1-minute intervals.
  • Queries on check_runs (dashboard, history views) slow down as the table grows, even with indexes.
  • Deleting an active check can time out due to cascaded destroy.
  • last_response is a TEXT column storing full HTTP response bodies—potentially KB per row.

Suggested approach

  1. Add a cleanup_old_check_runs job that deletes rows older than N days (configurable per account).
  2. Use Rails dependent: :delete_all (bulk SQL) instead of dependent: :destroy for the cascade.
  3. Consider archiving old runs to a separate table or cold storage.
  4. Add database-level partitioning by created_at for MySQL 8.0+.

Effort: medium

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions