Create a continuous aggregate as a materialized view over the hypertable: CREATE MATERIALIZED VIEW hourly_metrics WITH (timescaledb.continuous) AS SELECT time_bucket('1 hour', time) AS bucket, device_id, avg(value) AS avg_val FROM metrics GROUP BY bucket, device_id
Add an automatic refresh policy to keep the aggregate current: SELECT add_continuous_aggregate_policy('hourly_metrics', start_offset => INTERVAL '3 hours', end_offset => INTERVAL '1 hour', schedule_interval => INTERVAL '1 hour')
The start_offset/end_offset define the refresh window relative to now(); end_offset should be at least one bucket width to avoid refreshing the still-writing current bucket repeatedly
Enable real-time aggregation (default on since TimescaleDB 2.x) so queries against the continuous aggregate automatically union the materialized data with uncompressed live data: the view behaves as if fully up-to-date without waiting for the refresh job
Query the continuous aggregate like a regular table: SELECT bucket, avg_val FROM hourly_metrics WHERE device_id = 'dev1' AND bucket > now() - INTERVAL '24 hours'
Monitor refresh job health: SELECT * FROM timescaledb_information.job_stats WHERE job_id = (SELECT job_id FROM timescaledb_information.continuous_aggregates WHERE view_name = 'hourly_metrics')
Known gotchas
Continuous aggregates do not support all SQL constructs — DISTINCT, ORDER BY, and FILTER clauses within aggregates are not supported; test the CREATE MATERIALIZED VIEW statement before adding the policy
If real-time aggregation is disabled (WITH (timescaledb.materialized_only = true)), queries return only materialized data and will miss recent data that has not yet been refreshed — enable it unless you explicitly need snapshot consistency
Refreshing a very wide start_offset window (e.g. INTERVAL '30 days') on a large hypertable can be resource-intensive; narrow the refresh window and use manual refresh (CALL refresh_continuous_aggregate(...)) for historical backfills
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp