Was ist trunk based development? Praxisleitfaden für SREs
Zusammenfassung
Trunk based development ist ein Branching-Modell, bei dem Entwickler kleine Änderungen mindestens täglich in einen gemeinsamen Trunk mergen. Andere Branches leben nur Stunden, und der Trunk bleibt jederzeit releasefähig. Unfertige Arbeit verbergen Teams hinter Feature Flags oder Branch by Abstraction. Der Leitfaden zeigt Voraussetzungen, Release-Strategien, Flag-Schulden und die Fälle, in denen das Modell nicht passt.
Es ist 3 Uhr morgens, und der Release-Branch lässt sich nicht mergen. Vierzig Commits, drei Wochen alt, berühren dieselben Dateien wie main. Genau dieser Schmerz bringt die Frage auf den Tisch: was ist trunk based development? Die Antwort in einem Satz: Alle Entwickler integrieren kleine Änderungen mindestens einmal am Tag in einen gemeinsamen Branch, den Trunk oder main, und halten diesen Branch jederzeit releasefähig.
Dieser Leitfaden richtet sich an Platform Engineers, die Git bereits sicher beherrschen. Er erklärt, was das Modell verlangt, wogegen es schützt und wo es still und leise scheitert.
Was ist trunk based development, betrieblich gesehen?
Entfernen Sie die Definition bis auf ihre Randbedingungen. Alle Entwickler integrieren in einen einzigen Branch. Jeder andere Branch lebt Stunden, nicht Wochen. Der Trunk baut und besteht die Tests bei jedem Commit, damit er jederzeit ausgeliefert werden kann.
Die Capability-Seite von DORA gibt dafür Zahlen vor: drei oder weniger aktive Branches im Repository, Merges in den Trunk mindestens einmal täglich, keine Code Freezes und ein Build- und Testzyklus von wenigen Minuten. Diese Zahlen sind der eigentliche Punkt. Das Modell ist ein Budget für Feedback-Schleifen und keine Vorliebe für einen bestimmten Branching-Stil.

Kleine Teams committen manchmal direkt in den Trunk. Größere nutzen kurzlebige Branches und Pull Requests für Review und Build-Checks, aber nie, um Arbeit von der Integration fernzuhalten. Die Referenzseite trunkbaseddevelopment.com beschreibt beide Varianten und nennt Google als Beispiel: Dort arbeiten rund 35.000 Entwickler in einem Monorepo auf einem einzigen Trunk.
Warum langlebige Branches scheitern und was der Trunk dafür braucht
Ein Feature-Branch ist ein Kredit. Die Zinsen sind Merge-Konflikte, und sie wachsen mit jedem Commit, der auf main landet, während Sie weg sind. Je länger der Branch lebt, desto größer wird der Diff, und je größer der Diff, desto weniger liest ihn jemand genau.
Das wirkt sich direkt auf Ihre Change Failure Rate aus. Ein Merge mit 2.000 Zeilen wird überflogen und abgenickt. Ein Merge mit 60 Zeilen wird tatsächlich gelesen. Reviewer sind nicht faul, sie rationieren ihre Aufmerksamkeit. Kleine Batches sind der einzige Mechanismus, der die Qualität von Reviews skaliert.
Die zweite Kostenart zeigt sich erst beim Release. Zwei Branches, die jeweils die CI bestehen, können sich gegenseitig kaputt machen, sobald sie zusammenkommen. Das merken Sie beim Integrieren, im schlechtesten Moment und mit einer Deadline im Nacken.
Ohne unterstützende Praktiken endet der Umstieg auf den Trunk fast immer damit, dass Teams innerhalb eines Quartals wieder zu Feature-Branches zurückkehren. Vier Dinge müssen vorher existieren:
Ein Build- und Testlauf von unter etwa zehn Minuten. Dauert die CI 40 Minuten, bündeln Entwickler ihre Änderungen, und genau das untergräbt das Modell.
Tests, die aus echten Gründen fehlschlagen. Eine flackernde Suite trainiert Menschen dazu, erneut zu starten und trotzdem zu mergen.
Ein schneller, ehrlicher Review-Prozess. DORA nennt schwergewichtige und asynchrone Code Reviews als häufiges Hindernis, weil sie dazu drängen, Arbeit zu bündeln.
Eine sichere Methode, unfertige Arbeit auszuliefern. Dazu mehr im nächsten Abschnitt.
Fehlt eine dieser Voraussetzungen, wird der Trunk zu dem Ort, an dem sich Fehler ansammeln, statt zu dem Ort, an dem sie gefangen werden.
Wie mergen Sie unfertige Arbeit, ohne sie auszuliefern?
Das ist die Frage, die jeder Skeptiker stellt, und sie hat eine unspektakuläre Antwort: Sie entkoppeln Deployment von Release. Der Code geht dunkel in Produktion. Ein Flag entscheidet, wer ihn sieht.
// checkout.ts
import { flags } from "./flags";
export async function renderCheckout(user: User) {
if (await flags.isEnabled("new-payment-flow", { userId: user.id })) {
return renderNewPaymentFlow(user); // merged to trunk, dark by default
}
return renderLegacyCheckout(user);
}Die neue Strecke wird am ersten Tag gemergt, hinter einem Flag, das ausgeschaltet ist. Sie schalten es für interne Nutzer ein, dann für 1 Prozent, dann für 10 Prozent, mit einem SLO-Gate bei jedem Schritt. Überschreitet die Fehlerrate das Budget, geht das Flag aus, und die Änderung ist ohne Deployment praktisch zurückgenommen. Teams, die gehostete Flag-Dienste evaluieren, starten oft mit LaunchDarkly. Das Muster funktioniert aber mit jedem Anbieter oder einem eigenen Config-Store.
Die zweite Technik ist Branch by Abstraction für große Refactorings. Sie führen ein Interface ein, leiten die Aufrufer darüber, bauen die neue Implementierung dahinter und tauschen sie aus, sobald sie bereit ist. Kein langlebiger Branch, kein Big-Bang-Merge.

Die ehrlichen Kosten: Flags sind Schulden mit Halbwertszeit
Auf Konferenzen will darüber niemand sprechen. Jedes Flag ist eine Verzweigung im Produktionscode, die irgendjemand später entfernen muss. Wir haben Teams mit 80 Ingenieuren gesehen, die mehrere hundert veraltete Flags mitschleppten, jedes davon ein Pfad, den niemand vollständig testen kann.
Behandeln Sie Flags vertraglich als kurzlebig. Jedes bekommt bei der Anlage einen Owner und ein Ablaufdatum. Alarmieren Sie, wenn ein Flag über sein Ablaufdatum hinaus existiert. Entfernen Sie den toten Codepfad im selben Pull Request, der das Flag löscht.
Auch das kombinatorische Risiko ist real. Zehn unabhängige boolesche Flags ergeben 1.024 mögliche Konfigurationen, und Sie werden nie alle testen. Halten Sie die Wechselwirkungen gering und trennen Sie Release-Flags von dauerhaften Betriebsschaltern wie Kill Switches.
Release-Strategien vom Trunk aus
Es gibt zwei gängige Wege, vom Trunk aus einen Release zu schneiden, und keiner braucht einen langlebigen Branch.
Direkt vom Trunk releasen. Jeder grüne Commit ist ein Kandidat. Fehler werden nach vorn behoben, mit einem neuen Commit und nicht durch Patchen eines alten Branches. Das passt zu Teams mit starken automatisierten Tests und schnellen Deployments.
Einen Release-Branch just in time schneiden. Sie branchen von einem bekannten guten Trunk-Commit ab, härten ihn, liefern aus und löschen ihn danach. Fixes landen zuerst auf dem Trunk und werden zurückportiert. Das passt zu Teams mit langsameren Release-Gates oder regulierter Freigabe.
Welchen Weg Sie wählen, hängt von Ihrer Erkennungszeit ab. Wenn Sie ein fehlerhaftes Deployment innerhalb von fünf Minuten bemerken und in zwei Minuten zurückrollen, liefern Sie nach vorn aus. Liegt Ihre mittlere Erkennungszeit bei einer Stunde, gibt Ihnen ein Release-Branch wenigstens einen festen Stand.

Observability ist die andere Hälfte des Deals
Trunk based development erhöht Ihre Deployment-Frequenz, und damit steigt die Zahl der Momente, in denen etwas schiefgehen kann. Das Modell funktioniert nur, wenn Sie eine Regression innerhalb von Minuten nach einem Merge sehen. Dazu brauchen Sie Fehlerraten, Latenz-Perzentile und Sättigung, die einem bestimmten Release zugeordnet sind, und kein Dashboard, das jemand am Montag anschaut.
Ein brauchbarer Test: Können Sie nach einem Merge ohne fünf geöffnete Tabs beantworten, ob diese Änderung den p99 oder die Fehlerrate verschoben hat? Wenn nicht, sind Sie noch nicht bereit, zehnmal am Tag zu mergen.
Welchen Stack Sie auch betreiben, die Anforderung bleibt dieselbe: Deploy-Marker in Ihren Graphen, SLO-Alarme auf Basis der Burn Rate und ein Revert-Pfad, den eine müde Person um 3 Uhr morgens ohne langes Nachdenken ausführen kann.
Die DORA-Metriken reagieren unterschiedlich schnell. Deployment-Frequenz und Lead Time for Changes bewegen sich zuerst, weil kleinere Batches schneller durch die Pipeline laufen. Change Failure Rate und Time to Restore folgen. Sie hängen stärker von Observability und Revert-Pfad ab als vom Branching-Modell allein. Richten Sie die Zahlen nicht als Leistungsbewertung einzelner Personen aus. Sie beschreiben ein System. Steigt die Lead Time, schauen Sie zuerst auf die Review-Warteschlange und die CI-Dauer, bevor Sie die Menschen betrachten.
Trunk based development vs. GitFlow vs. GitHub Flow
Diese drei Modelle werden oft verwechselt. Trennen lassen sie sich an einer Eigenschaft: Wie lange bleibt Arbeit vom gemeinsamen Branch fern?
GitFlow führt einen develop-Branch, Feature-Branches, Release-Branches und Hotfix-Branches. Arbeit kann wochenlang isoliert bleiben. Das Modell wurde für versionierte, geplante Releases gebaut, und es zeigt sich schnell, wenn Sie zehnmal am Tag ausliefern wollen.
GitHub Flow liegt nah am Trunk. Kurzlebige Branches, Pull Requests, Merge nach main, Deployment. Der Unterschied, den die Referenzseite betont, liegt vor allem darin, woher Releases kommen.
Trunk based development ist von den dreien am strengsten, was die Lebensdauer von Branches angeht. Für alles, was nicht in einer einzigen kleinen Änderung ausgeliefert werden kann, setzt es Feature Flags oder Branch by Abstraction voraus.
Nutzt Ihr Team bereits GitHub Flow mit Branches, die weniger als zwei Tage leben, sind Sie dem Trunk näher, als Sie denken. Die Lücke liegt meist in der Flag-Disziplin und der Latenz beim Review, nicht im Tooling.
Wann die falsche Wahl ist und wie der Start ohne Big-Bang gelingt
Verzichten Sie auf das Modell oder schieben Sie es zumindest auf, wenn einer der folgenden Fälle zutrifft. Seien Sie ehrlich, in welchem Sie stecken.
Ihre Testsuite dauert eine Stunde, und Sie können sie nicht parallelisieren. Dann werden Sie bündeln, und das Bündeln bricht das Modell.
Sie liefern versionierte Artefakte an Kunden, die jahrelang auf alten Versionen bleiben. Dafür brauchen Sie Wartungs-Branches. Das ist legitim, und Sie können trotzdem täglich auf den Trunk integrieren.
Sie haben kein Flag-System und keine Lust, eines zu bauen. Halbfertige Arbeit wird dann in Releases durchsickern.
Ihr Team vertraut dem Build nicht. Reparieren Sie zuerst die Tests. Der Trunk wird das nicht für Sie tun.
Kündigen Sie keine Richtlinie an. Messen Sie zuerst und verkleinern Sie dann schrittweise:
Erfassen Sie Ihre aktuelle Branch-Lebensdauer und die Größe des medianen Pull Requests. Das sind Ihre Ausgangswerte.
Setzen Sie eine Obergrenze, zum Beispiel kein Branch älter als zwei Tage, und machen Sie sie auf einem Dashboard sichtbar.
Beheben Sie den langsamsten Teil der CI. Dauert der Build 30 Minuten, ist alles andere vorerst zweitrangig.
Führen Sie ein Flag für ein echtes Feature ein. Liefern Sie es dunkel aus und entfernen Sie es innerhalb eines Sprints.
Schaffen Sie Code Freezes zuletzt ab, wenn Ihr Revert-Pfad im Ernstfall erprobt wurde.
Schauen Sie nach einem Monat wieder hin. Die Zahlen, die sich zuerst bewegen, sind meist die Größe der Pull Requests und die Zeit bis zum Merge. Die Change Failure Rate braucht länger und verschlechtert sich manchmal sogar, bevor sie besser wird, weil Sie Fehler endlich früher sehen.
Was wird Ihr Post-Mortem sagen? Das ist die nützliche Frage, bevor Sie etwas ausliefern. Wenn Ihr letzter Incident auf einen Merge zurückging, den niemand prüfen konnte, auf einen Branch, der drei Wochen auseinanderdriftete, oder auf einen Release mit vierzig Änderungen, dann wissen Sie bereits, wann die Schulden fällig werden.
Sehen Sie sich Ihre letzten drei Ausfälle an. Wie viele hatten eine große, späte Integration als Ursache? Diese Zahl ist Ihr Business Case.