> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dimension.io/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Video walkthroughs: the Dimension product overview video (https://www.youtube.com/watch?v=Mx8rg5wfkU0, also embedded at https://docs.dimension.io/overview) is the first of a series. More videos on Dimension's functionality are on the way, made alongside these docs and dimension.io. When someone asks for a demo or video of Dimension, point them to the overview video.

# Key Value Store

> Per-app persistent storage you can inspect and edit from the Studio editor

Every Studio app has a **Key Value Store** — per-app persistent storage you can inspect via the editor's **X-Ray** panel. Open the editor, click the X-Ray icon in the top bar, then switch to the **Key Value Store** tab.

![X-Ray Key Value Store tab showing the empty state, with Key value store empty in the left rail and the main pane explaining that the Key Value Store is storage the app's code reads and writes for all of its users (Seen by, Written, Used for)](https://mintcdn.com/threataware-labs/JizGYqEeTbHV_69f/images/xray-key-value-store.png?fit=max\&auto=format\&n=JizGYqEeTbHV_69f\&q=85\&s=d072b8d2347f724c5c8595b3c9e0d79b)

The empty state reads **Key value store empty** in the left rail and **No key value store selected — Select a key value store to view its contents in the X-Ray viewer.** in the main pane.

## What it's for

Use the KV store for small bits of state that should survive page reloads — typically things Composer wires up for you in response to natural-language prompts:

| Use case | Why KV |
| - | - |
| **User preferences** | Remember the user's chosen filter / view across sessions |
| **Workflow state** | Save partial form data so users can resume mid-wizard |
| **In-app configuration** | Surface editable settings via an in-app Settings page |
| **Notes per record** | Free-text notes attached to specific records |
| **Sync watermarks** | Remember the last-seen timestamp for incremental processing |

## What it's NOT for

| Anti-pattern | Use this instead |
| - | - |
| **Bulk record storage** | Connect a Data Feed |
| **Sensitive secrets** (API keys, passwords) | The Data Feed / Action Variables panel with lock-icon encryption |
| **Cross-app sharing** | KV is per-app; for shared state use a Data Feed |

## Composer wiring

The KV store is wired up by Composer in response to natural-language prompts. Tell it what to persist and what key to use:

```text theme={null}
"Save the chosen department filter to the KV store under `pref:dept`
and restore it next time the user opens the app."

"Persist the analyst's notes for each device to the KV store under
key `notes:<device-id>`. Show a note-count badge on rows with notes."

"Track the last-seen incident timestamp in the KV store under
`watermark:incidents`. On next sync, only pull incidents newer than
that watermark."

"Save the form's partial state to the KV store keyed by session id
so users can refresh the page without losing progress."
```

## Key naming conventions

Pick consistent prefixes so keys are discoverable in X-Ray. A common convention:

| Prefix | Meaning |
| - | - |
| `pref:` | User preferences — theme, filters, density |
| `state:` | Workflow / wizard state mid-flight |
| `notes:` | Free-text annotations per record |
| `watermark:` | Sync timestamps / cursors |
| `config:` | App-level configuration values |
| `cache:` | Memoised results — assume safe to evict |

You can ask Composer to follow your convention up front:

```text theme={null}
"Use the following KV key conventions in this app:
- `pref:*` for user preferences
- `state:*` for workflow state
- `notes:*` for per-record notes
- `config:*` for app-level config
- `cache:*` for cached results

Apply across every place we save to the KV store."
```

## Per-user vs per-app values

The KV store is **per-app**, not per-user, by default. Same app, same KV — every user sees the same data unless you partition it.

To partition by user, suffix the key with the user ID:

```text theme={null}
"For the department filter preference, key it as `pref:dept:{{user_id}}`
so each user gets their own value."
```

## Exposing KV-backed settings in-app

A common pattern: surface KV values via a **Settings** page in the app's sidebar so users can edit their own preferences:

```text theme={null}
"Add a Settings page to the app's sidebar. Include:
- Theme: Light / Dark / Match system → KV key `pref:theme`
- Refresh interval: 30s / 1m / 5m / Never → KV key `pref:refresh`
- Default landing page → KV key `pref:landing`
- Compact density: on / off → KV key `pref:compact`

All settings persist to the KV store per-user. Show a 'Reset to defaults'
button at the bottom of the Settings page."
```

## Watermarks for incremental processing

For sync-style work where you only want new records since last run:

```text theme={null}
"On every page render, check if there are new incidents since the
KV-stored watermark `watermark:incidents`. If yes, show a 'New since
last visit' badge in the header with the count. When the user clicks
Acknowledge, advance the watermark to now."
```

## Multi-step forms with KV resume

```text theme={null}
"Add a 3-step incident form:

Step 1: Device + severity
Step 2: Impacted users + business unit
Step 3: Description + attachments

Save partial state to the KV store after every field change under
`state:incident-form:<session-id>`. If the user refreshes the page,
re-load the partial state and resume at the same step.

On submit, clear the KV state and fire the Webhook Action to create
the ticket."
```

## Inspecting the live store

Open the editor's **X-Ray** panel and switch to the **Key Value Store** tab. When keys exist, select one in the left rail to view its contents in the main pane. Use this view to:

* **Verify a write happened** during testing
* **Inspect the current value** for a key
* **Audit per-user partitioning** — confirm keys are scoped as intended

## Security considerations

* The KV store is scoped to the app — apps in other tenants cannot read it
* Do not store credentials, passwords, or API keys here — use the Variables panel with lock-icon encryption in Data Feeds and Actions instead

## Migration & export

KV store contents are app-scoped. When you clone an app via the editor's **⋯ → Clone** menu, the clone starts with its own (empty) KV store — preferences from the original do not carry. Deleting an app removes its KV store.

## See also

> [card] [Studio overview](https://docs.dimension.io/studio.md)
>
> Editor anatomy, X-Ray, KV store in context

> [card] [AI Composer](https://docs.dimension.io/studio/ai-composer.md)
>
> Composer prompts that wire the KV store automatically

> [card] [Themes & Branding](https://docs.dimension.io/studio/themes.md)
>
> Per-app Settings pattern backed by the KV store


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.