---
title: The data island
description: Refresh rewrites exactly one block of JSON inside the file, which is why your design survives every refresh untouched.
updated: 2026-08-04
---

The **data island** is the one block inside a published dashboard that holds its
numbers:

```html
<script type="application/json" id="dashies-data">
{ "version": 4, "updated_at": "2026-08-05T09:00:00Z", "datasets": { } }
</script>
```

Everything a viewer sees is computed from it. The runtime never fetches anything
else, except for one case covered below.

## Why this matters more than it sounds like it should

The island is the reason refresh is safe.

On each scheduled run, the scheduler re-runs the manifest's SQL, then reads the
stored file and splits it into three parts: everything up to and including the
opening `<script ... id="dashies-data">` tag, the JSON between the tags, and
everything from `</script>` onward. It replaces the middle part and writes the
file back.

**The first and third parts are never touched.** Not reformatted, not
regenerated, not re-rendered by a model. Your layout, your CSS, your copy, your
logo, the wording of a footnote you argued about: byte-for-byte identical after
every refresh, forever.

That is the property that makes an AI-authored dashboard viable as a long-lived
artifact rather than a one-off. You are not asking a model to reproduce your
design every day and hoping it does.

## What the island carries

A `version: 4` island is a **report**: one island holding up to eight named
datasets, each independently materialized. Alongside `version` it carries an
`updated_at` timestamp, which is what a slot marked `data-dash="updated-at"`
displays, and optional dashboard-level formatting defaults.

Each dataset section names its mode and then carries whatever that mode needs:
pre-aggregated rows, a precomputed lattice with its rolled-up flags, a row-level
schema plus rows, bounded domains for filters, or a pointer to an offloaded
object. [Datasets and the four modes](/concepts/dataset-modes) is where those
differences live.

## Island versions, and why a dashboard never changes version

There have been four island contracts, and all four are still live:

| Version | What it carries |
|---|---|
| 1 | a pre-aggregated additive cube, re-summed in the browser |
| 2 | row-level rows, re-queried in the browser with DuckDB-WASM |
| 3 | a precomputed grain lattice, looked up in the browser |
| 4 | up to eight named datasets, each independently one of the above |

The important rule is what refresh does with them: **the scheduler writes back
whichever version the dashboard already is.** It never migrates an island. A
dashboard published against version 1 keeps refreshing on version 1 for as long
as it exists, and a version 1 dashboard cannot silently become a version 2 one.

At boot the runtime normalizes every island into the same view, treating a
version 1, 2, or 3 island as a report with exactly one dataset called `main`. So
one code path serves all four contracts, and the older ones do not decay.

Everything published from a spec today is version 4. You will only meet the
earlier numbers if you are looking at a dashboard published before the report
format, or reading an error message that names one.

## The one thing that is not in the island

A `rows` dataset can be **offloaded to Parquet** instead of inlined. Its island
section then carries a pointer rather than the data, and the runtime range-reads
the object over the network, pulling only the parts of the file it needs.

Two consequences worth knowing:

- Such a dataset publishes **empty on purpose**, and its tiles read "Updating"
  until the first refresh lands the object. That is deliberate: showing a
  truncated sample as though it were the whole truth is exactly the class of
  silent wrongness this format exists to prevent.
- Refresh for that dashboard becomes **asynchronous**. The run is queued and
  completes minutes later rather than immediately.

Everything else, in every mode, rides inside the island.

## Two clocks

A refresh writes no version-history row and deliberately does not move the
dashboard's `updated_at` timestamp. So:

- **Edited** means the last time a person changed the dashboard. It is what the
  dashboard card shows and what version history lists.
- **Refreshed** means the last time the numbers moved. It lives on the Schedules
  page and in the run history.

A dashboard that refreshes every hour can show an "Edited" date from three weeks
ago, and that is correct. Keeping the two apart is why your dashboard list does
not reshuffle itself every fifteen minutes, why thumbnails are not re-rendered
constantly, and why your activity feed is not filled with events nobody caused.

## Next

[The runtime](/concepts/runtime) is the other half of the served page.
