The tins

What each one is, and what proves it

Every tin is Apache-2.0, published on mojoshelf, and CI-tested on stable Mojo 1.0.0 and the current nightly, across macOS and Linux. Each carries its own correctness oracle — an outside implementation I made it agree with.

Table format

File formats & storage

parquet

0.4.0

The first native Apache Parquet reader and writer in Mojo. It decodes the footer, the page headers, the levels and the values itself, and hands the result back in Arrow memory layout, exportable over the Arrow C Data Interface. That interface is the boundary, not a full Arrow library: there are no compute kernels, no IPC and no Flight.

  • Every physical and logical type, every encoding, every codec, v1 and v2 pages
  • Nested lists, maps and structs reconstructed from definition and repetition levels
  • Row-group, page-index and bloom-filter pruning; field-id projection for Iceberg
  • Arrow C Data Interface export, verified by pyarrow importing the arrays
  • Reads 1M rows in 4.7 ms on one core — 211M rows/s, 1.7× single-threaded pyarrow — and 2.35 ms on four, past threaded pyarrow
Checked against pyarrow, value-exact on 33 fixtures; pyarrow reads back every file it writes

avro

0.3.1

Pure-Mojo Apache Avro: schema parsing, the binary encoding, Object Container Files both ways, and schema resolution. The core has no dependencies at all — not even FFI.

  • Object Container Files, read and write, null / deflate / snappy / zstandard
  • A schema-compiled RecordCursor with no per-record allocation
  • Iceberg field-ids and OCF metadata survive parsing intact
  • Decodes manifest-shaped records at 18.1M/s — 10.7× fastavro
Checked against fastavro, both directions, across all four codecs

objectstore

0.3.0

Storage and HTTP for Iceberg tables: a FileIO abstraction over local files, HTTP(S) range reads and S3, with the pooled HTTP transport the rest of the stack was missing.

  • S3 with SigV4, vended credentials, presigned URLs and multipart upload
  • Pooled libcurl transport — 0.15 ms per range read on a reused connection
  • Pure-Mojo SHA-256 and HMAC on hardware crypto paths, 2.7 GB/s
  • GCS, Azure and plain HTTP range reads alongside local files
Checked against AWS SigV4 suite 37/37, and S3 verified end-to-end against MinIO in CI

sqlite

0.3.1

An embedded SQL database: connections, prepared statements, typed columns and RAII transactions over libsqlite3. A fork of ehsanmok/sqlite, made dependency-free so it installs from the registry with no external git repos.

  • Every column type, with NULL distinct from empty
  • Prepared statements, named parameters, explicit transactions
  • libsqlite3 opened once per process, not per connection
  • Backs the SQL catalog iceberg.mojo uses for PyIceberg parity
Checked against round-tripped against the sqlite3 shell in both directions

postgres

0.2.0

A PostgreSQL client over libpq: parameterized statements, typed text-format results, transactions with savepoints and COPY, every error carrying its SQLSTATE — and, in a module of its own, a connection pool for a threaded service. A fork of dvirarad/mojo-postgres, rewritten for the 1.x toolchain.

  • Every §5 type, with NULL distinct from empty and numeric kept as text
  • PQexecParams and prepared statements — no values escaped into SQL
  • COPY in and out at 5 M rows/s; handles co-own the connection
  • A bounded ConnectionPool behind with pool.lease(): acquire timeouts, is_alive-checked checkout, lifetime and idle recycling, ROLLBACK on return
  • A connection whose statement or transaction outlives its lease is closed, never handed to a second thread
  • Tested against a throwaway cluster on every CI leg — no Docker
Checked against psycopg 3 and psql — cell-exact, both directions

roaring

0.1.0

Pure-Mojo Roaring bitmaps, 32- and 64-bit, implementing the portable RoaringFormatSpec serialization plus Iceberg's deletion-vector v1 blob framing.

  • Bitmap32 and Bitmap64 with array, bitset and run containers
  • Portable serialization including the 64-bit extension
  • Iceberg deletion-vector blob framing with its own CRC-32
  • No dependencies
Checked against pyroaring, byte-exact in both directions

Primitives

thrift

0.1.0

Apache Thrift serialization in pure Mojo — compact and binary protocols — plus every struct, union and enum of the Parquet metadata schema, generated ahead of time.

  • TCompactProtocol and TBinaryProtocol behind one trait
  • All of parquet.thrift, pre-generated
  • Footer, page-header and page-index decode helpers
  • No RPC, no runtime IDL, no dependencies
Checked against Apache Thrift itself — 13 generated wire vectors, byte-identical

zstd

0.1.1

A Mojo binding to libzstd — one-shot and streaming, both directions — through a small C shim loaded at runtime, so consumers need no link flags.

  • One-shot and streaming compress and decompress
  • Frame introspection: is_zstd_frame, frame_content_size
  • The shim is dlopen'd once, not per call
  • 10–14 GB/s decompress
Checked against Python zstandard, against independently produced frames baked in as constants

lz4

0.1.1

A Mojo binding to liblz4 covering the block format, the frame format and the legacy Hadoop framing that older Parquet files still use.

  • LZ4_RAW blocks for Parquet pages
  • LZ4F frames for Iceberg Puffin blobs
  • Hadoop framing for legacy Parquet LZ4
  • 8–19 GB/s
Checked against CPython's lz4 package, on known vectors and round trips

brotli

0.1.0

A Mojo binding to libbrotli, the last of the seven Parquet page codecs. Bound rather than written: RFC 7932 needs two prefix-code forms, context maps, block-type switching, a distance cache and a 122 KB static dictionary with 121 word transforms that are part of the format itself.

  • One-shot compress and decompress, quality 0–11
  • A Brotli stream records no uncompressed size, so sized and unsized decoding are separate calls
  • The shim is dlopen'd once, not per call
  • 2.5 GB/s decompress
Checked against CPython's brotli package, on streams it produced and this one had never seen

snappy

0.1.1

Snappy in pure Mojo — the raw block format and the CRC-32C-checksummed framing format. No FFI, no C dependency.

  • Raw block format and sNaPpY framing
  • CRC-32C verified per chunk
  • Pure Mojo — nothing to build, nothing to link
  • Up to 20 GB/s incompressible, ~3 GB/s compressible
Checked against python-snappy, byte-exact

hashes

0.1.0

The three hashes Iceberg and Parquet actually need — CRC-32, MurmurHash3 x86-32 and XXH64 — in pure Mojo, with no dependencies and no FFI.

  • CRC-32 for page CRCs and deletion-vector checksums
  • MurmurHash3 for the Iceberg bucket[N] transform
  • XXH64 for Parquet bloom filters
  • 1.2–1.5 GB/s, identical results on every platform
Checked against zlib, mmh3 and xxhash, plus the Iceberg spec's Appendix B vectors

restate

0.3.2

Durable execution in Mojo, via Restate. A Rust shim embeds the official Restate SDK — Rust owns the HTTP/2 endpoint, the event loop and the journal — while your handlers are Mojo, driven by a synchronous loop where every durable operation crosses one C-ABI call.

  • State, sleep, run and awakeables from a plain next() loop
  • app.serve(num_workers) runs that loop on N threads via threads-mojo's WorkerPool
  • Self-calls need two or more workers: one worker has no second thread to run the callee
  • Payloads are raw bytes — parse and serialize in your handler
Checked against Two end-to-end suites against a real restate-server booted per run, on macOS and Linux

threads

0.4.0

Minimal OS threads for Mojo: spawn and join pthreads, share state through atomics and a mutex, and fan a loop out over cores with parallel_for. A stopgap, distilled from flare, until the language ships its own.

  • parallel_for over cores — Mojo currently ships no other way to use a second one
  • Atomics that bridge the stable/nightly std.atomic split
  • Mutex, spawn, join and thread pinning
  • Spawn and join in 14 µs; parallel_for scales ~4×
  • Typed parallel_for and TypedPool: shared state held alive by origin, the void* erasure inside the library
Checked against Contended-count and memory-visibility proofs designed to give a wrong number, not a flake

Cross-implementation oracle

iceberg-rs

0.1.0

Apache Iceberg over a thin Rust cdylib wrapping iceberg-rust behind a C ABI. Superseded — no longer required for any operation — and kept only as a third independent implementation to check the native one against.

  • 56 extern "C" functions over one shared tokio runtime
  • SQL/JDBC catalog against real object storage
  • Kept as a cross-implementation oracle, not a dependency
Checked against PyIceberg reading through the same sqlite catalog file the binding wrote