How Mounting Works¶
When you call mount("s3://my-bucket", "local://./data"), nexus-fs parses the URIs, creates storage backends, registers them with the kernel, and returns a facade that routes operations to the right backend.
URI parsing¶
Each URI is parsed into a MountSpec:
| Field | Description |
|---|---|
scheme | Backend type: s3, gcs, local, gdrive, or a connector scheme |
authority | Bucket name, project/bucket, or path |
mount_point | Auto-derived filesystem path (see below) |
uri | The original URI string |
Supported schemes:
| Scheme | Format | Example |
|---|---|---|
s3 | s3://<bucket> | s3://data-lake |
gcs | gcs://<project>/<bucket> | gcs://myproj/warehouse |
local | local://<path> | local://./data |
gdrive | gdrive://<id> | gdrive://shared |
Mount point derivation¶
Each backend is mounted at an auto-derived path in the virtual filesystem:
s3://my-bucket → /s3/my-bucket/
gcs://project/bucket → /gcs/bucket/
local://./data → /local/data/
gdrive://shared → /gdrive/shared/
The at= parameter overrides the auto-derived path:
# skip-test
import nexus.fs
fs = nexus.fs.mount_sync("s3://my-bucket", at="/data")
# /data/ instead of /s3/my-bucket/
Collision detection¶
nexus-fs checks for mount point collisions. If two URIs would mount at the same path, mount() raises an error. Use at= to resolve collisions.
Reserved paths¶
The paths /__sys__/ and /__pipes__/ are reserved by the kernel and cannot be used as mount points.
What happens during mount¶
sequenceDiagram
participant User
participant mount()
participant URI Parser
participant Backend Factory
participant Kernel
User->>mount(): mount("s3://bucket", "local://./data")
mount()->>URI Parser: parse_uri("s3://bucket")
URI Parser-->>mount(): MountSpec(scheme=s3, authority=bucket, ...)
mount()->>URI Parser: parse_uri("local://./data")
URI Parser-->>mount(): MountSpec(scheme=local, authority=./data, ...)
mount()->>Backend Factory: create_backend(s3_spec)
Backend Factory-->>mount(): S3 backend instance
mount()->>Backend Factory: create_backend(local_spec)
Backend Factory-->>mount(): Local backend instance
mount()->>Kernel: register mount(/s3/bucket/, s3_backend)
mount()->>Kernel: register mount(/local/data/, local_backend)
Kernel-->>User: SlimNexusFS facade - Parse: Each URI is parsed into a
MountSpecviaparse_uri(). - Derive mount point:
derive_mount_point()computes the filesystem path, checking for collisions and reserved paths. - Create backend: The backend factory creates a storage backend (S3, GCS, local, or connector) based on the scheme. Cloud backends trigger credential discovery at this stage.
- Register: Each backend is registered with the kernel at its mount point.
- Return facade: A
SlimNexusFS(async) orSyncNexusFS(sync) facade is returned, providing the unified API.
Namespace routing¶
When you call fs.read("/s3/my-bucket/file.txt"), the kernel routes the request:
- Match the path prefix against registered mount points
- Strip the mount prefix to get the backend-relative path
- Delegate the operation to the matching backend
- Return the result
This is an O(log m) lookup where m is the number of mounts.
Metadata storage¶
nexus-fs uses a SQLite database (WAL mode) to persist file metadata locally. This avoids re-listing remote backends on every operation and enables features like stat() and exists() without network calls for recently accessed files.
The database is stored in the nexus-fs state directory (platform- specific, see State Directory below).
State directory¶
nexus-fs writes two files to the state directory:
| File | Purpose | Regenerable? |
|---|---|---|
metadata.db | SQLite database with file metadata | Yes — rebuilt on next mount() |
mounts.json | Last-mounted URIs for auto-discovery | Yes — written on every mount() |
Default location depends on platform (override with NEXUS_FS_STATE_DIR):
- Linux:
~/.local/state/nexus-fs/ - macOS:
~/Library/Application Support/nexus-fs/ - Windows:
%LOCALAPPDATA%/nexus-fs/
Safe to delete
The entire state directory can be deleted without data loss. nexus-fs recreates it on the next mount() call. Your actual data remains in the storage backends (S3, GCS, local).
Cleanup and retention¶
nexus-fs does not automatically delete stale state. If you mount different backends over time, old metadata entries accumulate in metadata.db. To reset:
On close(), nexus-fs checkpoints the WAL and runs PRAGMA optimize to keep the database compact.
Corruption recovery¶
If metadata.db becomes corrupted (e.g., after a hard crash), delete it and re-mount. The database is a cache — no user data is stored in it.
If mounts.json contains invalid JSON, nexus-fs playground will show an empty mount list and fsspec auto-discovery will raise a clear error asking you to re-run mount().
Concurrent processes¶
nexus-fs is designed for single-process use per state directory.
- SQLite WAL mode allows concurrent readers, but only one writer.
mount()writesmounts.jsonatomically (temp file + rename), so concurrent readers always see valid JSON.- If two processes call
mount()against the same state directory simultaneously, the second writer may encounterSQLITE_BUSYand retry (up to 3 times with exponential backoff). If contention persists beyond the retry budget, anOperationalErroris raised.
To run multiple independent nexus-fs instances, set a different NEXUS_FS_STATE_DIR for each process.