Help us shape the future of Go! Take the 2026 Go Developer Survey

lith

module
v1.11.0 Latest Latest
Warning

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

Go to latest
Published: Oct 7, 2026 License: Apache-2.0

README

lith

Read-only, high-performance POSIX filesystem over an existing S3 bucket in its native key layout.

lith presents any S3 bucket — a Registry of Open Data dataset, a lab bucket, an instrument dump — as a read-only filesystem, using the bucket's key namespace directly. It writes nothing to the bucket, needs no sidecar objects, and serves all metadata (readdir, lookup, getattr, open) locally from an index after a one-time build.

Why "lith"? As in lithic / lithology — rock strata. lith serves a bucket's objects as read-only strata, exactly as they were laid down: the bucket's native key layout is the stratum, and lith never rewrites it.

Read-only by definition — the reason lith exists. No write path is not a limitation; it is what buys free local metadata, an index two uncoordinated readers agree on, handles pinned at open, and a cluster cache that never needs invalidation. A tool that can write cannot have those; writes are a separate program.

Cloud-native by thesis, portable by implementation — why it works. lith runs against any S3-compatible endpoint, but its economics come from the cloud: aggregate bandwidth that grows as readers are added, data that is already in the store, ephemeral compute, and free durability. Lustre and GPFS are on-prem designs running in the cloud; lith is a design that could not have been built anywhere else.

Whether lith is for you — and where it is the wrong tool — is What lith is for.

What it is

  • Read-only. There is no write path. Every mutating operation returns EROFS.
  • Native layout. The bucket's keys are the filesystem. Any bucket, any producer.
  • Local metadata. After an index build, listing and stat make zero S3 calls.
  • Mount any prefix. Root the filesystem at any prefix below the bucket; one prebuilt index backs many prefix mounts at once (lith umount/lith mounts manage them).
  • Prefetch that knows its limits. A single memory-tier-bounded budget feeds per-handle readahead, sibling readahead for chunked stores, a format-aware plan (Zarr chunk grid), and parallel parts for mid-size files; the in-flight window is sized from the NIC's baseline bandwidth.
  • Fast. Sequential throughput near NIC line rate; random reads bounded by cache hit rate, not S3 request latency.
  • A single static Go binary.

What it is not

  • Not writable. No writes, ever — not "writes disabled", writes absent.
  • Not a re-layout. It does not own or rewrite the bucket's object format.
  • Linux only. It relies on FUSE; macOS/Windows are out of scope.

Install

Download the static binary for your architecture (a stable name that always points at the latest release):

# arm64 (Graviton, Apple-on-Linux VMs, …)
curl -L https://github.com/scttfrdmn/lith/releases/latest/download/lith_linux_arm64 -o lith && chmod +x lith
# or x86-64
curl -L https://github.com/scttfrdmn/lith/releases/latest/download/lith_linux_amd64 -o lith && chmod +x lith
sudo mv lith /usr/local/bin/

Versioned .tar.gz archives, .deb/.rpm packages, and a container image (ghcr.io/scttfrdmn/lith) are on the releases page — grab the .deb/.rpm for your architecture, e.g. sudo dpkg -i lith_*_linux_amd64.deb (or sudo rpm -i lith_*_linux_amd64.rpm). Or, with Go: go install github.com/scttfrdmn/lith/cmd/lith@latest.

Verifying a release

Every release ships a checksums.txt with a keyless cosign signature bundle (checksums.txt.bundle), an SBOM per artifact, and a SLSA build-provenance attestation. To verify:

# the checksums signature (identity = the release workflow's OIDC identity)
cosign verify-blob checksums.txt --bundle checksums.txt.bundle \
  --certificate-identity-regexp 'https://github.com/scttfrdmn/lith/.github/workflows/.+' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com
# then confirm your download against the (now-trusted) checksums
sha256sum -c checksums.txt --ignore-missing

# build provenance for any downloaded artifact
gh attestation verify lith_linux_amd64 --repo scttfrdmn/lith

Commands

lith mount   s3://bucket[/prefix][@current|@<ver>] /mnt/point [flags]  # mount as a read-only filesystem
lith serve   nfs s3://bucket[/prefix][@current] [flags]  # NFSv3 gateway: one node serves a cluster
lith umount  /mnt/point [--all] [--force]              # unmount (SIGTERM, then fusermount fallback)
lith mounts                                            # list live lith mounts (and stale records)
lith refresh /mnt/point                                # hot-swap a @current mount to a newly published version
lith index   build|refresh|inspect s3://bucket[/prefix] --index-file F
lith doctor  [s3://bucket[/prefix][@ref]]              # diagnose whether lith will work here
lith bench   s3://bucket/key --pattern seq|rand4k|stride [--against PATH]
lith version                                            # version, commit, build date

Quick start: a public Registry of Open Data bucket

The 1000genomes bucket is public; use --no-sign-request to read it without credentials:

lith index build s3://1000genomes/changelog_details --index-file /tmp/1kg.lithidx --no-sign-request
lith index inspect /tmp/1kg.lithidx
sudo mkdir -p /mnt/1kg && sudo chown "$USER" /mnt/1kg   # you must own the mountpoint
lith mount  s3://1000genomes/changelog_details /mnt/1kg --index-file /tmp/1kg.lithidx --no-sign-request
ls -l /mnt/1kg
cat /mnt/1kg/changelog_details_20081219
lith umount /mnt/1kg

Documentation

Full docs — how to use lith, when to use it, and when not to — are at scttfrdmn.github.io/lith:

Benchmark data lives in bench/results/; the S3 client ceiling can be reproduced independently with cmd/lith-s3bench.

Testing

Unit tests run with the race detector and touch no network:

make test

An optional end-to-end test runs only when LITH_E2E_BUCKET is set. It builds an index from a real public prefix and asserts a known key resolves. It is verified against s3://1000genomes/changelog_details (key changelog_details_20081219):

LITH_E2E_BUCKET=1000genomes LITH_E2E_PREFIX=changelog_details go test ./internal/index/ -run E2E -v

License

Apache-2.0. Copyright 2026 Scott A Friedman.

Directories

Path Synopsis
cmd
lith command
Command lith is a read-only, high-performance POSIX filesystem over an existing S3 bucket in its native key layout.
Command lith is a read-only, high-performance POSIX filesystem over an existing S3 bucket in its native key layout.
lith-pfreplay command
Command lith-pfreplay replays a `lith mount --pf-trace` file through the real access-pattern detector and scores, per file handle, what fraction of the BYTES it caused to be prefetched were subsequently read by that same handle.
Command lith-pfreplay replays a `lith mount --pf-trace` file through the real access-pattern detector and scores, per file handle, what fraction of the BYTES it caused to be prefetched were subsequently read by that same handle.
lith-s3bench command
Command lith-s3bench isolates the S3 client/transport from lith's cache, prefetch, and FUSE layers.
Command lith-s3bench isolates the S3 client/transport from lith's cache, prefetch, and FUSE layers.
internal
blockstore
Package blockstore implements lith's read-only cache over S3 range GETs.
Package blockstore implements lith's read-only cache over S3 range GETs.
cargoship
Package cargoship reads CargoShip format-2.1 archive manifests and maps a virtual file's byte range to zstd frame range GETs against the packed `.tar.zst` chunk objects (scttfrdmn/cargoship#436, #439).
Package cargoship reads CargoShip format-2.1 archive manifests and maps a virtual file's byte range to zstd frame range GETs against the packed `.tar.zst` chunk objects (scttfrdmn/cargoship#436, #439).
format/bgzf
Package bgzf implements the access plan for the bgzf + external-index family (#107): BAM/CRAM, VCF/BCF, bgzipped FASTA.
Package bgzf implements the access plan for the bgzf + external-index family (#107): BAM/CRAM, VCF/BCF, bgzipped FASTA.
format/footer
Package footer holds the pure parsing and detection logic for lith's "footer family" access plan (issue #108): columnar/archive formats whose layout is described by a metadata block at the tail of the object (Parquet, ORC, Arrow/Feather, zip).
Package footer holds the pure parsing and detection logic for lith's "footer family" access plan (issue #108): columnar/archive formats whose layout is described by a metadata block at the tail of the object (Parquet, ORC, Arrow/Feather, zip).
format/zarr
Package zarr implements the Zarr chunk-grid access plan (#70).
Package zarr implements the Zarr chunk-grid access plan (#70).
fuse
Package fuse implements lith's read-only FUSE layer on the hanwen/go-fuse/v2 raw API.
Package fuse implements lith's read-only FUSE layer on the hanwen/go-fuse/v2 raw API.
index
Package index holds the immutable namespace snapshot of a bucket: an in-memory sorted arena of keys plus parallel metadata arrays, from which directory structure is derived rather than stored.
Package index holds the immutable namespace snapshot of a bucket: an in-memory sorted arena of keys plus parallel metadata arrays, from which directory structure is derived rather than stored.
metrics
Package metrics defines lith's Prometheus metrics and an HTTP handler for the --metrics endpoint.
Package metrics defines lith's Prometheus metrics and an HTTP handler for the --metrics endpoint.
nfs
Package nfs implements lith's read-only NFSv3 gateway (#143/#144): one node holds the Index and BlockStore and serves N clients over NFSv3, so a cluster pays one node's S3 traffic.
Package nfs implements lith's read-only NFSv3 gateway (#143/#144): one node holds the Index and BlockStore and serves N clients over NFSv3, so a cluster pays one node's S3 traffic.
pointer
Package pointer parses the CURRENT pointer object of a published dataset (cargoship#560): a small JSON object naming the current immutable version's index and manifest.
Package pointer parses the CURRENT pointer object of a published dataset (cargoship#560): a small JSON object naming the current immutable version's index and manifest.
prefetch
Package prefetch implements lith's per-open-file-handle access-pattern detector and readahead planner.
Package prefetch implements lith's per-open-file-handle access-pattern detector and readahead planner.
s3client
Package s3client defines the narrow S3 surface lith depends on and provides a tuned aws-sdk-go-v2 implementation of it.
Package s3client defines the narrow S3 surface lith depends on and provides a tuned aws-sdk-go-v2 implementation of it.
s3client/fake
Package fake is an in-process implementation of the s3client.API surface (ListObjectsV2, HeadObject, GetObject with Range) over an in-memory map.
Package fake is an in-process implementation of the s3client.API surface (ListObjectsV2, HeadObject, GetObject with Range) over an in-memory map.
version
Package version holds build-time identifying information for the lith binary.
Package version holds build-time identifying information for the lith binary.
pkg
lithindex
Package lithindex is the public, cross-repo entry point for building a lith index from a CargoShip 2.1 manifest.
Package lithindex is the public, cross-repo entry point for building a lith index from a CargoShip 2.1 manifest.

Jump to

Keyboard shortcuts

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