generate_series(..., now(), interval ...) with a materialized view to express periodic, time-driven logic — similar in spirit to a cron job, but expressed entirely in SQL.
The materialized view is kept up to date incrementally by RisingWave. Each time now() advances past the next interval boundary, a new timestamp row is appended automatically, which can drive downstream computations.
For the function constraints and full syntax, see generate_series — advanced usage.
Example: rolling 7-day window updated every 15 minutes
Choose astart timestamp close to the current date to limit the initial backfill. On first creation, RisingWave generates all ticks from start to now() — a distant past date results in a large number of rows to enumerate upfront.
generate_series(..., now(), ...) call produces a new tick each time now() advances by 15 minutes. The WHERE clause acts as a temporal filter that keeps the view window rolling — rows older than 7 days are automatically retracted.
What this pattern is good for
- Generating periodic time buckets (e.g., 15-minute, hourly, or daily slots).
- Driving time-windowed aggregations that should always cover the last N days.
- Creating a lightweight “heartbeat” or timer table that other materialized views can join against.
Limitations
This pattern is not a general cron replacement:- It does not schedule arbitrary SQL statements, DDL, DML, or stored functions at fixed wall-clock times.
- The materialized view reacts to
now()advancing; it cannot trigger external side-effects or notify other systems on its own. - For general task scheduling (e.g., running a stored procedure every hour), use a dedicated scheduler such as
pg_cron, Airflow, or a similar tool.
Related topics
- Temporal filters — Filter streaming data based on
NOW()to implement rolling windows and TTL - Time windows — Tumbling, hopping, and session windows for time-based aggregations
- generate_series — Full reference for the
generate_seriesfunction - What is a materialized view? — How RisingWave maintains MVs incrementally