> For the complete documentation index, see [llms.txt](https://docs.fractalworks.io/joule/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.fractalworks.io/joule/components/analytics/metrics-engine/create-metrics.md).

# Create metrics

## Objective

Metrics are defined as individual units referred to as a metric family. A metric family is an SQL query that defines metric calculations computed **within a continuous scheduled cycle**, making them available to all processors.

Here are some important areas to understand when creating metrics:

* The term metrics family refers the the set of metrics created under the  logical name provided.
* Access to a specific set of metrics is performed by a key look up.
* Metric storage is provided by SQL tables and therefore must match the query result.
* Metrics are indexed by key.
* Queries must follow the DuckDB SQL dialect, see DuckDB [documentation](https://duckdb.org/docs/sql/introduction) for a comprehensive guide.

In addition to the following example, you can read the tutorial on how to create your own metric.

{% content-ref url="/pages/owi6UI5k8WP319f0Xoy6" %}
[Create custom metrics](/joule/tutorials/analytics/create-custom-metrics.md)
{% endcontent-ref %}

## Example

This example configures a list of metrics to be computed.

```yaml
metrics engine:
  ...
  foreach metric compute:
    metrics:
      #
      # Metric family: BidMovingAverage
      #
      - name: BidMovingAverage
        #
        # Metric definition
        #
        metric key: symbol
        table definition: standardQuoteAnalyticsStream.BidMovingAverage 
        (symbol VARCHAR, avg_bid_min FLOAT, avg_bid_avg FLOAT,avg_bid_max FLOAT)
        query:
          SELECT symbol,
            MIN(bid) AS 'avg_bid_min',
            AVG(bid) AS 'avg_bid_avg',
            MAX(bid) AS 'avg_bid_max'
          FROM standardQuoteAnalyticsStream.quote
          WHERE
            ingestTime >= date_trunc('minutes',now() - INTERVAL 2 MINUTES) AND 
            ingestTime <= date_trunc('minutes',now())
          GROUP BY symbol
          ORDER BY 1;
        
        #
        # Truncate BidMovingAverage on startup
        #
        truncate on start: true
        
        #
        # Manage metric storage
        #
        compaction policy:
          frequency: 8
          time unit: HOURS
```

## Attributes schema

Each metric is defined using the below metrics.

<table><thead><tr><th width="188">Attribute</th><th width="301">Description</th><th width="157">Data Type</th><th data-type="checkbox">Required</th></tr></thead><tbody><tr><td>name</td><td>Unique metric family name</td><td>String</td><td>true</td></tr><tr><td>metric key</td><td>Unique key for the metric to be used to optimise query generation and processing</td><td>String</td><td>true</td></tr><tr><td>query</td><td>Metrics ANSI SQL query.<br><br>See <a href="https://duckdb.org/docs/sql/introduction">DuckDB SQL documentation</a></td><td>String</td><td>true</td></tr><tr><td>table definition</td><td>SQL table definition for the resulting metrics</td><td>String</td><td>true</td></tr><tr><td>truncate on start</td><td><p>Truncate metric data on restart. <em>Note</em> if you import metrics using the initialisation DSL element you will need to set this to false.</p><p><br>See <a href="/pages/vHMsc3LS0qAkvOmNjfCv">manage metrics</a> for detailed information</p></td><td>Boolean<br>Default: true</td><td>false</td></tr><tr><td>compaction policy</td><td><p>Manage the metric storage.</p><p><br>See <a href="/pages/vHMsc3LS0qAkvOmNjfCv">manage metrics</a> for detailed information</p></td><td></td><td>false</td></tr></tbody></table>
