# Storage

Keep values between runs, each under its own key.

## Do things in Storage

Add a **Storage** step and choose an **Operation**. Choose the row to see the fields of each.

- [Storage Operation](https://docs.gorunner.io/apps/storage#fields-f-operate): Get value · Set value · Append to list · Increment number · Delete key · Key exists?

Later steps read a step’s output by its name: see [Use data from earlier steps](https://docs.gorunner.io/build/use-data-from-earlier-steps).

## Limits

- Values are kept for the workspace, in the database. **Test step** uses its own copy, apart from published runs.
- One value holds at most 16 MB.

Not in your list? See [When an app isn’t here](https://docs.gorunner.io/apps/when-an-app-isnt-here#q-not-in-list).

## For developers

In the API, which calls apps pieces, Storage is `pieceId: "store"` with `actionId: "operate"`, set by `operation`. [Get an app](https://docs.gorunner.io/api/apps/get-app) returns every field.

It can change something outside the run (`writes_external`). See [How versions and side effects work](https://docs.gorunner.io/apps#q-versions).

### Storage › Storage Operation

Read or write a value in the persistent store. The Test step uses its own copy of the data, separate from published runs.

### Get value

- **Key · Required**: The storage key.
- **Default Value · Optional**: Returned when the key does not exist, instead of null.

### Set value

- **Key · Required**: The storage key.
- **Value · Optional**: Value to store (any JSON). Text that is valid JSON (42, true, {…}) is stored as that value; put it in quotes to keep it as text. Append: a stored value that is not a list becomes the list's first element.
- **Expire After (seconds) · Optional**: Optional expiry; 0 = never expire. Default: 0.

### Append to list

- **Key · Required**: The storage key.
- **Value · Optional**: Value to store (any JSON). Text that is valid JSON (42, true, {…}) is stored as that value; put it in quotes to keep it as text. Append: a stored value that is not a list becomes the list's first element.
- **Add Each Item · Optional**: When Value is a list, add each of its items rather than the list itself as one element. Off by default.

### Increment number

- **Key · Required**: The storage key.
- **Amount · Optional**: How much to add (can be negative). Default: 1.

### Delete key and Key exists?

- **Key · Required**: The storage key.

Source: https://docs.gorunner.io/apps/storage
