Scaling dashboard aggregations over hundreds of millions of events

Backend Live Coding November 13, 2026 sql

I separate OLTP from OLAP.

sql
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
-- ======================================================================
-- Q: Dashboards with aggregations over hundreds of millions of events. What do
-- you do?
--
-- I separate OLTP from OLAP. Steps in order of cost: (1) proper indexes and a
-- BRIN index on created_at for append-only tables, (2) partitioning by month
-- (fast dropping of old data for retention), (3) precomputed rollups (per
-- hour/day) or materialized views, (4) a read replica for reports, (5) a column
-- store such as ClickHouse or TimescaleDB when the volume requires it.
-- ======================================================================

CREATE TABLE events (
    id bigint GENERATED ALWAYS AS IDENTITY,
    tenant_id int NOT NULL,
    severity smallint NOT NULL,
    created_at timestamptz NOT NULL,
    payload jsonb,
    PRIMARY KEY (id, created_at)          -- the partition key inside the PK
) PARTITION BY RANGE (created_at);

CREATE TABLE events_2026_10 PARTITION OF events
    FOR VALUES FROM ('2026-10-01') TO ('2026-11-01');
CREATE INDEX ON events USING BRIN (created_at);

-- hourly rollup, refreshed by a scheduled job
INSERT INTO events_hourly (tenant_id, hour, severity, cnt)
SELECT tenant_id, date_trunc('hour', created_at), severity, count(*)
FROM events WHERE created_at >= :from AND created_at < :to
GROUP BY 1, 2, 3
ON CONFLICT (tenant_id, hour, severity) DO UPDATE SET cnt = EXCLUDED.cnt;