Garage Object Storage on PMSS
Garage turns two or three Pulsed Media boxes into a single S3 cluster you own outright, with every object replicated across the nodes so one box can go down and your data stays readable. It is a single, dependency-free binary that speaks the Amazon S3 API, built by the French collective Deuxfleurs to run over the open Internet between machines that do not share a backbone. Where rclone serve s3 and MinIO put an S3 endpoint on one box, Garage is the option when you want the endpoint spread across several boxes for redundancy — and the keys, the data, and the failure domain all stay in your hands, inside Pulsed Media's Finnish datacenters.
When Garage is the right tool
On a single box, rclone serve s3 is simpler and lighter — use that. Garage earns its place when you run more than one Pulsed Media box and want them to back each other up automatically:
- A storage box in Lauttasaari and another in Kerava, replicating every object across both — an object survives the loss of an entire node.
- A storage box plus a home server or a friend's box, stitched into one bucket namespace.
- Any S3 application (rclone, restic, Nextcloud, PeerTube, a Proxmox Backup Server S3 datastore) pointed at a cluster instead of a single point of failure.
You get the S3 interface without renting cloud object storage, without per-request or egress fees, and without a single box being able to take the whole store down with it.
What people run on it
Because Garage speaks the S3 API, it fits anywhere an application expects a bucket. The Garage project and its community run it as a backup target for restic and rclone, as the media backend for Matrix, Mastodon and PeerTube servers, as storage behind Nextcloud, and as a host for static websites, since a bucket can serve a site directly over HTTP. On Pulsed Media the fits are the same, with one difference: the cluster, the keys, and the hardware are all yours, in Finland. Common uses:
- Offsite backups that survive the loss of a whole box, not just a disk.
- A media library for a self-hosted Plex or Jellyfin setup, or for a Matrix/Mastodon/PeerTube instance.
- Object storage for any app you run on a Seedbox or storage box that wants S3 instead of a filesystem.
- A self-owned alternative to cloud object storage, with no per-request or egress fees.
What one node needs
Garage is deliberately light. Per node: 1 GB RAM, at least 16 GB of disk, any x86-64 CPU from the last decade (or ARMv7/ARMv8), and a network link under 200 ms with 50 Mbps or more between nodes. Three nodes is the natural minimum, because Garage replicates each chunk of data across three separate zones.
The 1 GB figure is a headroom recommendation, not a hard floor, and what it sizes is metadata. In a test cluster a garage server process held about 15 to 20 MB of resident memory when empty, both idle and while writing a 20 MB object at full speed: Garage streams data in fixed-size blocks rather than buffering whole objects, so a large upload passes through in pieces instead of being held in memory. Memory then grows with the number of stored objects, because each object's metadata lives in a memory-mapped database. Measured on a single node, that cost is about 0.9 KB per object (counted as total container memory, some of which is reclaimable cache, so the hard floor is a little lower): roughly 65 MB at 50,000 objects, and by extrapolation on the order of 1 GB only as a node nears a million objects. A node holding thousands to tens of thousands of objects runs in tens of megabytes and fits inside a storage box's resources with room to spare; the full 1 GB earns its place when a node holds hundreds of thousands of objects or serves heavy concurrent traffic.
How replication works
Garage splits objects into chunks and stores a copy of each chunk in three different zones. A zone is a failure domain you define — on PMSS, put each box in its own zone, and ideally split them across both Finnish datacenters so the loss of one site cannot take out more than one copy. The cluster agrees on where each chunk lives using a layout you assign; when a node goes away, reads are served from the surviving copies, and when it returns, Garage re-syncs it. This is the same class of design as Amazon's Dynamo paper, built on conflict-free replicated data types.
Availability and redundancy
Garage keeps three copies of every data block by default (replication factor 3), one per zone, and it decides reads and writes by quorum. In the default consistent mode a write is acknowledged once a majority of zones (two of three) have stored it, and reads need the same majority, so the cluster keeps full read-after-write consistency even while an entire zone is offline. Lose one zone of three and it keeps serving both reads and writes; the object read back with a node stopped, below, is exactly this at work.
Two looser modes exist when availability matters more than strict consistency. degraded drops the read quorum to 1, so data stays readable when more than one zone is down, at the cost of read-after-write consistency. dangerous drops both quorums to 1, giving up most durability guarantees, and is for niche cases only. The replication factor and consistency mode live in each node's config and must match across the cluster.
Garage also heals itself. Block-resync workers rebuild missing copies onto a returning or replacement node, and an automatic scrub runs every 25 to 35 days, reading every block and checking it against its hash so silent disk corruption is caught and repaired from a healthy replica. A scrub or rebuild can also be started by hand with garage repair.
Verified behaviour
A three-node cluster (replication factor 3, one zone per node) was exercised end to end: create a bucket and key, upload an object over the S3 API, then stop one node. With a third of the cluster down, the same object still read back byte for byte — Garage served it from the surviving replicas. Restarting the node let it rejoin and resync. This exercise validates Garage's own clustering and replication behaviour; running a cluster across separate Pulsed Media boxes follows the identical steps, with per-box network reachability (the RPC port reaching between boxes) being the setup-specific part to confirm.

Building a cluster on PMSS
The shape is the same on every node: drop the Garage binary into your home directory, give all nodes the same shared secret and a minimal config, connect them, assign a layout, then create a bucket and a key. Everything lives under your home directory — nothing touches the system.
1. Install the binary on each box
mkdir -p ~/bin # download the static garage binary for your architecture from garagehq.deuxfleurs.fr/download chmod +x ~/bin/garage garage --version
2. Write a config on each box
Every node shares one rpc_secret (a 32-byte hex value from openssl rand -hex 32). Metadata and data directories go under your home; bind the RPC and S3 ports to ports you control.
metadata_dir = "/home/USERNAME/garage/meta" data_dir = "/home/USERNAME/garage/data" replication_factor = 3 rpc_bind_addr = "[::]:3901" rpc_secret = "PASTE-openssl-rand-hex-32-HERE" [s3_api] api_bind_addr = "[::]:3900"
Start the daemon on each node with garage server.
3. Form the cluster
garage node id # get each node's identifier garage node connect <node-id>@<box>:3901 # connect the other nodes (one direction is enough) garage layout assign <node-id> -z <zone> -c <capacity> -t <tag> # -z is the zone (put each DC in its own) garage layout show garage layout apply --version 1 garage status # all three nodes HEALTHY
4. Create a bucket and a key
garage bucket create mybucket garage key create mykey # prints the access key and secret garage bucket allow --read --write mybucket --key mykey
5. Point an S3 client at it
Configure rclone (pre-installed on every box) with an s3 remote using the access key, the secret, and your S3 endpoint (http://BOX:3900), then upload as normal. Any S3 client works the same way.
Managing the cluster
Everything runs from the garage command-line tool: garage status shows node health and zones, garage layout manages capacity and placement, garage bucket and garage key handle buckets and access keys, garage worker and garage stats expose the background workers and per-table counts, and garage repair runs scrubs and rebuilds. For automation there is an HTTP Admin API (guarded by an admin token) and a Prometheus metrics endpoint, so a cluster wires into the same dashboards and alerting as the rest of your infrastructure. Garage ships as a single binary with systemd, Docker, Kubernetes and Ansible deployment paths, and a community-maintained web UI exists for operators who prefer a dashboard to the command line.
Security
Use long, random values for the RPC secret and every access key — these are what stand between your cluster and anyone who can reach the ports. Bind the S3 and admin ports to a VPN or a known client IP if you do not need them public. Garage moves and replicates bytes; it does not encrypt them for you, so combine it with client-side encryption when the data is sensitive.
Garage vs the single-box options
| Option | Nodes | Survives a node loss? | Best for |
|---|---|---|---|
| rclone serve s3 | 1 | No | The simplest S3 endpoint on one box |
| MinIO (rootless Docker) | 1 | No | One box, plus a web console and bucket policies |
| Garage | 3+ | Yes | A self-owned, redundant S3 spread across boxes |
For a single box, use rclone serve s3. Reach for Garage when you have the boxes to spread the risk across.
See also
- S3 Object Storage on PMSS — the single-box S3 options (rclone serve s3, MinIO)
- Storage Boxes — the disk a Garage cluster runs on
- Backup Proxmox with Pulsed Media Storage Box — S3 as a Proxmox Backup Server datastore
- Rclone — the S3 client used in the walkthrough
- Client-Side Encryption for Your Seedbox or Storage Box — encrypt before it reaches the cluster
- Pulsed Media Storage Box vs Hetzner Storage Box — how PM's storage box compares to Hetzner's