PhoenixKitWebAnalytics.Retention (PhoenixKitWebAnalytics v0.2.0)

Copy Markdown View Source

Keeps the events table from growing without bound.

Analytics is the one table in a PhoenixKit app that grows with traffic rather than with content, so it needs a story for old data from day one. Once an hour this process:

  1. Rolls up every completed day that doesn't have a PhoenixKitWebAnalytics.Schemas.DailyStat row yet — page views, visitors, sessions, bounces, and total session seconds, per site.
  2. Prunes raw events older than web_analytics_retention_days (365 by default; 0 disables pruning), in batches, and only for days that were rolled up first.

So the long-range trend line is permanent while the raw rows behind it are not. What is lost at the retention horizon is the ability to break an old day down by page or referrer — see PhoenixKitWebAnalytics.Reports for how reports handle the boundary.

Scheduling

The first run is deliberately a couple of minutes after boot: a host restart should not spend its first seconds deleting rows while it is also serving the post-deploy traffic spike. Runs are skipped entirely while the module is disabled.

Rollup is idempotent — a day is aggregated once, and the upsert makes a repeat run a no-op — so a crash or a restart mid-pass costs nothing.

Summary

Functions

Returns a specification to start this module under a supervisor.

Deletes raw events past the retention horizon, in batches.

Aggregates one day into DailyStat rows, one per site.

Writes DailyStat rows for completed days that don't have one yet.

Runs a rollup + prune pass immediately, in the caller's process.

Asks the running process to do a pass. Returns immediately.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

prune_old_events()

@spec prune_old_events() :: non_neg_integer()

Deletes raw events past the retention horizon, in batches.

Returns the number of rows deleted. Days that have not been rolled up yet are left alone — pruning never runs ahead of the aggregation that preserves the trend line.

rollup_day(date)

@spec rollup_day(Date.t()) :: :ok | :error

Aggregates one day into DailyStat rows, one per site.

rollup_pending_days()

@spec rollup_pending_days() :: non_neg_integer()

Writes DailyStat rows for completed days that don't have one yet.

Returns the number of days rolled up. At most 60 days are handled per pass, so a first run against a large backlog spreads its work over several hours instead of locking up the database in one go.

run()

@spec run() :: %{rolled_up: non_neg_integer(), pruned: non_neg_integer()}

Runs a rollup + prune pass immediately, in the caller's process.

Returns %{rolled_up: days, pruned: rows}. Used by the admin settings page's "Run now" action and by tests, which need the work to happen on the sandbox connection.

run_async()

@spec run_async() :: :ok

Asks the running process to do a pass. Returns immediately.