Zum Inhalt springen
use-cases / ci-cache-without-s3 / hero
FILES · CACHE · COST-OPTIMIZE

Der CI-Cache, der keine S3-Rechnungsposition ist

Die meisten CI-Pipelines verbrennen Geld an Cache-Traffic — Artefakte zu S3 pushen, sie beim nächsten Job wieder ziehen, für Storage zahlen, für Egress zahlen, nochmal zahlen, wenn Runner die Region wechseln. Auf Hoody ist der Cache ein Ordner auf demselben Bare Metal, das deinen Build-Container ausführt. Schick ein Tarball mit curl. Zieh es mit curl. Die Bytes verlassen die Box nie.

Files-API lesen
use-cases / ci-cache-without-s3 / mechanism

Drei Curls und ein Cron

Der gesamte CI-Cache sind drei Befehle und ein Cleanup-Job. PUT, um ein Tarball zu schreiben. GET, um es zu lesen. find -atime, um aufzuräumen. Es gibt kein viertes Teil — keine IAM-Policy, kein Bucket-Lifecycle, keine Signed-URL-Zeremonie.

WRITE

Komprimieren und PUT

Nach Install streamt der Runner node_modules durch tar | zstd in ein einziges PUT auf /files/cache. Hoody schreibt den Body als einen Binary-Blob auf Disk. Kein Multipart, kein Part-Uploader, kein SDK.

# Nach yarn install das Artefakt pushentar c node_modules | zstd -T0 | curl -T - https://files.containers.hoody.com/cache/$KEY.tar.zst
READ

GET und untar

Der erste Schritt im nächsten Job ist ein curl. Der Body kommt von NVMe mit Leitungsgeschwindigkeit, weil der Cache auf derselben physischen Box wie der Runner liegt — kein Egress-Hop, kein Cross-AZ-Pull, keine CloudFront-Edge.

# Nächster Job: ziehen und untar in einer Zeilecurl -fsS https://files.containers.hoody.com/cache/$KEY.tar.zst | tar x -I zstd
PRUNE

find -atime · nächtlich

Hoody Cron feuert einmal pro Nacht. find /files/cache -atime +30 -delete wirft alles raus, was kein Job seit einem Monat gelesen hat. Keine Retention-Policy, keine Glacier-Tier, kein Lifecycle-JSON zum Pflegen.

# Nächtlicher Cron — alles 30T ungelesen ist wegfind /files/cache -atime +30 -delete

PUT schreibt. GET liest. find räumt auf. Die Hoody-Files-API ist der Cache-Server, die Aufräum-Engine und das Audit-Log — alles hinter derselben /files/[path]-URL.

use-cases / ci-cache-without-s3 / powers

Drei Stärken von Cache-als-Ordner

Den Cache zu einem separaten Anbieter zu schieben, ergab Sinn, als Storage knapp war. Auf einem Bare-Metal-Container fügt es einfach einen Anbieter hinzu.

ÖKONOMIE

Kein GB-Monat, kein Egress, keine Requests

S3 berechnet drei Zähler: Storage, Egress und pro Request. Hoody Files ist im Pauschalserver-Preis enthalten — die Disk, die du eh schon mietest, ist die Disk, auf der der Cache sitzt. Die Bytes überschreiten nie eine Abrechnungsgrenze.

LATENZ

NVMe statt cross-region

Reads kommen von derselben physischen Box, die den Build ausführt. Kein S3-Endpoint zum Auflösen, kein TLS-Handshake zu einer Region, kein Rate-Limit auf Prefix-Throughput. Ein 1,4-GB-Rust-Target packt in Sekunden aus.

OWNERSHIP

Eine Vendor-Beziehung, nicht zwei

Dein Runner und dein Cache leben auf derselben Instanz, werden auf derselben Rechnung abgerechnet, werden mit derselben SSH-Session debuggt. Wenn du den Container ausschaltest, ist der Cache das Disk-Image — wieder online in dem Moment, in dem du ihn hochfährst.

use-cases / ci-cache-without-s3 / invoice

Was von der Rechnung verdunstet

Ein typischer mittelgroßer CI-Footprint bewegt etwa 1,4 TB Cache-Traffic pro Monat. Hier ist die Rechnungsposition, die er auf AWS aufbaut; bei Hoody läuft der Cache im Pauschalserver, den du eh schon zahlst.

VORHER · S3-RECHNUNGdiesen Monat, auf AWS
  • Storage · GB-Monat$1.0947,2 GB × $0.023
  • Egress · GB raus$127.801,42 TB × $0.090
  • PUT-Requests$2.06412k × $5/M
  • GET-Requests$4.5611,4M × $0.40/M
  • CloudFront / NAT−$57.71Cross-AZ-Pull
Monats-Total$78
fünf Posten · fünf Sätze · ein Bucket
NACHHER · HOODY FILESdiesen Monat, auf Hoody
  • Festplatte auf dem Serverno extra chargein den monatlichen Pauschalserver-Preis einbegriffen
  • Egress zwischen Jobsno extra chargeLoopback · bleibt auf der Box
  • PUT- / GET-Requestsno per-request or per-GB meterkein Pro-Request-Zähler
  • Vendor-Beziehungno extra chargeder Runner und der Cache sind eine Rechnung
  • 47,2 GB genutztvom PlanSpielraum auf der gleichen Server-Disk, die du eh schon mietest
Monats-Totalincluded in server price
eine Disk · eine Rechnung · null neuer Anbieter

Wenn der Cache auf der Box lebt, die den Build ausführt, hat der Zähler, den S3 laufen ließ, nichts zu lesen. Die Position bewegt sich nicht, weil es keine Transaktion gibt, die abzurechnen wäre.

use-cases / ci-cache-without-s3 / capacity

Was der Files-Endpoint garantiert

Hoody Files ist kein dünner Wrapper — es ist ein echtes persistentes Backend mit Hashing, History, Range-Reads und einem Audit-Journal. Der CI-Cache nutzt eine dünne Schicht von dem, was tatsächlich offengelegt ist.

  1. EINE URL · JEDES ARTEFAKT/files/[path]

    PUT zum Schreiben, GET zum Lesen, HEAD für ETag und Content-Length, ?hash für SHA256, ?stat für Metadaten. Der Cache ist dieselbe Endpoint-Familie, die Logs, Builds und geteilte Artefakte antreibt.

  2. ZEITREISE-READS?at · ?revision

    Jeder Schreibvorgang läuft durch das File-Journal. Zieh den Cache von gestern per Timestamp oder per Revisionsnummer pro Pfad — ein Flake zu debuggen erfordert kein separates Snapshot-Tool mehr.

  3. MOUNTEN, WENN DU IHN ENTWÄCHST60+ Backends

    Wenn der Cache wirklich in S3, B2 oder einem Drive-Ordner leben muss, mounte ihn als Backend und behalte dieselbe /files/[path]-URL. Der Runner-Code ändert sich nie — der Cache zieht einfach um.

Zahlen spiegeln die veröffentlichte Hoody-Files-API-Oberfläche wider — `GET/PUT/HEAD/PATCH /api/v1/files/[path]`, die Query-Parameter `?hash`/`?stat`/`?at`/`?revision`/`?history` und die File-Journal-Endpoints unter `/api/v1/journal`.

use-cases / ci-cache-without-s3 / punchline

Dein CI-Cache hört auf, ein separater Anbieter zu sein. Er ist ein Ordner auf der Box, die du eh schon mietest.

gestern · fünf Sätzeheute · eine Disk
WAS AUF DER ALTEN RECHNUNG STANDS3-Bucket + Egress + Requests + Lifecyclefünf Posten · separate IAM · separater Anbieter
WAS ES JETZT ISTPUT /files/cache/$KEY · GET /files/cache/$KEYzwei Curls — und der Cache ist die eigene Disk des Runners
Files-Spec lesen
use-cases / ci-cache-without-s3 / replaces

Was das ersetzt

Die Standard-Cache-Backends, zu denen man greift, berechnen jeweils eine Vendor-Beziehung, eine Egress-Rechnung oder eine Pro-Build-Gebühr. /files berechnet dir nichts davon.

  • AWS S3 Bucket-as-CacheStorage, Egress, Requests — drei Zähler für ein Tarball, das du zwei Tage behältst
  • GitHub Actions Cache10 GB gratis, danach Pro-GB-Gebühren und eine 7-Tage-Eviction, die du nicht tunen kannst
  • BuildJet CachePro-Runner-Preise für Storage, das eh außerhalb des Runners lebt
  • Bazel Remote Cache ServicesEin ganzer zweiter Daemon und ein Cache-Protokoll zum Babysitten
  • Turborepo Remote CachePro-Build-Preise für ein Tarball, das dein Monorepo eh schon produziert
  • Earthly Cloud CacheEin verwaltetes Remote-Backend für das, was nur curl + tar ist
use-cases / ci-cache-without-s3 / cta

Hör auf, einen Cache von einer zweiten Cloud zu mieten. Schreib das Tarball auf die Disk, die du eh schon zahlst, und curl es zurück.

Files-API lesen
use-cases / ci-cache-without-s3 / related

Lies die anderen