---
title: "Self-hosting S3 Storage on €5 VPS: Practical Garage Guide"
slug: "self-hosting-s3-storage-5-eur-vps-garage"
published: "2026-06-06"
updated: "2026-06-12"
validated: "2026-06-12"
categories:
  - "Cloudflare"
tags:
  - "self-hosting S3 storage"
  - "Garage S3-compatible storage"
  - "Cloudflare CDN origin"
  - "€5 VPS object storage"
  - "NVMe IOPS optimization"
  - "image delivery architecture"
  - "presigned URL caching"
  - "multi-tenant marketplace storage"
  - "backup and replication strategies"
  - "origin cache miss handling"
llm-intent: "reference"
audience-level: "intermediate"
framework-versions:
  - "garage"
  - "cloudflare"
  - "postgresql"
  - "nvme"
  - "hetzner vps"
status: "stable"
llm-purpose: "Self-hosting S3 storage with Garage on a €5 VPS shows how to run S3-compatible object storage as an origin behind Cloudflare CDN to cut costs and scale."
llm-prereqs:
  - "Access to Garage"
  - "Access to Cloudflare"
  - "Access to PostgreSQL"
  - "Access to NVMe"
  - "Access to Hetzner VPS"
llm-outputs:
  - "Completed outcome: Self-hosting S3 storage with Garage on a €5 VPS shows how to run S3-compatible object storage as an origin behind Cloudflare CDN to cut costs and scale."
---

**Summary Triples**
- (Self-hosting S3 Storage on €5 VPS: Practical Garage Guide, focuses-on, Self-hosting S3 storage with Garage on a €5 VPS shows how to run S3-compatible object storage as an origin behind Cloudflare CDN to cut costs and scale.)
- (Self-hosting S3 Storage on €5 VPS: Practical Garage Guide, category, general)

### {GOAL}
Self-hosting S3 storage with Garage on a €5 VPS shows how to run S3-compatible object storage as an origin behind Cloudflare CDN to cut costs and scale.

### {PREREQS}
- Access to Garage
- Access to Cloudflare
- Access to PostgreSQL
- Access to NVMe
- Access to Hetzner VPS

### {STEPS}
1. Assess your image workload
2. Provision a €5 VPS with NVMe
3. Install and configure Garage
4. Set up backups and replication
5. Put Cloudflare in front as CDN
6. Test cache-hit behavior and limits

<!-- llm:goal="Self-hosting S3 storage with Garage on a €5 VPS shows how to run S3-compatible object storage as an origin behind Cloudflare CDN to cut costs and scale." -->
<!-- llm:prereq="Access to Garage" -->
<!-- llm:prereq="Access to Cloudflare" -->
<!-- llm:prereq="Access to PostgreSQL" -->
<!-- llm:prereq="Access to NVMe" -->
<!-- llm:prereq="Access to Hetzner VPS" -->
<!-- llm:output="Completed outcome: Self-hosting S3 storage with Garage on a €5 VPS shows how to run S3-compatible object storage as an origin behind Cloudflare CDN to cut costs and scale." -->

# Self-hosting S3 Storage on €5 VPS: Practical Garage Guide
> Self-hosting S3 storage with Garage on a €5 VPS shows how to run S3-compatible object storage as an origin behind Cloudflare CDN to cut costs and scale.
Matija Žiberna · 2026-06-06

A €5 Hetzner VPS running Garage can power real production image storage for an early-stage SaaS, marketplace, or multi-tenant platform — as long as you treat it as an origin and let a CDN handle public delivery. The server does not need to serve every image request. It needs to store objects reliably and respond to cache misses. That distinction changes everything about how you size and architect the system.

I recently built this layer for a marketplace platform and spent time stress-testing how far a small server could actually go before the architecture needed to change.

---

## What Is Garage and Why Does It Matter for Self-Hosting?

Garage is an open-source S3-compatible object storage system built for self-hosted deployments. Your application talks to it using the standard S3 API — the same one you would use with AWS — while Garage handles object storage and metadata internally. You can run it on a single VPS or distribute it across multiple nodes.

The appeal for an early-stage product is straightforward: you get S3-compatible storage at infrastructure cost rather than per-request pricing, with full control over where your data lives.

---

## Where a Small VPS Actually Becomes a Bottleneck

Most developers assume CPU is the limiting factor on a cheap server. In practice, for object storage workloads, the first constraints you hit are disk I/O and IOPS, then network bandwidth, then memory and filesystem cache. CPU is usually last.

Every upload, download, listing operation, and delete goes through metadata lookups before the actual object transfer. The storage layer spends a meaningful amount of time waiting on disk rather than saturating the processor. This means a server with a fast NVMe SSD and reasonable RAM will outperform a higher-CPU instance with slow storage.

---

## The Workload: A Real Marketplace Pattern

The use case I was optimizing for looks like this: a multi-tenant marketplace where each tenant has around 80 products, a few images per product, and image sizes between 60 KB and 200 KB.

Admins upload through a dashboard. Visitors browse public storefronts.

This is a very common SaaS pattern, and the upload side is almost never the problem. 80 images at 200 KB each is 16 MB. Even with hundreds of tenants uploading simultaneously, the storage footprint stays manageable and uploads happen in bursts rather than continuously.

Public delivery is the real workload.

---

## Why Image Delivery Is the Dominant Load

Serving images to visitors generates far more sustained load than storing them ever does. The math scales quickly:

| Daily image views | Approximate traffic |
|---|---|
| 1,000 | ~200 MB |
| 10,000 | ~2 GB |
| 100,000 | ~20 GB |

At 10,000 views per day, a server handling every request directly would be pushing 2 GB of transfer plus the associated IOPS for every object read. At 100,000 views, the bandwidth alone exceeds what most €5 VPS plans include in their monthly allowance.

This is the number that determines whether Garage on a small VPS is viable — and the answer depends entirely on whether you put a CDN in front of it.

---

## The Architecture That Makes This Work

The correct setup separates two responsibilities that developers often conflate: storage and delivery.

```
# Upload path
Tenant → Application → Garage

# Public delivery path
Visitor → Cloudflare → Garage (origin, cache miss only)
```

Garage stores originals and any optimized variants. The application manages permissions, generates signed URLs, and handles metadata. Cloudflare sits in front of public assets and serves cached copies to visitors. PostgreSQL stores image references alongside the rest of your application data.

The first time a visitor requests an image, Cloudflare fetches it from Garage and caches it. Every subsequent request for the same image is served from Cloudflare's edge without touching the origin server at all. 10,000 image views may only generate a handful of actual requests back to Garage, depending on your cache hit rate and how frequently your image set changes.

This means the VPS is responsible for uploads, cache misses, image processing, and administrative operations — not for serving every public image request.

---

## Why You Should Not Build Your Own CDN

Self-hosting additional VPSs in multiple regions as a DIY CDN sounds appealing from a cost perspective. The operational surface area makes it impractical for most teams.

Geographic routing, cache invalidation, SSL/TLS management, DDoS protection, health checks, cache purging, and regional failover are all problems a CDN product has already solved. Solving them yourself means building CDN infrastructure alongside your actual product.

Cloudflare's free tier handles the delivery layer well for most early-stage SaaS products. The combination of Garage for storage and Cloudflare for delivery gives you cheap, durable storage with fast global delivery — without the operational overhead of managing edge infrastructure.

---

## FAQ

**Can Garage run on a single-node VPS without data redundancy concerns?**

Single-node Garage works fine for development and early production, but you should have a backup strategy in place. Garage supports multi-node layouts for replication — even spreading across two small VPSs gives you meaningful durability improvement. For a very early product, scheduled snapshots of the storage volume are a reasonable baseline.

**Does Cloudflare cache S3 presigned URLs correctly?**

Presigned URLs include query parameters (expiry, signature) that can interfere with cache key matching. For public assets, you are better off using public bucket paths that Cloudflare can cache by path alone. Reserve presigned URLs for private or permission-gated files that should bypass the CDN entirely.

**What file sizes start to stress a small VPS?**

Large video files or high-resolution unoptimized uploads will strain both storage IOPS and network bandwidth faster than image-heavy workloads. If your use case includes video, either process uploads to lower-resolution variants before storage, or plan for a larger VPS or dedicated storage node sooner.

**How do I handle cache invalidation when a tenant replaces an image?**

The simplest approach is to include a version or hash in the object key rather than overwriting the same path. When an image changes, a new key is written and the old one is retired. This avoids cache invalidation entirely because the URL changes with the content.

**When does this architecture stop scaling?**

The CDN-as-delivery-layer pattern scales well past what most early-stage products ever reach. The origin server becomes relevant again when cache miss volume is high (lots of unique, rarely-repeated requests) or when you are doing significant server-side image processing at request time. Both are solvable with a larger VPS or by moving processing to build time.

---

## Conclusion

A €5 VPS running Garage is not AWS S3 at scale. For an early-stage SaaS, marketplace, or multi-tenant platform, it is far more capable than most developers assume — because the CDN is doing the heavy lifting on public delivery, not the server.

The pattern is straightforward: use Garage as the source of truth for object storage, put Cloudflare in front of it for public delivery, and let each layer do what it is optimized for. The VPS handles uploads and the occasional cache miss. The CDN handles everything else.

If you are building something similar or running into specific scaling questions, drop a comment below. And subscribe if you want more practical guides on self-hosted infrastructure for SaaS products.

Thanks,
Matija

## LLM Response Snippet
```json
{
  "goal": "Self-hosting S3 storage with Garage on a €5 VPS shows how to run S3-compatible object storage as an origin behind Cloudflare CDN to cut costs and scale.",
  "responses": [
    {
      "question": "What does the article \"Self-hosting S3 Storage on €5 VPS: Practical Garage Guide\" cover?",
      "answer": "Self-hosting S3 storage with Garage on a €5 VPS shows how to run S3-compatible object storage as an origin behind Cloudflare CDN to cut costs and scale."
    }
  ]
}
```