# Where your data lives

# Where your data lives

Find, browse and query what your devices send to the cloud. It all lands in
**Reservoir**, in one of four tables chosen by what the channel *is*, not which
input sent it.

| Table | What's in it | Example channel |
|---|---|---|
| `scalars` | Numeric and text channel data from your devices. | `/rig/pressure` |
| `video` | Camera footage and other video recordings. | `/cam/front` |
| `geometry` | Point clouds and other captures drawn in a 3D scene. | `/lidar/points` |
| `waveforms` | Spectra, histograms and other value series over an axis. | `/arm/joints/position` |

Other tables:

| Table | What's in it |
|---|---|
| `trellis_measurements` | one row per judged measurement of a test run |
| `trellis_verdicts` | interlock trips, check verdicts and run outcomes |
| `trellis_commands` | commands Trellis sent to outputs |
| `occurrences` | marks and alarms — see below |

`occurrences` has one row per event: a mark's instant, a span's start and end,
an alarm firing. Each row says who set up the detector (`origin`: a deployed
setup, a run's recipe, a Pipelines rule, a notebook, or a person) and what to
open to edit it. An alarm row also has `severity` and `notify` (who to tell;
empty on a close and on a shelved firing). An interlock trip is never here; it
is a `trellis_verdicts` row.

**Rollups** and the **Search index** are built for you. They appear in the
table list so you can see their size.

## Browse it

Open **Reservoir → Explore**. Pick a table, then a channel, on the left. You
see rows, footage or a 3D preview, depending on the table.

The SQL strip above already holds the query for your selection. Edit it and
press **Run** to ask anything else. The URL keeps the table, channel and query,
so you can share the exact view as a link.

## Query it

Every table has three shared columns: `path` (the channel), `device_id`, and
`event_time` (the source clock, in UTC). Use them to line tables up: the same
`path` and `event_time` in `geometry` and `video` is the same instant.

Recent samples from one channel:

```sql
SELECT event_time, f64
FROM scalars
WHERE path = '/rig/pressure'
ORDER BY event_time DESC
LIMIT 100
```

`scalars` holds one value per row, in the column for its type: `f64`, `i64`,
`bool`, `text` or `bytes`. `producer` says which input or derived step sent it.
`time_basis` says whether `event_time` is the sensor's clock or the arrival
time.

Which channels exist, and how much of each:

```sql
SELECT path, count(*) AS samples
FROM scalars
GROUP BY path
ORDER BY samples DESC
```

A waveform row is a whole array at one instant: `values`, plus its axis —
`axis_name`, `axis_unit`, and either `axis_labels` for named slots like
`J1`…`J6` or `axis_start`/`axis_step` for evenly spaced bins.

```sql
SELECT event_time, axis_labels, values
FROM waveforms
WHERE path = '/arm/joints/position'
ORDER BY event_time DESC
LIMIT 10
```

Footage has one row per chunk. `dur_us` is the chunk length in microseconds;
`codec` is how it was encoded:

```sql
SELECT event_time, dur_us, codec
FROM video
WHERE path = '/cam/front'
ORDER BY event_time DESC
LIMIT 20
```

Geometry rows have `archetype` (what to draw: `points3d`, `boxes3d`,
`segmentation_image`, `transform3d`, …) and `frame_id` (the coordinate frame
the capture belongs to).

> **Note:** A channel whose input never said what it is lands in the `bytes`
> column of `scalars`. You can still query and replay it, but it gets no chart,
> player or 3D preview. Set the channel's kind where it is sent, and the next
> sample lands in the right table.

Old data is deleted on the schedule you set: see [Retention](https://phloem.ai/docs/workspace/retention/).
