Persistent Storage Architecture
Lioran S3 uses a decoupled on-disk layout that separates transactional metadata from bulk physical payload files.
1. Directory Structure
The base data path is configured via BASTION_DATA_DIR (default: /data in containers or ./data locally):
/data/
├── metadata/ # RocksDB transactional metadata engine
│ ├── CURRENT
│ ├── MANIFEST-*
│ ├── *.sst # SSTable files containing bucket & object records
│ └── OPTIONS-*
│
├── objects/ # Physical committed object payloads
│ └── <bucket-id>/
│ └── <hash-prefix>/
│ └── <payload-blob>
│
└── .staging/ # Temporary staging area for active uploads
└── <upload-uuid-v7>.tmp
2. Decoupling Guarantee
- RocksDB Metadata: Stores bucket configurations, quota usage, object keys, content types, ETags, SHA-256 hashes, creation timestamps, and multipart session state. Under no circumstances are object payload bytes placed inside RocksDB.
- Payload Volumes: Raw payload bytes reside in
/data/objects/. Files are placed using structured hash paths to avoid hot-spotting and directory-depth bottlenecks. - Temporary Staging: In-flight uploads stream to
/data/.staging/. If a transfer is interrupted or canceled, the temporary file is swept by background cleanup and never pollutes the committed object space.
3. Filesystem Recommendations
Recommended
- Local NVMe / SSD: High-IOPS solid-state drives formatted with ext4 (with
dir_index), XFS, or modern NTFS. - Direct Block Storage: Cloud block volumes (AWS EBS gp3/io2, Google Persistent Disk SSD, Hetzner Volume SSD).
Not Recommended
- Network-Attached Storage (NFS / CIFS / SMB): Embedded RocksDB requires POSIX file locking and reliable
fsyncsemantics. Running RocksDB over network filesystems often leads to lock contention, performance degradation, and database corruption. - Ephemeral Storage: Avoid running without persistent volume mounts (
volumes: [bastion-data:/data]); container termination will delete all metadata and payloads.