Windows

Velocity and aggregation windows: count, sum, avg, ratio, min, and max over an entity's recent history.

A window computes a per-entity aggregate over a recent span of time — "how many charges on this card in the last hour", "the average amount over the last day" — and exposes it as a derived column that a rule then compares with an op and value.

Shared window fields

Every window leaf nests under a window: key and shares this core:

FieldPurpose
entity_fieldThe entity to group history by, e.g. card_token.
functionOne of count, sum, avg, ratio, min, max.
duration_secondsHow far back the window reaches.
opComparison operator applied to the aggregate.
valueThe threshold to compare against.

Some functions need extra fields:

FunctionExtra field(s)
sum, avgsum_field — the numeric field to aggregate.
rationumerator_field and denominator_field.
min, maxvalue_field — the numeric field to take the min/max of.

The six functions

Each block below is copied verbatim from the canonical sample file.

count — how many events for this entity in the window?

- window:
    entity_field: card_token
    function: count
    duration_seconds: 3600
    op: gt
    value: 3

sum — does the total of a field exceed a threshold?

- window:
    entity_field: card_token
    function: sum
    sum_field: amount
    duration_seconds: 3600
    op: gt
    value: 1000

avg — is the average of a field above a threshold?

- window:
    entity_field: card_token
    function: avg
    sum_field: amount
    duration_seconds: 3600
    op: gt
    value: 100

ratio — is one field's total a large fraction of another's?

- window:
    entity_field: card_token
    function: ratio
    numerator_field: amount
    denominator_field: available_credit
    duration_seconds: 3600
    op: gt
    value: 0.5

min — is the smallest value in the window below a floor?

- window:
    entity_field: card_token
    function: min
    value_field: amount
    duration_seconds: 3600
    op: lt
    value: 10

max — is the largest value in the window above a ceiling?

- window:
    entity_field: card_token
    function: max
    value_field: amount
    duration_seconds: 3600
    op: gt
    value: 10000

Batch semantics

BlazeRules evaluates one batch at a time, and windows are computed across batches:

  1. Read the entity history committed by earlier batches.
  2. Inject the window aggregates as derived columns onto the current batch.
  3. Evaluate the current batch's rules against those columns.
  4. Write the current batch into the entity history for future batches.
flowchart LR
  A[Read prior history] --> B[Inject window columns]
  B --> C[Evaluate current batch]
  C --> D[Write current batch to history]

This means a record in batch N sees the state committed by earlier batches. By default, repeated rows for the same entity within a single batch do not see each other's earlier rows in that same batch.

🚧

Window state is in-process

Window history lives in the engine process. It is not durable and not shared across processes. For window-heavy streaming workloads, keep entity/partition affinity so each entity's events route to the same process. If you need durable, distributed, exactly-once windows, run BlazeRules as an operator inside a stream processor such as Flink or Kafka Streams.

Where to go next