Skip to main content
Graph Node provides built-in aggregation capabilities for timeseries data, enabling efficient storage and querying of metrics, statistics, and time-bucketed analytics. This feature is available from spec version 1.1.0 onwards.

Overview

Aggregations are declared in your subgraph schema through two complementary types:
  1. Timeseries type: Stores raw data points with timestamps
  2. Aggregation type: Defines how raw data is aggregated over time intervals
Graph Node automatically computes and maintains aggregations as new data arrives, rolling up statistics for hourly and daily intervals.

Defining Timeseries

A timeseries entity stores individual data points with automatic timestamps:
required
Marks the type as a timeseries. These entities are immutable and append-only.
Int8!
required
Automatically set by Graph Node in insertion order. Must be of type Int8.
Timestamp!
required
Automatically set by Graph Node to the current block timestamp. User-provided values are silently overridden.

Timeseries Characteristics

  • Immutable: Once created, timeseries entities cannot be updated or deleted
  • Automatic IDs: The id field is set automatically in ascending order
  • Automatic timestamps: The timestamp field is always set to block timestamp
  • Efficient storage: Optimized for append-only operations

Defining Aggregations

Aggregations compute statistics over timeseries data at specified time intervals:
required
Marks the type as an aggregation with two required arguments:
  • intervals: Array of time intervals ("hour" or "day")
  • source: Name of the timeseries type to aggregate
Int8!
required
Automatically set by Graph Node. Set to the id of one of the source data points (unspecified which).
Timestamp!
required
Automatically set to the beginning of the aggregation time interval.

Aggregation Functions

The @aggregate directive supports these functions:
Aggregation Function
Sum of all values in the interval.
Aggregation Function
Number of data points in the interval.
Aggregation Function
Minimum value in the interval.
Aggregation Function
Maximum value in the interval.
Aggregation Function
First value in the interval (by timeseries id ordering).
Aggregation Function
Last value in the interval (by timeseries id ordering).

Dimensions

Dimensions are non-aggregated fields used to group data. They enable multi-dimensional aggregations:
How dimensions work:
  • Fields without @aggregate are dimensions
  • Each unique combination of dimension values creates a separate aggregation series
  • In the example above, each token gets its own hourly and daily statistics

Cumulative Aggregations

By default, aggregations compute values for each time interval independently. Cumulative aggregations compute running totals across all intervals:
Boolean
default:"false"
When true, aggregates over the entire timeseries up to the end of the current interval.

Aggregation Expressions

The arg parameter can be a field name or a SQL expression:

Supported Expression Syntax

Expressions use SQL syntax with these supported features:
  • Arithmetic: +, -, *, /, %, ^
  • Comparison: =, !=, <, <=, >, >=
  • Logical: and, or, not
  • Other: is [not] {null|true|false}, is [not] distinct from
  • abs(x): Absolute value
  • ceil(x), ceiling(x): Round up
  • floor(x): Round down
  • div(x, y): Integer division
  • mod(x, y): Modulo
  • power(x, y): Exponentiation
  • gcd(x, y): Greatest common divisor
  • lcm(x, y): Least common multiple
  • sign(x): Sign (-1, 0, or 1)
  • coalesce(x, y, ...): First non-null value
  • nullif(x, y): NULL if x equals y
  • greatest(x, y, ...): Maximum value
  • least(x, y, ...): Minimum value
  • case when ... then ... else ... end: Conditional expression

Querying Aggregations

Graph Node creates top-level query fields for each aggregation:

Basic Aggregation Query

Enum
required
Time interval to query: "hour" or "day" (must match intervals defined in schema).
Enum
default:"exclude"
Whether to include the current, partially filled bucket:
  • exclude: Only return completed, rolled-up buckets (default)
  • include: Also return in-progress bucket computed on-the-fly

Filtering Aggregations

Filter by dimensions and timestamp ranges:

Available Timestamp Filters

String
Exact timestamp match (microseconds since epoch).
String
Greater than or equal to timestamp.
String
Greater than timestamp.
String
Less than or equal to timestamp.
String
Less than timestamp.
[String]
Timestamp in list.
Timestamps are strings containing microseconds since Unix epoch.Example: "1704164640000000" = 2024-01-02T03:04:00ZConvert from seconds: seconds * 1000000

Current Bucket

By default, aggregation queries return only completed, rolled-up buckets. Setting current: include adds the in-progress bucket:
How it works:
  • exclude: Only returns buckets whose time interval has ended and been rolled up
  • include: Adds one additional bucket computed on-the-fly from unrolled source data
  • The current bucket covers from the last completed bucket to the most recent data point

Nested Aggregation Queries

The current argument works on nested aggregation fields:
Current bucket support for nested fields is only available when the field references a single aggregation type. It’s not supported for aggregations accessed through interfaces with multiple implementations.

Complete Example

Here’s a comprehensive example showing timeseries and aggregations for DEX trading data:
schema.graphql

Query Examples

Sorting Behavior

Aggregations have a default sort order:
  • Sorted by timestamp and id in descending order by default
  • Returns most recent buckets first
  • Can be overridden with orderBy and orderDirection

Best Practices

  1. Choose appropriate intervals: Use hourly for recent data, daily for historical trends
  2. Use dimensions wisely: Each dimension combination creates separate aggregation series
  3. Leverage cumulative aggregations: Useful for running totals and lifetime metrics
  4. Filter by timestamp: Always specify timestamp ranges to limit data scanned
  5. Monitor aggregation lag: Current buckets may not reflect all recent data until rollup completes
  6. Use expressions for computed metrics: Calculate derived values at aggregation time

Next Steps