# Object Metrics & Freshness

Object-level metrics collect information about tables and views as a whole — row counts, schema metadata, definition hashes, and data freshness.

![monitor-chart-object](https://3453272330-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M93cpHl7B7NPZlDrubS%2Fuploads%2Fgit-blob-11a65f24aae1dace1040937e45512a108988f356%2Fmonitor-chart-object.png?alt=media)

## Object-Level Metrics

| Key         | Type | Description                                                                                                                                                                     |
| ----------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `metadata`  | bool | Collect schema information — column names, types, and table type. Enables [schema change detection](https://docs.slingdata.io/sling-platform/platform/monitors/schema-changes). |
| `row_count` | bool | Count the total number of rows via `COUNT(*)`. Also used as a baseline for [anomaly detection](https://docs.slingdata.io/sling-platform/platform/monitors/anomaly-detection).   |
| `body_md5`  | bool | Track the MD5 hash of view or stored procedure definitions to detect code changes. Not applicable to regular tables.                                                            |

```yaml
objects:
  public.users:
    metadata: true
    row_count: true

  public.my_view:
    metadata: true
    body_md5: true
```

## Alert on Change

Use `alert_on_change` to specify which types of changes should trigger alerts:

| Change Type | Description                          |
| ----------- | ------------------------------------ |
| `name`      | Object was renamed                   |
| `type`      | Object type changed                  |
| `timestamp` | Last modified timestamp changed      |
| `size`      | Object size changed                  |
| `body`      | View or procedure definition changed |
| `count`     | Row count changed                    |

```yaml
objects:
  public.users:
    metadata: true
    row_count: true
    alert_on_change:
      - count
      - size
      - timestamp
```

## Data Freshness

Freshness monitoring detects when data becomes stale. Combine `freshness_column` with `freshness_threshold` to track data age and receive alerts when tables fall behind their expected update schedule.

### How It Works

When `freshness_column` is set, Sling queries `MAX(freshness_column)` to determine the timestamp of the most recent data. If the result is older than `freshness_threshold`, a **data\_stale** event is fired.

If only `freshness_threshold` is set without `freshness_column`, Sling falls back to the object's metadata timestamp (last DDL or modification time). This is less precise for tables that receive `INSERT` operations without schema changes.

### Duration Format

Thresholds use duration strings composed of one or more units:

| Unit | Meaning | Example            |
| ---- | ------- | ------------------ |
| `d`  | Days    | `7d` = 7 days      |
| `h`  | Hours   | `24h` = 24 hours   |
| `m`  | Minutes | `30m` = 30 minutes |
| `s`  | Seconds | `60s` = 60 seconds |

Units can be combined: `"1d12h"` = 1 day and 12 hours, `"1h30m"` = 1 hour and 30 minutes.

### Basic Freshness Check

```yaml
objects:
  public.orders:
    freshness_column: created_at
    freshness_threshold: "12h"

  public.users:
    freshness_column: updated_at
    freshness_threshold: "24h"
```

### Freshness in Defaults

Apply a default freshness configuration to all objects, then override per table as needed:

```yaml
defaults:
  freshness_column: updated_at
  freshness_threshold: "24h"

objects:
  public.users: {}               # uses default (24h on updated_at)
  public.orders:
    freshness_column: created_at  # different column
    freshness_threshold: "6h"     # tighter SLA
```

{% hint style="warning" %}
For accurate freshness detection, set `freshness_column` to a timestamp column that is updated when new data arrives. Without it, Sling relies on metadata timestamps which may not reflect actual data changes.
{% endhint %}

## Complete Example

```yaml
connection: MY_POSTGRES

defaults:
  metadata: true
  row_count: true

objects:
  public.users:
    freshness_column: updated_at
    freshness_threshold: "24h"
    alert_on_change:
      - count
      - timestamp

  public.orders:
    freshness_column: created_at
    freshness_threshold: "6h"
    alert_on_change:
      - count

  public.products:
    row_count: true
    body_md5: false

  public.daily_report_view:
    metadata: true
    body_md5: true
    alert_on_change:
      - body
```
