◆PRISMObjstore

06 / 12Prism Systems · Cloud-Native & Developer Infrastructure

Object storage that survives a whole zone at 1.5× cost

An S3-compatible object store built on Reed–Solomon erasure coding over GF(256): zone-aware shard placement, degraded reads, background repair, CRC scrubbing for bit rot, versioning, multipart uploads and Range requests.

Zero dependenciesReed–Solomon GF(256)S3-compatible API~75 MB/s encode in JSSelf-healing
Live simulator

Fail a zone and watch the cluster heal

Objects stream in and are split into data and parity shards across 15 nodes in 3 zones. Fail zone-a, click nodes to kill them, inject bit rot, switch to 3× replication, then GET your own object back.

paused
click a node to fail / recover it
Stripe health
Repair traffic (shards / s)
PUT / GET an object
—
Cluster events
Features

What's inside the engine

Real algorithms, not mock-ups. The simulator above runs the exact same code you import.

◫

Reed–Solomon coding

Systematic RS(k, m) over GF(2^8) with a Cauchy parity matrix, so any k of the k+m shards reconstruct the data. Inverse matrices are cached per loss pattern.

⌖

Zone-aware placement

Rendezvous hashing picks k+m distinct nodes per stripe with at most ⌈n/zones⌉ per zone, so RS(6,3) over 3 zones survives losing any one zone.

↯

Degraded reads

Reads use the data shards when they are all online, otherwise rebuild the missing ones from parity on the fly. Range reads only touch the stripes they need.

⟲

Background repair

Budgeted repair rebuilds missing shards onto healthy nodes in the least-used zones and never co-locates two shards of a stripe.

✓

Scrubbing

Every shard carries a CRC-32. Reads skip corrupt shards and scrubs drop them, so silent bit rot is found and repaired before it adds up.

🗂

S3 semantics

Buckets, versioning with delete markers, ListObjectsV2 with prefix, delimiter and continuation, user metadata and MD5 ETags.

⇪

Multipart uploads

Out-of-order parts, ETag checks, unused parts freed on completion, and md5(md5(p1)‖…)-N ETags like S3.

∞

Durability model

Binomial loss model per repair window with AFR, which shows why RS(6,3) beats 3× replication at half the storage.

How it works

From request to result

Stripe

Objects are cut into stripes (1 MiB by default). Each stripe is split into k equal data shards, zero-padded at the end.

Encode

m parity shards are computed as GF(256) linear combinations of the data shards (dst ^= MUL[c][src]).

Place

Rendezvous hashing ranks nodes per stripe. A per-zone cap spreads shards, and each shard is stored with its CRC-32.

Read

Collect shards from healthy nodes, drop any with a bad CRC, and use the fast path or invert the k×k sub-matrix to rebuild.

Heal

Repair finds stripes with missing shards, rebuilds them from any k survivors and writes them to new nodes. Scrubs catch bit rot.

Architecture

System design

Every box is a module in src/. Data flows left to right.

k+m shardsrebuildAPIS3 HTTP APIpath-style · XMLMultipartparts · ETagsMETADATABucketsversions · markersStripe mapshard → node · crcCODINGReed–SolomonGF(256) · CauchyPlacementrendezvous · zone capNODESShard stores15 nodes · 3 zonesRepair + scrubrebuild · crc32
Use it

Ship it in your own stack

Zero dependencies. Works in Node.js 18+ and modern browsers.

example.js
import { ObjectStore, ReedSolomon, durability } from "prism-objstore";

const s3 = new ObjectStore({ k: 6, m: 3, nodes: 12, zones: 3 });
s3.createBucket("photos", { versioning: true });
s3.putObject("photos", "2026/cat.jpg", bytes, { contentType: "image/jpeg" });

for (const n of s3.nodes.filter((n) => n.zone === "zone-a")) s3.fail(n.id);   // lose a zone
const { body, etag } = s3.getObject("photos", "2026/cat.jpg");              // degraded read, still correct
s3.repair();                                                                 // rebuild missing shards
s3.scrub();                                                                  // find bit rot via CRC-32

// raw codec
const rs = new ReedSolomon(10, 4);
const shards = rs.encode(data);      // 14 shards
shards[2] = shards[7] = null;        // lose any 4
rs.reconstruct(shards); rs.join(shards, data.length);

durability({ k: 6, m: 3, afr: 0.02, repairHours: 6 });   // { overhead: 1.5, nines: 14.2 }
terminal
$ npx github:krishyaa06/prism-objstore demo
$ npx github:krishyaa06/prism-objstore encode photo.jpg --k 10 --m 4
$ npx github:krishyaa06/prism-objstore durability --afr 0.03 --repair 12
$ npx github:krishyaa06/prism-objstore serve --port 9000
$ curl -X PUT localhost:9000/photos && curl -T cat.jpg localhost:9000/photos/cat.jpg
$ curl -X POST localhost:9000/_admin/fail/node-01 && curl -r 0-99 localhost:9000/photos/cat.jpg
terminal
# use the CLI without installing
$ npx github:krishyaa06/prism-objstore --help

# or add the engine to your project
$ npm install github:krishyaa06/prism-objstore

# run the simulator locally
$ git clone https://github.com/krishyaa06/prism-objstore.git && cd prism-objstore
$ npx serve .   # then open http://localhost:3000