---
title: Unified Addressing
sidebarTitle: Addressing
---

Spacedrive uses a unified addressing scheme that works seamlessly across local devices, cloud storage, and content-addressed files. Every file has a single, intuitive URI that tells you exactly where it lives - whether it's on your laptop, in S3, or stored by content hash.

**Local devices:**

```
local://jamies-macbook/Users/james/Documents/report.pdf
```

**Cloud storage:**

```
s3://my-bucket/photos/2024/vacation.jpg
```

**Content addressed:**

```
content://550e8400-e29b-41d4-a716-446655440000
```

The same URI format works across all storage types, matching industry-standard cloud tools like AWS CLI and gsutil. Copy a path from Spacedrive and paste it directly into your terminal.

## URI Formats

### Cloud Storage - Service-Native URIs

Cloud files use the same URI format as their native tools:

```
s3://my-bucket/photos/2024/vacation/IMG_0123.jpg
gdrive://My Drive/Documents/Contract 2024.pdf
onedrive://Documents/Budget Spreadsheet.xlsx
dropbox://Apps/Spacedrive/backup-2024-10.zip
azblob://container/data/export-2024.csv
gcs://my-bucket/logs/application-2024-10-15.log
```

**Pattern**: `{service}://{identifier}/{path}`

Where:

- `{service}`: Cloud service type (s3, gdrive, onedrive, dropbox, azblob, gcs, b2, wasabi, spaces)
- `{identifier}`: Service-specific root (bucket name, folder, container)
- `{path}`: Path within the service

<Tip>
	These URIs match AWS CLI, gsutil, and other cloud tools exactly. Copy a path
	from Spacedrive and paste it into `aws s3 cp` without modification.
</Tip>

### Local Files - Device-Aware URIs

Local files include the device name for multi-device clarity:

```
local://jamies-macbook/Users/james/Documents/report.pdf
local://home-server/mnt/storage/media/movies/Inception.mkv
local://work-desktop/C:/Projects/spacedrive/README.md
```

**Pattern**: `local://{device-slug}/{path}`

Where:

- `{device-slug}`: URL-safe device identifier (generated from device name)
- `{path}`: Absolute path on that device

<Note>
	Device slugs are generated automatically from your device name by converting
	to lowercase and replacing non-alphanumeric characters with hyphens. "Jamie's
	MacBook Pro" becomes `jamies-macbook-pro`.
</Note>

### Content-Addressed Files

Content URIs reference files by their content hash, independent of location:

```
content://550e8400-e29b-41d4-a716-446655440000
```

**Pattern**: `content://{uuid}`

This enables location-independent operations. The same photo stored on multiple devices and in cloud storage shares one content URI. Spacedrive resolves it to the most efficient available location.

## Device Slug System

Spacedrive generates URL-safe slugs from device names to create stable, human-readable URIs.

### Slug Generation

```rust
// Convert device name to slug
let name = "Jamie's MacBook Pro";
let slug = name.to_lowercase()
    .chars()
    .map(|c| if c.is_alphanumeric() { c } else { '-' })
    .collect::<String>()
    .trim_matches('-');
// Result: "jamies-macbook-pro"
```

Examples:

- "Jamie's MacBook" → `jamies-macbook`
- "Home Server 2024" → `home-server-2024`
- "DESKTOP-ABC123" → `desktop-abc123`

### Slug Uniqueness

Each device's slug must be unique within your Spacedrive network. The database enforces this with a unique constraint on the `slug` column. If you try to add a device with a duplicate name, you'll need to rename one device.

<Warning>
	If two devices have the same name (e.g., both "MacBook Pro"), you must give
	them distinct names before they can sync. Spacedrive will warn you during
	pairing.
</Warning>

### Resolution

When parsing a `local://` URI, Spacedrive looks up the device by slug:

```rust
// Parse: local://jamies-macbook/Users/james/file.txt
let device_id = device_manager.resolve_by_slug("jamies-macbook")?;
let path = PathBuf::from("/Users/james/file.txt");
```

Currently, slug resolution only works for the current device. Remote device paths use UUIDs internally but display with slugs for user-facing operations.

## How It Works

Spacedrive maintains user-friendly URIs in the display layer while using efficient internal identifiers for operations.

### User-Facing Display

```rust
// Display path to user
let display_uri = sd_path.display_with_context(&context).await;
println!("{}", display_uri);
// Output: "s3://media-bucket/videos/demo.mp4"
```

### Internal Representation

```rust
pub enum SdPath {
    Physical {
        device_slug: String,       // URL-safe device identifier
        path: PathBuf,
    },
    Cloud {
        service: CloudServiceType, // Cloud service type (S3, GoogleDrive, etc.)
        identifier: String,        // Service identifier (bucket, drive name, etc.)
        path: String,              // Path within the service
    },
    Content {
        content_id: Uuid,
    },
}
```

### Resolution Flow

```
User Input:     s3://my-bucket/file.jpg
                     ↓
Parse Scheme:   "s3" → CloudServiceType::S3
                     ↓
Parse Identity: identifier = "my-bucket"
                path = "file.jpg"
                     ↓
Create SdPath:  SdPath::Cloud { service: S3, identifier: "my-bucket", path: "file.jpg" }
                     ↓
Find Volume:    VolumeManager::find_cloud_volume(S3, "my-bucket")
                     ↓
Mount Cache:    "s3://my-bucket" → VolumeFingerprint (O(1) lookup)
                     ↓
Operations:     Use volume backend for I/O operations
```

The service and identifier are stored directly in the `SdPath`, making cloud paths self-contained. The VolumeManager maintains a mount point cache for fast volume lookups.

## Cloud Service Schemes

Spacedrive supports these cloud URI schemes:

| Service              | Scheme        | Example                                |
| -------------------- | ------------- | -------------------------------------- |
| Amazon S3            | `s3://`       | `s3://my-bucket/path/file.jpg`         |
| Google Drive         | `gdrive://`   | `gdrive://My Drive/Documents/file.pdf` |
| OneDrive             | `onedrive://` | `onedrive://Documents/file.xlsx`       |
| Dropbox              | `dropbox://`  | `dropbox://Apps/Spacedrive/file.zip`   |
| Azure Blob           | `azblob://`   | `azblob://container/data/file.csv`     |
| Google Cloud Storage | `gcs://`      | `gcs://bucket/logs/file.log`           |
| Backblaze B2         | `b2://`       | `b2://bucket/backups/file.tar`         |
| Wasabi               | `wasabi://`   | `wasabi://bucket/archive/file.zip`     |
| DigitalOcean Spaces  | `spaces://`   | `spaces://space/assets/file.png`       |

S3-compatible services (MinIO, Cloudflare R2, Wasabi, etc.) use the `s3://` scheme with custom endpoints.

## Parsing URIs

### From User Input

```rust
use sd_core::domain::addressing::SdPath;

// Parse cloud URI
let path = SdPath::from_uri_with_context(
    "s3://my-bucket/photos/vacation.jpg",
    &context
).await?;

// Parse local URI
let path = SdPath::from_uri_with_context(
    "local://jamies-macbook/Users/james/file.txt",
    &context
).await?;

// Parse content URI
let path = SdPath::from_uri_with_context(
    "content://550e8400-e29b-41d4-a716-446655440000",
    &context
).await?;
```

### Error Handling

```rust
match SdPath::from_uri_with_context(uri, &context).await {
    Ok(path) => { /* Use path */ }
    Err(SdPathParseError::UnknownScheme) => {
        // Invalid URI scheme
    }
    Err(SdPathParseError::VolumeNotFound) => {
        // Cloud volume doesn't exist or isn't added
    }
    Err(SdPathParseError::DeviceNotFound) => {
        // Device slug not found
    }
    Err(_) => {
        // Other parse errors
    }
}
```

## CLI Usage

The unified addressing scheme makes CLI operations intuitive:

```bash
# Copy from Google Drive to S3
sd cp gdrive://Work/report.pdf s3://backup/documents/

# List files on remote device
sd ls local://home-server/mnt/media/movies/

# Search across all storage
sd search "*.mp4"
# Results show unified URIs:
#   gdrive://Videos/vacation.mp4
#   s3://media/clips/demo.mp4
#   local://macbook/Users/james/Downloads/tutorial.mp4

# Sync local to cloud
sd sync local://macbook/Photos/ s3://backup/photos/
```

## Code Examples

### File Operations

```rust
// Copy from cloud to local
let src = SdPath::from_uri_with_context(
    "gdrive://Work/presentation.pptx",
    &context
).await?;

let dst = SdPath::from_uri_with_context(
    "local://macbook/Desktop/",
    &context
).await?;

copy_action.execute(src, dst).await?;
```

### Display Paths

```rust
// Get user-friendly URI for display
let uri = sd_path.display_with_context(&context).await;
println!("File location: {}", uri);

// Examples:
// "s3://media-bucket/videos/demo.mp4"
// "local://jamies-macbook/Users/james/file.txt"
// "content://550e8400-e29b-41d4-a716-446655440000"
```

### Building Paths

```rust
// Create cloud path
let path = SdPath::Cloud {
    service: CloudServiceType::S3,
    identifier: "my-bucket".to_string(),
    path: "photos/vacation.jpg".to_string(),
};

// Create local path
let path = SdPath::Physical {
    device_slug: "jamies-macbook".to_string(),
    path: PathBuf::from("/Users/james/file.txt"),
};

// Create content path
let path = SdPath::Content {
    content_id: Uuid::new_v4(),
};
```

## Industry Standard Alignment

Spacedrive's addressing matches industry tools:

**AWS CLI**:

```bash
aws s3 cp s3://bucket/file.jpg local-file.jpg
sd cp s3://bucket/file.jpg local://macbook/Desktop/file.jpg
```

**gsutil**:

```bash
gsutil cp gs://bucket/file.jpg local-file.jpg
sd cp gcs://bucket/file.jpg local://macbook/Desktop/file.jpg
```

**Azure CLI**:

```bash
az storage blob download --container container --name file.csv
sd cp azblob://container/file.csv local://macbook/Desktop/file.csv
```

The alignment eliminates context switching between tools. URIs copy-paste directly between Spacedrive and native cloud tools.

## Benefits

### Self-Documenting

URIs clearly show where files live:

```
s3://media-bucket/photos/vacation.jpg
     ↑           ↑
   Service    Bucket
```

No need to remember which cloud provider or check internal IDs.

### Cross-Storage Operations

Operations work identically across storage types:

```rust
// Same API for all storage backends
copy(src, dst).await?;

// Works for any combination:
// - local → local
// - local → cloud
// - cloud → cloud
// - cloud → local
```

### Location Independence

Content URIs enable operations without knowing physical location:

```rust
// Reference by content, not location
let file = SdPath::Content { content_id };

// Spacedrive finds the best location:
// - Fastest device (SSD vs HDD)
// - Lowest cost (local vs cloud egress)
// - Highest availability
```

## Limitations

### Device Slug Resolution

Device slug resolution works for all devices in the library through an in-memory cache. When a library opens, all device slugs are loaded into the DeviceManager's cache, enabling instant O(1) resolution for any device whether online or offline.

The cache updates automatically when:

- A library is opened (loads all devices from database)
- New devices pair and sync
- The library closes (cache is cleared)

This means `local://` URIs can reference any device in the library, not just the current device.

### Cloud Volume Lookup

Cloud volumes use an O(1) mount point cache for fast lookups. The cache maps mount point strings (e.g., `"s3://my-bucket"`) to volume fingerprints. For volumes added before the cache was implemented, a linear scan serves as a fallback.

### Slug Collisions

If two devices would generate the same slug, the second device must be renamed. There's no automatic disambiguation.

## Best Practices

### URI Display

Use `display()` to convert SdPath to a user-facing URI string. The method generates the appropriate format automatically based on the path type.

### URI Parsing

Use `from_uri()` when parsing user input. The method parses service-native URIs and validates the format.

### Device Naming

Choose distinct device names to avoid slug collisions. Include location or purpose in names:

- "jamies-macbook-home"
- "jamies-macbook-work"
- "home-server-basement"
- "backup-nas-office"

### Cloud Mount Points

Spacedrive ensures cloud mount points are unique by appending `-2`, `-3` if collisions occur:

```
s3://my-bucket      ← First S3 volume with this bucket
s3://my-bucket-2    ← Second volume (different credentials or endpoint)
```

This enables multiple configurations for the same cloud resource.

## Related Documentation

- [Devices](/docs/core/devices) - Device management and pairing
- [Volumes](/docs/core/volumes) - Volume system and cloud integration
- [Cloud Integration](/docs/core/cloud-integration) - Cloud storage details
- [Data Model](/docs/core/data-model) - SdPath internal representation
