Skip to main content
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
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.

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
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.

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

// 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.
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.

Resolution

When parsing a local:// URI, Spacedrive looks up the device by slug:
// 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

// 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

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:
ServiceSchemeExample
Amazon S3s3://s3://my-bucket/path/file.jpg
Google Drivegdrive://gdrive://My Drive/Documents/file.pdf
OneDriveonedrive://onedrive://Documents/file.xlsx
Dropboxdropbox://dropbox://Apps/Spacedrive/file.zip
Azure Blobazblob://azblob://container/data/file.csv
Google Cloud Storagegcs://gcs://bucket/logs/file.log
Backblaze B2b2://b2://bucket/backups/file.tar
Wasabiwasabi://wasabi://bucket/archive/file.zip
DigitalOcean Spacesspaces://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

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

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:
# 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

// 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

// 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

// 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:
aws s3 cp s3://bucket/file.jpg local-file.jpg
sd cp s3://bucket/file.jpg local://macbook/Desktop/file.jpg
gsutil:
gsutil cp gs://bucket/file.jpg local-file.jpg
sd cp gcs://bucket/file.jpg local://macbook/Desktop/file.jpg
Azure CLI:
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:
// 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:
// 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.