> ## Documentation Index
> Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Usage Aggregation — Cron Scheduling Guide

> The pf_aggregate_resource_usage() function rolls up realtime usage into daily/monthly periods. It should be scheduled to run periodically via pg_cron.

## Overview

The `pf_aggregate_resource_usage()` function rolls up realtime usage into daily/monthly periods. It should be scheduled to run periodically via `pg_cron`.

## Function

```sql theme={null}
SELECT pf_aggregate_resource_usage();
```

This SECURITY DEFINER function:

1. Iterates all active quotas with `reset_period` = `'daily'` or `'monthly'`
2. Sums realtime usage rows for the current period
3. Upserts aggregated rows into `pf_resource_usage` with `aggregation_period = 'daily'` or `'monthly'`

## Scheduling via pg\_cron

### Prerequisites

Enable `pg_cron` and `pg_net` extensions in the Supabase Dashboard → Database → Extensions.

### Recommended Schedule

```sql theme={null}
-- Run daily aggregation every hour
SELECT cron.schedule(
  'pf-43-usage-aggregation-hourly',
  '0 * * * *',
  $$SELECT pf_aggregate_resource_usage();$$
);

-- Run daily cleanup of old realtime rows (optional)
SELECT cron.schedule(
  'pf-43-realtime-cleanup-daily',
  '30 3 * * *',
  $$DELETE FROM pf_resource_usage
    WHERE aggregation_period = 'realtime'
    AND period_start < now() - interval '7 days';$$
);
```

### Via Supabase Dashboard

1. Go to **SQL Editor** → New Query
2. Paste the `cron.schedule(...)` SQL above
3. Run the query

### Verification

```sql theme={null}
SELECT * FROM cron.job WHERE jobname LIKE 'pf-43%';
```

## Notes

* The aggregation function is idempotent (uses UPSERT)
* No edge function needed — runs directly in Postgres
* Realtime rows older than 7 days can be safely pruned
* Monitor via `pf_resource_usage` row counts per aggregation\_period
