lode

module
v0.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 2, 2026 License: MPL-2.0

README

lode

DVC add and status, much faster. Same repo. No migration.

CI

lode is a DVC-compatible accelerator for the data-versioning hot path in Go. Point it at an existing DVC repo and, for the supported commands, it writes the same .dvc pointer files, .dir objects, local cache layout, and S3-compatible remote object paths that DVC expects. If you stop using it, nothing is trapped in a new format: keep using dvc on the same repository.

$ time dvc add big/      # 20,000 files
real    0m5.79s

$ time lode add big/     # same repo, DVC-compatible add output
real    0m0.44s

On a Tiny-ImageNet benchmark with 100,200 files, lode add is 12.4x faster and incremental add after changing one file is 13.2x faster than DVC 3.67.1. The benchmark harness verifies that dvc status accepts the dvc add-style outputs produced by lode.

Try it safely on a DVC repo

brew install getlode/tap/lode
cd your-existing-dvc-repo
lode doctor
lode status
lode add path/to/data
lode verify
# Optional proof: DVC should still read the repo normally.
dvc status

Nothing migrates. lode writes standard DVC files and cache objects for the commands it supports. There is no format lock-in; if you do not want the files produced during a trial, review or revert the .dvc/.gitignore changes with Git and keep using DVC. For a more careful copy-based trial, see Try without risk.

Current scope

Works today Not yet
init, add, status, checkout, push, fetch, pull, gc, verify, doctor dvc repro / pipelines
Existing DVC 3.x repos and legacy DVC 2.x cache reads Native gs://, Azure, SSH remotes
S3-compatible remote implementation; tested directly with MinIO Replacing every DVC command

See the compatibility matrix for the tested surface and known limits.

Help wanted

The most useful feedback right now is a real DVC repo trial: run lode doctor, lode status, lode add, then dvc status, and report the result in #23. Good early contribution areas are native GCS, Azure, and SSH remotes, plus benchmark reports on real datasets.

Why

DVC is the standard for versioning datasets and ML models, but dvc add and dvc status can have high per-file overhead on large repos, especially many-small-file datasets. lode reimplements that data-versioning hot path in Go, with concurrent hashing, batched writes, and a local state DB that skips re-hashing unchanged files. No migration: your repo stays a DVC repo.

Install

brew install getlode/tap/lode
# or download a binary from the Releases page (no toolchain needed)
# or, if you have Go:  go install github.com/getlode/lode/cmd/lode@latest

Single self-contained binary, no Python runtime. Linux / macOS / Windows, amd64 / arm64.

New to DVC? You don't need DVC or Python installed — lode is standalone. Run lode init then lode add <folder> to start versioning a dataset, and lode push to back it up to S3. Because lode uses DVC's on-disk format, DVC's docs and concepts apply directly if you want to go deeper. For ML pipelines (dvc repro), keep using DVC — lode accelerates the data layer and coexists with it.

Quickstart: zero to versioned

$ mkdir cats-dataset && cd cats-dataset && lode init --no-scm
Initialized lode repository in .../cats-dataset/.dvc

$ lode add images/                 # hash + cache the folder, write a tiny pointer
images               tracked -> images.dvc

$ cat images.dvc                   # this text file is what you commit to git — not the data
outs:
- md5: da80a810597fa6de9381d9d1b76b3517.dir
  size: 600000
  nfiles: 3
  hash: md5
  path: images

$ lode status                      # instant — unchanged files are not re-hashed
Data and pipelines are up to date.

$ lode remote add -d r s3://my-bucket/store && lode push   # back the data up

images.dvc is a few lines of text you version in git; the actual files live in the cache and your remote. Change one image and lode status flags it; lode push ships only what changed. It is a standard DVC repo — dvc reads it too.

Usage

lode init --no-scm             # start a repo with no Python and no DVC (use plain `lode init` in a git repo)
lode add data/                 # track a directory (or a file)
lode status                    # what changed — without re-hashing unchanged data
lode remote add -d r s3://bucket/store
lode remote modify r endpointurl https://nyc3.digitaloceanspaces.com
lode push                      # upload to an S3-compatible remote
lode pull                      # fetch + checkout on a clean clone
lode checkout                  # materialize the workspace from cache
lode gc -f                     # reclaim unreferenced objects
lode verify                    # check integrity + prove DVC compatibility on your repo
lode doctor                    # diagnose repo, cache, remotes and DVC coexistence

Already have a DVC repo? Skip init and point lode at it for the supported commands — same DVC format, no migration.

Command What it does
init Create a DVC-compatible repo — standalone, no Python required
add Hash (in parallel), cache, write the .dvc, update .gitignore
status Report changes using the state DB (no re-hash of unchanged data); --json
push / fetch / pull Sync with S3-compatible object storage; MinIO is covered in integration tests
checkout Materialize the workspace (reflink → hardlink/symlink → copy)
gc Remove unreferenced objects from the cache (and remote with -c)
verify Re-hash cached objects and check they match their recorded hash — proves integrity and, on a DVC repo, that lode computes the same hashes
doctor Diagnose repo, cache, remotes, format and DVC coexistence; --json, CI-friendly exit codes
S3 remote credentials

For S3-compatible remotes, credentials resolve in this order:

  1. Explicit remote config in .dvc/config: access_key_id, secret_access_key, session_token
  2. AWS environment variables
  3. Shared AWS credentials file, honoring the remote profile option or AWS_PROFILE
  4. IAM role credentials from the runtime environment

Prefer environment variables, the shared AWS credentials file, or IAM roles over storing static keys in .dvc/config, because .dvc/config is plain text.

DVC compatibility

  • Byte-compatible for tested dvc add file and directory outputs — verified by a byte-oracle test that compares lode's .dvc and .dir output against the real dvc binary.
  • Same content-addressed layout in cache and remote (files/md5/<2>/<rest>).
  • Bidirectional interop for the integration suite: objects lode pushes are pulled by DVC and vice versa in the MinIO-backed tests.
  • Reads the legacy DVC 2.x cache layout.

This is validated where it matters most for format risk: CI runs the byte-oracle against a real DVC 3.67.1 install and runs the MinIO interop suite against a live S3-compatible server. The tested surface is tracked in docs/compatibility.md.

Benchmarks

On a real public dataset — Tiny-ImageNet, 100,200 files, 16-core, DVC 3.67.1, median of 6 runs (execution order alternated to remove page-cache bias):

operation DVC lode speedup
add (fresh repo, warm page cache) 25.40s 2.05s 12.4x
status (no change) 3.46s 1.16s 3.0x
add (1 file changed, of 100k) 6.10s 0.46s 13.2x

...and dvc status then reports "up to date" on the repo lode produced for the tested add outputs. The harness asserts this every run. The last row is the structural win: change one file in a 100k dataset and DVC re-processes the directory; lode's state DB skips the rest. The gap is ~12x on many small files and narrows to ~3.7x on large files (both become hash-bound — shown honestly). Full methodology (median +/- stddev, memory, file-size regimes) and the documented DVC slowness this addresses: BENCHMARKS.md. Reproduce with scripts/benchmark.sh. See also Try without risk.

How it works

  • Parallel, bounded hashing (errgroup capped at NumCPU) with a reused buffer pool.
  • State DB (embedded, pure-Go) keyed by file metadata -> hash, so status and re-add skip files that did not change. Use --rehash for safety-critical checks, NFS/restored-backup edge cases, or whenever metadata cannot be trusted.
  • Atomic, batched writes: no per-file fsync, no per-file DB transaction — the two changes that turned an early 78 s run into 0.44 s.
  • Zero cgo end-to-end, so the binary cross-compiles to every target without a C toolchain.

Scope

In scope today: the data-versioning core — add, status, checkout, push, fetch, pull, gc — over a local cache and S3-compatible object storage. MinIO is covered by CI integration tests; provider-specific S3-compatible services should work through the same API but need more field reports.

Not yet (planned / feedback-driven): the pipelines / repro engine, and non-S3 remotes (GCS, Azure, SSH).

Development

make build         # CGO_ENABLED=0 single binary
make test-short    # unit + oracle, no external services
make test          # full suite — needs MinIO and the real `dvc` binary
make lint

CI runs unit tests, the DVC byte-oracle, and the MinIO-backed integration suite. To run the integration suite locally, provide a MinIO (MINIO_ENDPOINT, MINIO_ACCESS_KEY, MINIO_SECRET_KEY), the reference dvc (DVC_BIN), and the built binary (LODE_BIN). See tests/ for details. Contributions: see CONTRIBUTING.md.

Project status

lode is young and currently maintained by one person. The honest reason that's low-risk to depend on: lode does not own your data or its format. Your repo is a standard DVC repo — if lode stalls or you walk away, keep using dvc, no migration, no export. The tested byte-compatibility that makes that true is enforced by a test that runs against the real dvc on every CI build. Roadmap and how to help: ROADMAP.md, CONTRIBUTING.md, ARCHITECTURE.md.

License

MPL-2.0 — free to use, modify, and ship, including commercially and inside closed-source products. MPL is file-level copyleft: changes to lode's own files stay open, but you can combine it with proprietary code, and there's no license to buy. Commercial use is allowed under MPL-2.0; see COMMERCIAL.md for the plain-English licensing note.

Contributions are accepted under a DCO (sign off with git commit -s) — no CLA, no copyright assignment. See CONTRIBUTING.md.

lode is an independent project and is not affiliated with or endorsed by Iterative, Inc. or the DVC project. "DVC" is used only to describe compatibility.

Directories

Path Synopsis
cmd
lode command
internal
cache
Package cache implements DVC's content-addressed object store (.dvc/cache/files/md5/<2>/<rest>) with atomic writes and 0o444 protection.
Package cache implements DVC's content-addressed object store (.dvc/cache/files/md5/<2>/<rest>) with atomic writes and 0o444 protection.
checkout
Package checkout handles workspace materialization and .gitignore management.
Package checkout handles workspace materialization and .gitignore management.
cli
Package cli wires the lode command-line interface.
Package cli wires the lode command-line interface.
dvcfile
Package dvcfile reads and writes .dvc files with byte-exact compatibility with DVC 3.x.
Package dvcfile reads and writes .dvc files with byte-exact compatibility with DVC 3.x.
lock
Package lock implements DVC-compatible repository locking so lode can coexist with DVC-Python on the same repo.
Package lock implements DVC-compatible repository locking so lode can coexist with DVC-Python on the same repo.
remote
Package remote implements S3-compatible object stores (AWS S3, MinIO, Cloudflare R2, Backblaze B2) using DVC's content-addressed key layout.
Package remote implements S3-compatible object stores (AWS S3, MinIO, Cloudflare R2, Backblaze B2) using DVC's content-addressed key layout.
repo
Package repo handles DVC repository discovery and well-known paths.
Package repo handles DVC repository discovery and well-known paths.
transfer
Package transfer moves objects between the local cache and a remote store, preserving DVC's ordering and integrity guarantees.
Package transfer moves objects between the local cache and a remote store, preserving DVC's ordering and integrity guarantees.
tests

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL