---
title: Data Storage
sidebarTitle: Data Storage
---

Extensions get their own database tables and file storage locations. You define data models in Rust, and Spacedrive creates the tables automatically. You declare storage locations, and users choose where files go during installation.

Extensions use three storage layers: database tables for domain models, files in user-controlled locations for original data, and sidecars for derivative intelligence. Spacedrive handles sync, indexing, and search automatically.

#### Model Definition

```rust
#[model(
    table_name = "person",
    version = "1.0.0",
    sync_strategy = "shared"
)]
pub struct Person {
    #[primary_key]
    pub id: Uuid,
    pub name: String,
    #[indexed]
    pub email: Option<String>,
    #[metadata]
    pub metadata_id: i32,
}
```

#### Generated Schema

This Rust struct will generate the following SQL table:

```sql
CREATE TABLE ext_photos_person (
    id BLOB PRIMARY KEY,
    name TEXT NOT NULL,
    email TEXT,
    metadata_id INTEGER NOT NULL,
    FOREIGN KEY (metadata_id) REFERENCES user_metadata(id) ON DELETE CASCADE
);

CREATE INDEX idx_ext_photos_person_email ON ext_photos_person(email);
```

### Linking to Core Systems

Extension models are not isolated silos. They are deeply integrated with Spacedrive's core systems.

- **Tagging and Collections**: By adding the `#[metadata]` attribute to a field, your model is linked to the `user_metadata` table. This allows your custom data models to be tagged, added to collections, and searched just like any other file in Spacedrive.

- **Core Entities**: You can define foreign key relationships to core Spacedrive tables like `entries` or `content_identities`. This allows you to, for example, create an `Album` model that has a many-to-many relationship with photos (entries).

### Migrations

As you develop your extension, you will inevitably need to change your data models. The Spacedrive SDK includes a migration system to manage schema changes.

- **Migration Files**: You can provide SQL migration files with your extension (e.g., `v1.1.0_add_birthdate.sql`).
- **Automatic Execution**: When a user updates your extension, Spacedrive will automatically run the necessary migrations to bring their database schema up to date.

### Extension Locations

Extensions that create files must declare their storage locations. Users choose where the data goes during installation.

```json
{
  "extension_id": "com.spacedrive.email",
  "locations": [
    {
      "id": "email_archive",
      "name": "Email Archive",
      "purpose": "Store archived emails in .eml format",
      "suggested_path": "~/Spacedrive/Email Archive",
      "user_selects_path": true
    }
  ]
}
```

When you write files to this location, Spacedrive indexes them automatically. Query via the core entries table, not a custom cache.

```rust
// Write file to extension's location
let entry = ctx.write_file_to_location(
    "email_archive",
    "inbox/email.eml",
    email_data,
).await?;

// Core creates Entry automatically
// Query later via core VDFS
let emails = ctx.query_entries()
    .in_location("email_archive")
    .with_extension("eml")
    .execute().await?;
```

### What to Store Where

**Database tables:** Domain models, configuration, relationships
- EmailAccount, Transaction, Contact
- NOT file metadata (use core entries table)

**Files:** Original user data in standard formats
- .eml files, receipt PDFs, research papers
- User chooses where these go
- Spacedrive indexes automatically

**Sidecars:** Derivative analysis and intelligence
- OCR text, embeddings, extracted metadata
- Stored in library's sidecar directory
- Portable with your library
