> For the complete documentation index, see [llms.txt](https://mercure-technologies.gitbook.io/xprem/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://mercure-technologies.gitbook.io/xprem/storage/overview.md).

# Overview

**xprem** supports multiple storage solutions for hosting your update assets: **Amazon S3**, **Google Cloud Storage (GCS)**, **Azure Blob Storage**, **S3 Compatible Storage like Cloudflare R2** and **Local File System**. This guide will help you set up your storage solution and configure your server to use it.

### Storage layout

Each update is stored under its application, branch, and runtime version.

```
appId/
└── branch/
    └── runtimeVersions/
        └── update/
```

This hierarchy isolates updates across applications, branches, and runtime versions.

### Object key prefix

S3, S3-compatible storage, GCS, and Azure Blob Storage support an optional key prefix. Set `BUCKET_KEY_PREFIX` to store all xprem objects below that prefix.

For example, `BUCKET_KEY_PREFIX=expo-open-ota` stores objects under `expo-open-ota/appId/...`.

Local Storage honors `BUCKET_KEY_PREFIX` too — objects are stored under `{LOCAL_BUCKET_BASE_PATH}/{prefix}/…`. Do not also include the prefix in the configured local storage path, or it is applied twice.

### Storage migrations

xprem runs a migration job against the configured storage. The job applies required storage changes and records each completed migration.

Migration state is stored in `.migrationhistory`. Do not delete or modify this file. It prevents completed migrations from running again.

### Inside an update directory

EOAS uploads the output of `expo export`: the JS bundles under `_expo/`, the `assets/` directory, `metadata.json`, and `expoConfig.json`.

Everything the server knows about an update beyond those files lives in the database. The `updates` table holds the platform, the git commit hash, the optional update message, the manifest UUID shown in the dashboard, and the completion state that makes an update visible to clients once its upload has been verified. Storage holds only the bundles and assets.

A rollback is stored as an update with no bundle and no assets. It participates in update resolution like any other update: the server serves it as a `rollBackToEmbedded` directive, and publishing after a rollback resumes normal delivery.

#### Update IDs

Each update directory is named after its publish timestamp in milliseconds. iOS and Android publish separate directories; a platform digit is appended to the timestamp so simultaneous publishes never collide. The UUID shown in the dashboard is the manifest `id`; updates imported from a v2 deployment derive it deterministically from their export metadata.

### Caching

The server caches manifests and update resolutions to avoid repeated storage and database lookups. Configure caching to keep resolution fast as update history grows. See [Caching overview](/xprem/caching/overview.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://mercure-technologies.gitbook.io/xprem/storage/overview.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
