COOLJAPAN
← All posts

rs3gw 0.2.2 Released — A C/FFI-Free Storage Profile, protoc-Free Builds, and Per-Bucket Cost Tracking

rs3gw is a Pure Rust S3-compatible object-storage gateway. 0.2.2 adds feature-gated profiles — including a 100% C/FFI-free storage-only build — a pure-Rust protox proto compiler that removes the system protoc requirement, per-bucket usage/cost tracking via /api/usage, and an SSE HEAD Content-Length fix.

release rs3gw s3 object-storage rust pure-rust storage-gateway

Object storage you can audit line by line — now with a storage core that pulls zero C, and a build that needs zero protoc.

Today we released rs3gw 0.2.2 — a substantial patch that carves rs3gw into composable Cargo features, lands a genuinely C/FFI-free storage-only profile, swaps the system protoc build step for a pure-Rust compiler, and gives every bucket request/byte/cost visibility through a new /api/usage endpoint.

No C. No C++. No Go. No Fortran. rs3gw is a drop-in S3-compatible gateway — 100+ operations, the same SDKs and CLIs you already use — but where MinIO is Go and Ceph RGW is C++, rs3gw is Rust the whole way down. With 0.2.2 that claim gets sharper: the storage-only default dependency tree is now genuinely C/FFI-free — no ring, no aws-lc-sys, no native-tls, no zstd-sys, no rustls 0.23 — and the build itself no longer shells out to a system protoc, because a pure-Rust .proto compiler (protox) does that work in-process. One static binary. Sovereign. Auditable end to end.

Why 0.2.2 matters

Technical Deep Dive

The feature architecture. rs3gw is now sliced along clean seams. default = ["server"] keeps the familiar full server (axum, axum-server, tower, tonic, async-graphql, utoipa, the Prometheus exporter, OpenTelemetry/OTLP, reqwest webhooks). local = [] is the storage-only profile. Cloud backends are feature-gated: s3 (aws-sdk-s3 1.132 + aws-config), gcs (google-cloud-), azure (azure_); columnar/serialization formats live behind formats (parquet, arrow, apache-avro, orc-rust, prost-reflect, rmp-serde); and all-backends activates all four at once. The binaries carry required-features so they never break the storage-only build: rs3ctl requires ["server"], s3-migrate requires ["s3","server"], and testdata-generator requires ["formats"]. Across the test suite, server-only integration files now carry #![cfg(feature = "server")], format-dependent modules carry #[cfg(feature = "formats")], and the select_object_content handler and its XML select parser are gated behind formats too — so when a feature is off, those modules compile out cleanly rather than dragging in dependencies. The payoff is the Pure-Rust default closure: with default-features = false, features = ["local"], the C/FFI surface is gone.

protox in build.rs. Generating Rust from .proto used to mean a protoc binary on the PATH. 0.2.2 replaces that with protox 0.9, a pure-Rust compiler: build.rs calls protox::compile(...) to emit a FileDescriptorSet, which tonic-prost-build consumes to produce the gRPC bindings. The build is now hermetic and toolchain-free beyond Cargo and rustc (1.85+).

UsageTracker and /api/usage. src/observability/usage.rs introduces an in-memory, per-bucket accumulator. It tracks PUT/GET/DELETE request counts, bytes uploaded and downloaded, and live storage size and object count. That data backs the new REST endpoints under src/api: /api/usage returns a report with per-bucket storage_bytes, object_count, bytes_uploaded, bytes_downloaded, requests_by_op, total_requests, and estimated_cost.total_usd, plus report-level total_objects, total_storage_bytes, and generated_at. Pass ?flush=true and it invokes any registered cost-hook callbacks — the seam where you wire in real billing.

The SSE HEAD Content-Length fix. Previously, HEAD on an SSE-encrypted object reported the ciphertext length sitting on disk, while GET streamed the (shorter) plaintext — an inconsistency that tripped up clients. In src/storage/encryption.rs, HEAD now loads the encryption sidecar and derives the plaintext size: for chunked/multipart objects it sums the per-chunk plaintext_len fields; for single-PUT objects it computes single_shot_plaintext_len(ciphertext_len). If the sidecar is unavailable, it falls back, best-effort, to the on-disk size. HEAD and GET now agree.

Compression throughout src/storage runs on OxiArc — oxiarc-zstd, oxiarc-lz4, and oxiarc-deflate 0.3.3 — pure-Rust codecs, no zstd-sys in the default tree.

Getting Started

Build the server. Default features include server, and there is no system protoc to installprotox compiles the .proto definitions in pure Rust:

git clone https://github.com/cool-japan/rs3gw.git
cd rs3gw
git checkout v0.2.2
cargo build --release         # no system protoc needed — protox compiles .proto in pure Rust
./target/release/rs3gw

Library consumers who want only the storage layer get the new C/FFI-free default tree:

# Cargo.toml
rs3gw = { version = "0.2.2", default-features = false, features = ["local"] }

Make a real S3 call and read the new usage endpoint (default port :9000):

aws --endpoint-url http://localhost:9000 s3 cp report.parquet s3://analytics/
curl http://localhost:9000/api/usage            # per-bucket requests, bytes, estimated cost
curl http://localhost:9000/api/usage/analytics  # one bucket

What’s New in 0.2.2

Modularity & Pure Rust

Observability

Testing

Fixes

Deps

Tips

This is the foundation

rs3gw sits squarely inside the COOLJAPAN ecosystem. It’s built on scirs2-io and the broader SciRS2 stack (now 0.5.0), compresses through OxiArc 0.3.3, and builds with pure-Rust protox — no system toolchain beyond Cargo and rustc. It lives alongside SciRS2, NumRS2, OptiRS, PandRS, OxiBLAS, OxiCode, and OxiZ: a coherent, sovereign, all-Rust foundation where each layer is auditable and replaceable.

Repository: https://github.com/cool-japan/rs3gw

Object storage shouldn’t require you to trust a binary you can’t read. With 0.2.2, the storage core is pure Rust, the build is hermetic, and every byte and dollar is something you can query.

Star the repo if you believe infrastructure should be sovereign, auditable, and C-free.

KitaSan at COOLJAPAN OÜ June 17, 2026

↑ Back to all posts