7 Punkte von GN⁺ 2025-12-27 | 2 Kommentare | Auf WhatsApp teilen
  • Mehrere Paketmanager nutzten Git wie eine Datenbank, weil Versionsverwaltung und Zusammenarbeit bequem sind, stießen mit wachsender Größe jedoch auf Performance- und Wartungsprobleme
  • Cargo, Homebrew und CocoaPods wechselten schließlich wegen der wachsenden Größe ihrer Git-Indizes, langsamer Updates und Ineffizienz in CI-Umgebungen zu HTTP-basierten Indizes oder CDNs
  • vcpkg arbeitet weiterhin auf Basis von Git-Tree-Hashes; in Umgebungen mit flachen Klonen (shallow clone) kommt es zu Build-Fehlschlägen und komplizierten Workarounds
  • Das Go-Modulsystem führte GOPROXY und eine Prüfsummendatenbank (sumdb) ein, entfernte damit die Git-Abhängigkeit und verbesserte Sicherheit und Geschwindigkeit
  • Git ist für die Zusammenarbeit an Code hervorragend geeignet, erweist sich jedoch immer wieder als ungeeignet für Paket-Metadatenabfragen oder die Verwaltung großer Register

Das wiederholte Scheitern von Versuchen, Git als Datenbank zu verwenden

  • Git ist wegen Vorteilen wie Versionshistorie, verteilter Struktur und kostenlosem Hosting attraktiv, stößt als Datenbank aber an Skalierungsgrenzen
  • Mehrere Paketmanager übernahmen Git als Index, doch mit der Zeit nahmen Leistungseinbußen und Infrastrukturbelastung zu

Cargo

  • Der crates.io-Index begann als Git-Repository, und alle Clients führten eine vollständige Replikation (clone) durch
    • Als das Repository wuchs, entstand in der Delta-Resolution-Phase ein Performance-Flaschenhals in libgit2
    • In CI-Umgebungen wurde bei jedem Build der komplette Index heruntergeladen, was zu erheblicher Verschwendung führte
  • Mit RFC 2789 wurde das sparse-HTTP-Protokoll eingeführt, sodass nur die benötigten Metadaten per HTTPS abgerufen werden
    • Stand April 2025 nutzen 99 % der Anfragen den sparse-Modus
    • Der Git-Index existiert weiterhin, wird von den meisten Nutzern aber nicht mehr verwendet

Homebrew

  • GitHub bat Homebrew darum, keine flachen Klone mehr zu verwenden; Updates wurden als „sehr teure Operation“ bezeichnet
    • Der .git-Ordner von homebrew-core nähert sich 1 GB, und bei Updates kommt es durch Delta Resolution zu Verzögerungen
  • Im Februar 2023 stellte Homebrew 4.0.0 Tap-Updates auf einen JSON-Download-Mechanismus um
    • Durch den Wegfall von Git fetch wurden Updates schneller, und der automatische Update-Zyklus änderte sich von 5 Minuten auf 24 Stunden

CocoaPods

  • Beim Paketmanager CocoaPods für iOS/macOS wurde das aus Hunderttausenden podspecs bestehende Specs-Repository übermäßig groß
    • Klonen und Aktualisieren dauerten mehrere Minuten, und der Großteil der CI-Zeit ging für Git-Operationen drauf
  • GitHub führte ein CPU-Rate-Limit ein; flache Klone wurden als Ursache der Serverlast benannt
  • Das Team setzte Übergangsmaßnahmen wie das Abschalten automatischer Fetches, den Wechsel zu vollständigen Klonen und das Sharding des Repositorys um
  • Ab Version 1.8 erfolgte der Wechsel zu CDN-basierter HTTP-Auslieferung, wodurch bei Nutzern etwa 1 GB Speicherplatz eingespart und die Installationsgeschwindigkeit deutlich verbessert wurde

Nixpkgs

  • Nix vermeidet auf Client-Seite bereits Git-Klone durch tarball-basierte Channels
    • Paketausdrücke werden per HTTP über S3 und CDN bereitgestellt
  • Die Infrastruktur von GitHub wird jedoch durch ein 83-GB-Repository und 20.000 Forks belastet
    • Im November 2025 meldete GitHub fehlgeschlagene Einigungen zwischen Replikaten und Fehler bei Wartungsarbeiten
    • Lokale Klone sind zwar 2,5 GB groß, aber das gesamte Fork-Netzwerk belastet den GitHub-Speicher stark

vcpkg

  • vcpkg, der C++-Paketmanager von Microsoft, versioniert mit Git-Tree-Hashes
    • Um über builtin-baseline die Ports eines bestimmten Commit-Zeitpunkts reproduzieren zu können, wird die vollständige Historie benötigt
  • In Umgebungen mit flachen Klonen (GitHub Actions, DevContainers) schlagen Builds fehl
    • Als Lösung ist die Einstellung fetch-depth: 0 nötig, was den Download der gesamten Historie erfordert
  • Aufgrund der Struktur von Git-Tree-Hashes ist kein Commit-Tracking möglich; das Problem ist wegen struktureller Grenzen nicht behebbar
  • Unterstützt werden weiterhin nur registerbasierte Git-Repositories, HTTP- oder CDN-Alternativen gibt es nicht

Go-Modulsystem

  • Das Engineering-Team von Grab verkürzte nach Einführung eines Modul-Proxys die Zeit für go get von 18 Minuten auf 12 Sekunden
  • Im bisherigen Verfahren musste das gesamte Repository jeder Abhängigkeit geklont werden, um go.mod lesen zu können
  • Das Go-Team hatte Bedenken wegen der Abhängigkeit von VCS-Werkzeugen und Sicherheitslücken
  • Seit Go 1.13 ist GOPROXY der Standard; Modulquellen und go.mod werden per HTTP bereitgestellt
    • sumdb (Prüfsummendatenbank) gewährleistet Integrität und Dauerhaftigkeit der Module

Allgemeine Probleme beim Einsatz von Git als Datenbank

  • Git-basiertes Wiki (Gollum) wird bei großen Repositories bei der Verzeichnisnavigation und beim Laden von Seiten langsam
    • GitLab plant, die Nutzung von Gollum einzustellen
  • Git-basiertes CMS (Decap) stößt an das GitHub-API-Limit von 5.000 Anfragen
    • Ab etwa 10.000 Einträgen sinkt die Leistung, und neue Nutzer mit leerem Cache verursachen eine Anfragenflut
  • GitOps-Tool (ArgoCD) hat beim Klonen von Repositories Probleme mit überschrittenem Speicherplatz
    • Ein einzelner Commit invalidiert den gesamten Cache, und große Monorepos benötigen gesonderte Skalierung

Strukturelle Gründe, warum Git als Datenbank ungeeignet ist

  • Verzeichnisgrenzen: Mit steigender Dateizahl wird Git langsamer
    • CocoaPods erzeugte wegen 16.000 Verzeichnissen riesige Tree-Objekte und löste das Problem durch hashbasiertes Sharding
  • Groß-/Kleinschreibung: Git unterscheidet sie, macOS und Windows jedoch nicht
    • Azure DevOps ergänzte serverseitige Sperren, um Konflikte zu verhindern
  • Beschränkung der Pfadlänge: Das Windows-Limit von 260 Zeichen verursacht Fehler bei git status
  • Fehlende Datenbankfunktionen:
    • Es gibt keine CHECK-/UNIQUE-Constraints, keine Sperren, keine Indizes und keine Migrationsfunktionen
    • Jeder Paketmanager muss eigene Systeme für Validierung und Indizierung aufbauen

Fazit

  • Git ist für die Zusammenarbeit an Quellcode hervorragend geeignet, jedoch ungeeignet für Paket-Metadatenabfragen oder die Verwaltung großer Register
  • Die meisten Paketmanager wechseln am Ende zu HTTP-basierten Indizes oder Datenbanken
  • Die Vorteile von Git (Versionshistorie, PR-Workflow) sind attraktiv, doch als Datenbankersatz scheitert es
  • Auch wenn ein Git-Index beim Entwurf eines neuen Paketmanagers attraktiv wirkt, stößt man wie bei Cargo, Homebrew, CocoaPods, vcpkg und Go auf dieselben Grenzen

2 Kommentare

 
GN⁺ 2025-12-27
Hacker-News-Kommentare
  • Das wirkt wie eine Art Tragödie der Allmende. GitHub ist kostenlos und bietet viele großartige Funktionen, also wollen es alle nutzen. Aber solche Entscheidungen treten immer dann auf, wenn es Externalitäten gibt.
    Die für mich wichtigste Externalität ist die Zeit der Nutzer. Die meisten Softwareunternehmen achten nur auf die Kosten der Engineering-Zeit und ignorieren die Zeit der Nutzer. Sie konzentrieren sich auf die Entwicklung von Features, optimieren aber nicht die Zeit, die für die Interaktion der Nutzer benötigt wird. Wenn ich zum Beispiel 1 Stunde darauf verwende, eine App 1 Sekunde schneller zu machen, sparen eine Million Nutzer pro Jahr 277 Stunden. Aber weil Nutzerzeit eine Externalität ist, findet diese Art von Optimierung fast nie statt
    Am Ende laden Nutzer unnötig mehr Daten herunter und warten länger, und die Entwickler tragen für diese Verschwendung keine Verantwortung

    • Ich weiß nicht genau, was mit dem Ausdruck „Software House“ gemeint ist, aber bei den meisten Consumer-Softwareprodukten, an denen ich gearbeitet habe, wurden Kennzahlen wie Startgeschwindigkeit oder Latenz als Kerngrößen verfolgt. Das ist seit Jahrzehnten selbstverständlich. Man hörte zum Beispiel oft, dass Amazon durch ein paar Millisekunden Unterschied bei der Seitenladezeit Millionen Dollar verliert
    • Das steht im selben Zusammenhang wie die Aussage, dass Geschwindigkeit ebenfalls ein Feature ist. Allerdings wird die Zeit der Nutzer nicht nur von der reinen Performance, sondern auch stark vom UI-Design beeinflusst
    • Ich glaube nicht, dass das eine „Tragödie der Allmende“ ist. GitHub gehört Microsoft, also haben sie entschieden, dass sie das tragen können. Eine echte Allmende müsste so strukturiert sein, dass sie niemandem gehört und alle davon profitieren
    • Wenn man über dieses Problem tiefer nachdenkt, fällt einem Alan Kays Aussage ein — „Wenn dir Software wirklich wichtig ist, musst du auch die Hardware selbst bauen“. Laden über das Netzwerk ist im Kern eine schlechte Nutzererfahrung. Wenn man Nutzer wirklich respektiert, muss man **Local-First-/Native-First-**Anwendungen bauen. Aber Unternehmen, die die Nutzererfahrung so weit respektieren, sind extrem selten
    • Andy Hertzfelds Text „Saving Lives“ ist in diesem Zusammenhang interessant — dort gibt es die Anekdote: „Das Starten des Macintosh ist viel zu langsam. Wir müssen es schneller machen!“
  • Ich baue Cargo/UV für C. Toller Artikel, ich kann dem sehr gut nachfühlen.
    Gerade am Anfang ist der Betrieb einer Registry wirklich schwierig. Man muss sich nicht nur um das Schreiben von Code, die Qualität der Tools und den Community-Aufbau kümmern, sondern auch um Infrastruktur, die weltweiten Traffic verkraftet. In so einer Situation ist eine Git-basierte Lösung attraktiv
    Das Problem ist aber sparse checkout. Ich möchte Paketmanifeste per git versionieren, aber weil beliebige Commits nachverfolgt werden müssen, ist das ineffizient. Am Ende entsteht eine Struktur, in der man zwei Commits pushen muss, was in der Praxis kaum machbar ist
    Ich halte den Ansatz von Conan für am praktikabelsten. Statt perfekter Reproduzierbarkeit packt man bedingte Logik in das Manifest. Auch ein Mapping von Manifesten nach Versionsbereichen ist möglich. Nicht perfekt, aber ein praktischer und nützlicher Kompromiss.
    Natürlich wäre die echte Lösung eine Datenbank, aber da einem niemand die Server- und Betriebskosten abnimmt, ist das realistisch schwer umzusetzen

    • Aus einem anderen Blickwinkel betrachtet sind die meisten erfolgreichen Paketmanager anfangs Git-basiert gestartet und erst später, bei Bedarf, auf eine effizientere Struktur umgestiegen
    • Auch der Ansatz des Arch Linux AUR ist eine Überlegung wert. Jedes Paket hat ein eigenes Git-Repository und enthält nur das Manifest. So vermeidet man Monorepo-Probleme oder Albträume mit Referenzen
    • Es ist auch attraktiv, ein Repository über ein simples HTTP-Backend wie S3 zu betreiben. Am Anfang startet man mit einem einzelnen Server, und wenn es populär wird, sucht man Sponsoren und zieht in die Cloud um.
      Wenn Geld und Unabhängigkeit das Problem sind, wäre auch ein P2P-Ansatz möglich. Wenn allerdings CI-Caching nicht funktioniert, kann der Traffic explodieren
    • Wenn man noch nicht viele Nutzer hat, ist es verfrühte Optimierung, vorab Infrastruktur für die ganze Welt bereitzustellen
    • Es gibt keinen Grund, Nutzern unbedingt alle Historiedaten zu zeigen. Mit einem post-commit hook kann man nur den HEAD-Zustand als statische Dateien rendern und wie bei GitHub Pages bereitstellen.
      Als Referenz taugt auch die Mirror-Struktur von Linux-Distributionen wie Debian, Fedora oder openSUSE
  • Dieser Artikel vermischt zwei Probleme. Das eine ist, git als Datenbank für einen Paketindex zu verwenden, das andere, den Code jedes Pakets per git zu holen. Das sind getrennte Dinge.
    Den Index kann man in git haben und die Pakete als zip/tar ausliefern, oder umgekehrt. Bei Go gibt es sogar gar keinen Index

    • Der Autor wirkt etwas verwirrt. Der Aussage „Lasst nicht alle Nutzer die Datenbank replizieren“ stimme ich zu, aber daraus folgt nicht, dass man den Git-Graphen nicht zur Datenkodierung verwenden dürfte.
      Dinge wie GitHubs Backend-Implementierung oder 20.000 Forks sind für den Kern des Problems irrelevant. Auch ohne Git-Working-Tree sind effiziente Key-Value-Lookups möglich.
      Die Behauptung, „Git-History-Rewrites entsprächen DB-Migrationen“, ist ebenfalls seltsam. Wäre es dann nicht besser, einfach eine Postgres-Instanz zu betreiben?
    • Der eigentliche Punkt des Artikels liegt nicht beim Code selbst, sondern beim Prozess, die go.mod-Datei zu holen. Deshalb wurde als Lösung go.mod separat gehostet
    • Auch mit git kann man nur die benötigte einzelne Datei holen, aber strukturell bleibt das trotzdem etwas unpassend
  • Der Ansatz „Nimm die einfache Lösung, solange sie funktioniert, und repariere es, wenn sie nicht mehr funktioniert“ ist realistisch.
    Julia macht es genauso, und weil es im Vergleich zu Rust nur etwa ein Siebtel so viele Pakete gibt, ist es bisher kein Problem.
    Man könnte das verbessern, indem man nur die oberste Registry.toml-Datei abruft und dann nur die benötigten Pakete herunterlädt. Kein großes Problem

    • Julia nutzt die Git-Registry nur als offizielles Ledger, während der eigentliche Client das Pkg Protocol verwendet
    • Man könnte diesen Ansatz auch als Geist von FAFO (einfach ausprobieren und auf die Nase fallen) bezeichnen. Praktisch ist es, aber persönlich mag ich das nicht
    • Ich halte diese Haltung für unethisch. Diese Denkweise von „erstmal einfach bauen und später reparieren“ vergrößert am Ende nur die technische Schuld.
      Die Kultur von „Move fast and break things“ hat die langsame und fehleranfällige Software hervorgebracht, die wir heute sehen
    • Wenn man Probleme später behebt, steigen die Kosten exponentiell. Am Ende landet man bei „Wir leben einfach mit einem leicht kaputten Zustand“. Im Artikel ist das Beispiel vcpkg genau so ein Fall
    • Es gibt dort ein Beispiel, bei dem es so aussieht, als hätte jemand UUIDs absichtlich manipuliert. Dass so etwas möglich ist, finde ich etwas beunruhigend
  • Ich stimme der Schlussfolgerung zu: „Git ist als Datenbank für den Start eines Paketmanagers hervorragend geeignet“

    • Der Client sollte aber nicht das gesamte Repository beziehen, sondern besser eine Cache- oder DB-Schicht dazwischenschalten. Gerade in CI/CD-Umgebungen ist Effizienz besonders wichtig
    • Nixpkgs war dank Git erfolgreich. Skalierungsprobleme sind Luxusprobleme für später
    • Bevor man Git lobpreist, sollte man sich aber wenigstens ein wenig mit Datenbankforschung beschäftigen
    • Git kann auch zu einem Supply-Chain-Albtraum werden. Die Leftpad-Affäre könnte sich dann jede Woche wiederholen
    • Git ist als Datenbank für Paketmanager furchtbar. Die Leute nutzen es nur, weil GitHub das kostenlos hostet
  • Ich vertrete eher die Position „Am Ende hat es doch funktioniert“. Für den frühen Betrieb war es völlig ausreichend hilfreich, und Skalierungsprobleme ließen sich später lösen

    • Einige Projekte können sich wegen architektonischer Grenzen aber nicht mehr von git lösen
    • Wenn man mit einem dateisystembasierten Store wie git anfängt, ist ein späterer Protokollwechsel fast unmöglich. Man muss von Anfang an API-zentriert entwerfen
    • Eigentlich gäbe es eher Chancen, git effizienter zu nutzen. Git einfach zu verwerfen, ohne Alternativen vorzuschlagen, ist eine halbgare Schlussfolgerung
    • Es gibt auch den ironischen Witz: „Weil es nicht von 0 auf 1 Billion Nutzer skaliert hat, ist es also Müll“
  • Hier steckt Survivorship Bias drin. Dass der Git-Index von Cargo groß wurde und Probleme verursachte, liegt daran, dass Cargo erfolgreich war.
    Die meisten kleinen Projekte nutzen git als Datenverteilungsprotokoll ganz problemlos.
    In einer frühen Phase, in der unklar ist, ob man überhaupt skaliert, ist es vernünftig, git und GitHub zu nutzen, um sich auf das Kernproblem zu konzentrieren

    • Man muss sich vor zu früher Optimierung hüten. Auch Cargo oder Homebrew haben den einfachen Weg gewählt und sind gewachsen; Skalierungsprobleme waren später ein „gutes Problem“
  • Wenn ich auf der HN-Startseite einen Artikel mit dem Tenor „Was du gerade machst, ist falsch“ sehe, macht mich das immer demütig.
    So etwas ist mir auch schon ein paar Mal passiert. Diesmal war es ein Artikel über PG Notify.
    Aber im Moment entwickle ich allein, und ich weiß nicht einmal, ob das Projekt überhaupt erfolgreich sein wird, also ist git für die Plugin-Verteilung am realistischsten.
    Wenn später Skalierungsprobleme auftauchen, werde ich diesen Artikel trotzdem als Referenz heranziehen

    • Selbst jetzt lassen sich einige Fallstricke vermeiden. Eine größere Gefahr könnte Vendor Lock-in wie die Abhängigkeit von GitHub sein
  • Ich hoste meinen Code persönlich mit Forgejo. Nach außen ist er nicht exponiert und mit mTLS geschützt.
    Aber Go-Module verlangen ein Zertifikat und erkennen meine Forgejo-Instanz deshalb nicht.
    Selbst mit SSH hieß es, HTTPS-Zugriff sei nötig, daher verwende ich am Ende mit einer replace directive eine lokale Kopie. Ziemlich umständlich

    • Wenn man .git an das Ende des Modulpfads hängt und $GOPRIVATE setzt, kann man Git-Befehlsauthentifizierung ohne HTTPS-Anfragen nutzen. Siehe offizielle Dokumentation
    • Wenn man das TLS-Zertifikat (CA) der Instanz zum Trust Store hinzufügt, funktionieren auch HTTPS-Downloads
    • Die Aussage „HTTP-Zugriff ist nötig“ stimmt so nicht. Das lässt sich mit einem lokalen Proxy lösen
    • Mit Tailscale DNS und Zertifikaten kann man Let’s-Encrypt-Zertifikate bekommen, ohne etwas nach außen freizugeben
  • Nicht nur Paketmanager, sondern auch viele kleine Projekte crowdsourcen Daten in Git-Repositories.
    Die meisten sind so klein, dass sie nie an technische Grenzen stoßen.
    Allerdings erhöht diese Struktur die Hürde für Nicht-Entwickler, sich zu beteiligen. Bei Paketmanagern ist das eine Ausnahme, bei allgemeinen Projekten ist es ein Problem
    Um bei solchen Problemen zu helfen, habe ich eine Open-Source-Bibliothek namens Datatig erstellt.
    Das zugehörige Vortragsmaterial ist hier zu finden. Ich werde mich künftig auf diesen Artikel beziehen und auch Inhalte zum Thema Skalierung ergänzen

 
lamanus 2025-12-28

Man nutzt eben Git, weil es unkompliziert ist, statt eigens ein separates System aufzubauen, um Beiträge von Mitwirkenden anzunehmen. Dass das eine Grenze sein soll, überzeugt mich nicht besonders, und eine Alternative für die realen Probleme ist überhaupt nicht zu sehen.