Aquifer

Running on shelbynet · pre-production

A shared data layer for AI inference.

When several inference nodes serve the same model, each one pulls the weights independently. Aquifer publishes an artifact once and lets every node retrieve it from Shelby, with integrity checked against a commitment registered on chain.

Measured, not claimed

It loses the race it was built to win.

A cold pull of an 87 MB model was slower than downloading the same bytes from Hugging Face, and no number of nodes amortizes the publish. That result is at the top of this page rather than the bottom of a footnote.

9,920.8 ms Aquifer cold pull, every shard verified
3,633.4 ms Baseline: a real Hugging Face download, same session, same uplink, with equivalent verification
796.7 ms Warm pull from the verified disk cache

Two interleaved iterations on shelbynet, 2026‑08‑01. Both paths do the same integrity work, so neither is credited for effort it did not spend. Full method and caveats in BENCHMARKS.md.

What it actually wins

Content addressing, and verification. Republishing a model version where one file changed moves kilobytes instead of the whole artifact, and every shard is checked against its digest before a byte is returned.

Republishing a version with a single changed file — shelbynet, 2026-08-01.
Measurement Value Note
Shards uploaded 2 Only the shards whose bytes actually changed
Shards skipped, already stored 9 Recognised by content address
Bytes uploaded 4,662 B Against roughly 87 MB for the first publish
Read latency, 1 MiB blob 909.1 ms p50 of 12 samples; p90 1,217.2 ms, p99 1,969.9 ms

What these numbers are not

They were measured on a developer network whose storage providers are cloud-hosted nodes run by the Shelby team. They do not describe production, and Shelby's own published performance claims are not repeated anywhere on this site. Every figure here is generated from a committed result file, never typed by hand.

Three subsystems, one storage contract

What it does

Model registry

Versioned weights as content-addressed shards. Pulls verify every shard against its digest and every reassembled file against its own, and refuse to return bytes that do not match.

Shared embedding cache

Vectors computed by one node, reused by every other. Shelby requires an absolute expiry on every write, so the TTL is enforced by the network — there is no eviction thread to write.

Tamper-evident ledger

Hash-chained inference records, anchored to a second independent network. Records carry digests of inputs and outputs, so a published log does not publish prompts.

And a claim stated at its real strength

A record can carry a replay commitment — a digest anyone can recompute by running the same model on the same input. Two hosts running one model on one input diverge by about 7 × 10⁻⁹, so bit-exact comparison is impossible; the commitment is over a quantized output, and the quantization travels inside it.

A match therefore shows an equivalent computation to a stated precision, not identical bits. Verification reports matched, mismatched, or not‑replayable — and the last is never reported as a pass.

Read from the network, not the documentation

What building this found

Aquifer was built against an SDK that added Shelby testnet support one day before the project started. Several things the documentation implies turned out not to hold.

  • Immutability is not enforced

    Writing a name that already exists is accepted, the blob is replaced, and the on-chain commitment is updated to the replacement's. Measured directly: 8 bytes at one merkle root, overwritten by 15 bytes at another.

  • Micropayments are not metered

    The RPC accepts a payment addressed to a channel that does not exist, and accepts descending sequence numbers, serving both. The sender half of the read economics is real — funds lock on chain — but nothing on the serving side meters a read.

  • Aptos testnet cannot run the SDK

    Its deployed contract takes seven arguments for register_blob; the SDK sends ten. Uploads are impossible there, which is why this runs on shelbynet.

  • A read is terminated at ~15 seconds

    A 32 MiB range read succeeded at 14.2 s while 48 and 64 MiB both died between 16 and 18 s. It tracks elapsed time, not size — and raising concurrency pushes every request toward the same ceiling rather than away from it.

  • Blob names cap at 190 characters

    Undocumented publicly; found in the SDK's schema. A content-addressed naming scheme reaches it quickly, and exceeding it aborts on chain after gas is spent.

  • The indexer serves no blob data

    Its GraphQL schema exposes one field. Listings are derived from registration events on the fullnode instead.

Each is recorded with its evidence in SHELBY-API-NOTES.md. The first is pinned as a defect in a conformance suite that holds three storage backends to one contract, so the test fails if the behaviour changes in either direction.

Getting started

Run it

Node 22 or newer. The whole stack tests offline against an in-memory backend — no key, no tokens, no network.

# clone, install, and run the suite offline
git clone https://github.com/Ridwannurudeen/aquifer
cd aquifer && npm install && npm test

# diagnose a live setup: balances, endpoints, what is missing
npx aquifer doctor

doctor is the command to run first. It reports which variables are set, both token balances, and whether the RPC and indexer answer — each with the remediation for whatever is missing. An account needs both APT for gas and ShelbyUSD for storage, and a write with no resolvable location aborts on chain.

Python inference nodes talk to a local gateway sidecar, because the Shelby SDK is TypeScript-only:

from aquifer import AquiferClient

client = AquiferClient()
client.pull("all-MiniLM-L6-v2", "latest", into="./models")

The client depends on nothing outside the Python standard library. Inference nodes have opinionated dependency trees and a storage client has no business adding to them.