ADR-0008: Storage and artifact management
- Status: Accepted (milestone 1) for SQLite metadata and the local CAS. Shared database and object storage are Proposed.
- Date: 2026-10-29
Context
Job metadata (small, transactional) and artifacts (large, immutable) have different needs. Remote workers do not share a filesystem with the submitter or the control plane.
Decision
- Metadata:
SqliteStore(src/gpulayer/storage/sqlite.py) holds jobs, tasks, workers, events, logs, instances and costs. It uses WAL mode,busy_timeout30 s, a process-local re-entrant lock, andBEGIN IMMEDIATEtransactions, so several local processes can safely share one file. There is a schema version in ametatable, and a mismatch refuses to open. - Artifacts:
LocalArtifactStore(artifacts/store.py) is content-addressed by SHA-256 (artifact://sha256/<hex>). Writes are atomic (temp file + rename), and every read verifies the digest. TheArtifactStoreprotocol lets an object store replace it. - Remote workers fetch artifacts over the API (
GET /v1/artifacts/<sha>), verify the digest, and cache them per worker. Outputs written to$GPULAYER_OUTPUT_DIRare uploaded after the task (limits: 1000 files, 512 MiB per task) and referenced inJobResult.outputs. - Logs are stored as database rows (lines truncated at 8 KiB). They are not artifacts.
Alternatives considered
- Shared filesystem (NFS): not available for cloud or remote workers. Possibly a future optimization, declared as a capability.
- PostgreSQL from day one: an operational burden for the local mode. It is the expected choice for multi-replica deployments (Proposed).
- S3-compatible object storage: the expected remote implementation (Proposed). Presigned URLs would offload transfer from the control plane.
Consequences and trade-offs
- All artifact bytes pass through the control plane in served mode, which limits it to modest data sizes.
- No garbage collection: artifacts, logs and events grow without bound.
- Restart recovery works because every state is persisted (see
test_state_is_persisted_across_restart). In-flight provider calls are not journaled.
Security and operational implications
- Artifact access is by digest. Any authenticated client or worker can read any artifact whose digest it knows (ADR-0003 gap).
- Back up
$GPULAYER_HOME(metadata.db*,artifacts/,server-credentials.json).
Follow-up
PostgresStoreand anS3ArtifactStorewith presigned transfers, both behind the existing interfaces.- Retention and GC policies, plus log archival to artifacts.
- Data-locality hints in placement.