GitLab CI needs: DAG-Pipelines statt strikter Stages
AI generated
CI/CD
.yml
GitLab · CI/CD · DevOps
GitLab CI needs
DAG-Pipelines statt strikter Stages

In einer klassischen GitLab-Pipeline wartet jede Stage darauf, dass alle Jobs der vorherigen Stage fertig sind, selbst wenn ein Job gar nicht von den anderen abhaengt. Das Keyword needs durchbricht diese starre Reihenfolge und macht aus der Pipeline einen Directed Acyclic Graph, in dem Jobs starten, sobald ihre tatsaechlichen Abhaengigkeiten erfuellt sind, was die Gesamtlaufzeit oft drastisch verkuerzt.

16 Min. Lesezeit needs Keyword DAG-Pipeline Stage-Optimierung Pipeline-Laufzeit

1. Das Problem des klassischen Stage-Modells

Im Standard-Ausfuehrungsmodell von GitLab CI ist eine Pipeline in Stages gegliedert, und alle Jobs einer Stage laufen parallel, aber erst die naechste Stage startet, wenn wirklich jeder Job der vorherigen Stage erfolgreich abgeschlossen ist. Dieses Modell ist einfach zu verstehen und fuer kleine Pipelines vollkommen ausreichend, wird aber zum Flaschenhals, sobald eine Stage einen einzelnen langsamen Job enthaelt, der auf mehrere schnelle Jobs in der naechsten Stage keinen inhaltlichen Einfluss hat. Ein typisches Beispiel ist eine Test-Stage mit einem schnellen Unit-Test-Job und einem deutlich langsameren End-to-End-Test-Job, gefolgt von einer Build-Stage, die eigentlich nur vom Unit-Test-Ergebnis abhaengt, aber trotzdem warten muss, bis auch der langsame E2E-Job fertig ist, weil das Stage-Modell keine feinere Abhaengigkeitssteuerung kennt.

Dieses Warten summiert sich in der Praxis erheblich, besonders in Pipelines mit vielen Stages und heterogenen Job-Laufzeiten. Ein Build-Job, der eigentlich in wenigen Sekunden starten koennte, wartet unter Umstaenden mehrere Minuten, nur weil ein voellig unabhaengiger Job in derselben Stage noch laeuft. Bei mehreren aufeinanderfolgenden Stages mit jeweils solchen Ungleichgewichten addiert sich die Wartezeit zu einer Gesamtlaufzeit, die deutlich laenger ist, als es die tatsaechliche Abhaengigkeitskette der Jobs erfordern wuerde. Genau dieses strukturelle Problem loest needs, indem es die Reihenfolge nicht mehr an die Stage-Grenze koppelt, sondern an explizit deklarierte Job-zu-Job-Abhaengigkeiten.

2. Wie needs den Ausfuehrungsgraphen veraendert

Sobald ein Job das Keyword needs mit einer Liste von Job-Namen erhaelt, ignoriert GitLab fuer diesen Job die strikte Stage-Reihenfolge und startet ihn, sobald alle in needs genannten Jobs abgeschlossen sind, unabhaengig davon, ob andere Jobs derselben oder frueherer Stages noch laufen. Die Stage-Zuordnung bleibt dabei fuer die Anzeige in der Pipeline-Ansicht und fuer die logische Gruppierung bestehen, verliert aber ihre Funktion als Ausfuehrungsschranke. Damit wird die Pipeline effektiv zu einem Directed Acyclic Graph, kurz DAG, in dem jeder Job ein Knoten ist und jede needs-Beziehung eine gerichtete Kante, die GitLab beim Pipeline-Start in eine optimale Ausfuehrungsreihenfolge uebersetzt.

Wichtig ist, dass needs nicht nur die Reihenfolge, sondern auch den Artefakt-Fluss steuert: Standardmaessig laedt ein Job mit needs automatisch die Artefakte der genannten Abhaengigkeiten herunter, selbst wenn diese aus einer frueheren Stage stammen, und ignoriert dabei Artefakte aus Jobs, die nicht in der needs-Liste stehen, selbst wenn diese in einer frueheren Stage liefen. Das ist ein bewusster Unterschied zum klassischen Verhalten, bei dem standardmaessig alle Artefakte aller vorherigen Stages verfuegbar sind. Wer von einem klassischen Stage-Modell auf needs umstellt, muss deshalb pruefen, ob ein Job tatsaechlich alle Artefakte bekommt, die er braucht, weil sich der Artefakt-Scope durch die Migration aendert und sich sonst schwer nachvollziehbare Fehler in nachgelagerten Jobs einschleichen koennen.


stages: [build, test, package, deploy]

build_frontend:
  stage: build
  script: [npm run build]

build_backend:
  stage: build
  script: [composer install --no-dev]

unit_tests:
  stage: test
  needs: [build_backend]
  script: [vendor/bin/phpunit]

package_app:
  stage: package
  needs: [build_frontend, unit_tests]
  script: [./package.sh]

3. Parallele Zweige und schnellere Gesamtlaufzeit

Der grosse praktische Nutzen von needs zeigt sich, sobald eine Pipeline mehrere unabhaengige Zweige enthaelt, die erst spaeter wieder zusammenlaufen. Im klassischen Modell laufen zum Beispiel Frontend-Build und Backend-Build in derselben Stage parallel, aber die naechste Stage muss auf beide warten, selbst wenn die davon abhaengigen Tests jeweils nur einen der beiden Zweige betreffen. Mit needs kann jeder Test-Job gezielt nur auf den fuer ihn relevanten Build-Job warten, sodass Frontend-Tests loslaufen koennen, sobald der Frontend-Build fertig ist, ganz unabhaengig davon, ob der Backend-Build noch fortlaeuft. Diese Entkopplung fuehrt in der Praxis dazu, dass die Gesamtlaufzeit einer Pipeline naeher an die Laufzeit des laengsten tatsaechlichen Abhaengigkeitspfads rueckt statt an die Summe aller Stage-Laufzeiten.

Fuer Pipelines mit klar trennbaren Komponenten, etwa einem Frontend, einem Backend und einer Infrastruktur-Definition, kann needs die Gesamtlaufzeit um 30 bis 50 Prozent senken, je nachdem wie unausgeglichen die Job-Laufzeiten innerhalb der einzelnen Stages ursprünglich verteilt waren. Der Effekt ist besonders gross, wenn eine Pipeline viele Stages mit jeweils nur wenigen Jobs hat, weil sich dort die Wartezeiten zwischen den Stages am staerksten summieren. Teams, die ihre Pipeline-Laufzeit senken wollen, sollten deshalb zuerst pruefen, welche Jobs tatsaechlich voneinander abhaengen und welche nur zufaellig in derselben Stage-Reihenfolge stehen, weil genau dort das groesste ungenutzte Optimierungspotenzial liegt.

4. needs ohne stages und die vollstaendige DAG-Pipeline

Seit neueren GitLab-Versionen ist das stages-Keyword fuer needs-basierte Pipelines nicht mehr zwingend erforderlich, weil GitLab die Ausfuehrungsreihenfolge vollstaendig aus dem needs-Graphen ableiten kann, ohne dass jeder Job noch einer Stage zugeordnet sein muss. In diesem Modus faellt die Stage-Spalte in der Pipeline-Ansicht weg und stattdessen wird ausschliesslich der Abhaengigkeitsgraph visualisiert, was fuer sehr komplexe Pipelines mit vielen unabhaengigen Zweigen deutlich uebersichtlicher sein kann als eine lange Liste kuenstlich benannter Stages, die eigentlich nur zur Gruppierung dienten.

In der Praxis empfiehlt sich diese vollstaendige DAG-Variante vor allem fuer neu aufgesetzte Pipelines, waehrend bei der Migration einer bestehenden Pipeline oft ein hybrider Ansatz sinnvoller ist: Die Stages bleiben als grobe logische Gruppierung erhalten, aber innerhalb und zwischen den Stages sorgt needs fuer die tatsaechliche Ausfuehrungsreihenfolge. Dieser hybride Ansatz ist leichter zu kommunizieren, weil Teammitglieder weiterhin an bekannten Begriffen wie build, test und deploy orientiert bleiben, waehrend die Performance-Vorteile von needs trotzdem vollstaendig genutzt werden, ohne dass die gesamte Pipeline-Struktur neu gedacht werden muss.


# Vollstaendige DAG-Pipeline ohne explizite Stage-Reihenfolge
lint:
  stage: .pre
  script: [composer run lint]

build:
  needs: []
  script: [composer install]

test:
  needs: [build]
  script: [vendor/bin/phpunit]

deploy:
  needs: [test, lint]
  script: [./deploy.sh]

5. Artefakt-Steuerung und needs-Optionen im Detail

needs akzeptiert nicht nur eine einfache Liste von Job-Namen, sondern auch eine erweiterte Objekt-Syntax mit den Feldern job, artifacts und optional. Mit artifacts: false laesst sich gezielt verhindern, dass Artefakte einer Abhaengigkeit heruntergeladen werden, obwohl die Ausfuehrungsreihenfolge weiterhin von dieser Abhaengigkeit bestimmt wird, was etwa bei einem Job sinnvoll ist, der nur auf den erfolgreichen Abschluss eines vorherigen Jobs wartet, aber dessen Build-Artefakte gar nicht braucht. Das Feld optional: true erlaubt es, dass eine Abhaengigkeit unter bestimmten rules-Bedingungen gar nicht existiert, ohne dass die Pipeline dadurch fehlschlaegt, was bei bedingt erzeugten Jobs in Kombination mit rules haeufig gebraucht wird.

Zusaetzlich unterstuetzt needs auch Cross-Pipeline- und Cross-Projekt-Abhaengigkeiten ueber das Feld pipeline beziehungsweise project, wodurch ein Job in einer Pipeline auf Artefakte oder den Status eines Jobs aus einer anderen, bereits abgeschlossenen Pipeline warten kann. Diese Faehigkeit wird vor allem in groesseren Organisationen genutzt, in denen mehrere Projekte lose gekoppelt sind, etwa wenn ein Deployment-Repository auf das erfolgreiche Bauen eines Artefakts in einem separaten Build-Repository wartet, ohne dass beide Repositories in einer einzigen Monorepo-Pipeline zusammengefasst werden muessen.


deploy:
  stage: deploy
  needs:
    - job: build
      artifacts: true
    - job: security_scan
      optional: true
    - job: lint
      artifacts: false
  script:
    - ./deploy.sh

6. Grenzen: maximale Anzahl an needs und Zyklenpruefung

GitLab begrenzt die Anzahl der needs-Eintraege pro Job standardmaessig auf 50, was fuer die allermeisten Pipelines mehr als ausreichend ist, in extrem verzweigten Monorepo-Pipelines mit vielen Teilprojekten aber theoretisch relevant werden kann. Wird dieses Limit ueberschritten, meldet GitLab bereits beim Parsen der .gitlab-ci.yml einen Fehler, sodass das Problem nicht erst zur Laufzeit auffaellt, sondern schon beim Commit oder in der CI-Lint-Pruefung. In solchen Faellen hilft es meist, die Abhaengigkeiten ueber Zwischenjobs zu buendeln, die selbst mehrere needs-Eintraege zusammenfassen und von nachgelagerten Jobs dann nur noch als eine einzige Abhaengigkeit referenziert werden.

GitLab prueft zudem automatisch, ob der aus needs entstehende Graph zyklenfrei ist, also ob es keine Kette von Abhaengigkeiten gibt, die letztlich auf sich selbst zurueckfuehrt. Ein solcher Zyklus waere logisch unausfuehrbar, weil zwei Jobs gegenseitig aufeinander warten wuerden, und GitLab lehnt eine Pipeline mit einem erkannten Zyklus bereits bei der Validierung ab, bevor auch nur ein einziger Job gestartet wird. Diese eingebaute Pruefung ist besonders wertvoll in grossen, oft von mehreren Teams gepflegten Pipelines, in denen ein versehentlich eingefuehrter Zyklus sonst erst nach einem fehlgeschlagenen Pipeline-Start auffallen wuerde.

7. Eine bestehende Stage-Pipeline auf needs umstellen

Der pragmatische Einstieg fuer eine bestehende Pipeline ist, zunaechst die tatsaechlichen inhaltlichen Abhaengigkeiten zwischen den Jobs zu kartieren, unabhaengig davon, in welcher Stage sie aktuell stehen. Oft zeigt sich dabei, dass die Stage-Reihenfolge historisch eher zufaellig entstanden ist und viele Jobs eigentlich gar keine echte Abhaengigkeit zu allen Jobs der vorherigen Stage haben, sondern nur zu ein oder zwei konkreten Jobs. Diese Kartierung ist der wichtigste Schritt, weil eine falsch gesetzte needs-Liste entweder zu fehlenden Artefakten fuehrt, wenn eine echte Abhaengigkeit vergessen wird, oder zu unveraendert langsamen Pipelines, wenn zu vorsichtig weiterhin auf zu viele Jobs gewartet wird.

Nach der Kartierung empfiehlt sich eine schrittweise Einfuehrung, beginnend mit den Jobs, die den groessten Zeitgewinn versprechen, typischerweise die Jobs am Ende einer langen Stage-Kette, die eigentlich nur von einem einzelnen fruehen Job abhaengen. Die CI/CD-Pipeline-Ansicht in GitLab visualisiert den entstehenden Graphen direkt und macht sichtbar, ob die neue needs-Struktur tatsaechlich zur erwarteten Parallelisierung fuehrt. Ein Vergleich der Pipeline-Dauer vor und nach der Umstellung, sichtbar in der Pipeline-Analytics-Ansicht des Projekts, liefert dabei einen konkreten Beleg fuer den Nutzen und hilft, die Investition gegenueber dem Team zu rechtfertigen.

8. Wann needs wenig bringt

needs entfaltet seinen Nutzen vor allem bei ungleichmaessig verteilten Job-Laufzeiten und mehreren parallelen Abhaengigkeitszweigen. Bei sehr kleinen Pipelines mit nur zwei oder drei Jobs, die ohnehin schon fast vollstaendig sequenziell voneinander abhaengen, bringt die Umstellung kaum messbaren Zeitgewinn, fuehrt aber trotzdem zusaetzliche Komplexitaet in die Pipeline-Datei ein. In solchen Faellen ist es meist sinnvoller, die einfache Stage-Reihenfolge beizubehalten, weil der Wartungsaufwand fuer die needs-Pflege den geringen Zeitgewinn nicht rechtfertigt.

Auch bei Pipelines, in denen Runner-Kapazitaet der eigentliche Engpass ist, etwa weil nur wenige Shared Runner zur Verfuegung stehen, bringt needs weniger als erwartet, weil parallel startbereite Jobs trotzdem auf einen freien Runner warten muessen. In solchen Umgebungen sollte vor der needs-Optimierung zuerst die Runner-Kapazitaet geprueft werden, etwa durch Autoscaling oder zusaetzliche Runner-Tags fuer unterschiedliche Job-Typen, weil andernfalls die theoretische Parallelisierung durch needs in der Praxis an der begrenzten Anzahl gleichzeitig verfuegbarer Runner scheitert und der erhoffte Zeitgewinn ausbleibt.

9. Fazit: needs als gezielter Hebel fuer Pipeline-Geschwindigkeit

needs verwandelt eine starre Stage-Pipeline in einen Directed Acyclic Graph, in dem Jobs so frueh wie moeglich starten, statt auf kuenstliche Stage-Grenzen zu warten, was in Pipelines mit ungleichmaessigen Job-Laufzeiten und mehreren parallelen Zweigen spuerbare Zeitersparnis bringt. Der Umstieg erfordert eine sorgfaeltige Kartierung der tatsaechlichen Abhaengigkeiten und ein Bewusstsein dafuer, dass sich mit needs auch der Artefakt-Scope aendert, ist aber mit dem hybriden Ansatz aus bestehenden Stages plus gezielten needs-Eintraegen risikoarm umsetzbar.

Die folgende Tabelle stellt das klassische Stage-Modell und das needs-basierte DAG-Modell entlang der wichtigsten Kriterien gegenueber, als Entscheidungshilfe fuer die eigene Pipeline.

Kriterium Klassisches Stage-Modell needs-basiertes DAG-Modell Praxis-Empfehlung
Job-Start erst wenn gesamte vorherige Stage fertig ist sobald genannte Abhaengigkeiten fertig sind needs bei ungleichen Job-Laufzeiten einsetzen
Artefakt-Verfuegbarkeit alle Artefakte aller vorherigen Stages nur Artefakte der needs-Liste needs-Liste vor Umstellung sorgfaeltig kartieren
Komplexitaet der Konfiguration gering, lineare Reihenfolge hoeher, expliziter Graph noetig bei kleinen Pipelines Stage-Modell beibehalten
Skalierung mit vielen Zweigen Wartezeiten summieren sich parallele Zweige laufen unabhaengig besonders bei Monorepos und Multi-Komponenten sinnvoll
Runner-Abhaengigkeit weniger relevant profitiert von ausreichender Runner-Kapazitaet Autoscaling pruefen bevor needs eingefuehrt wird

Mironsoft

CI/CD-Pipelines, Zero-Downtime-Deployments und Release-Automatisierung

Deployments, die ohne Ausfallzeit und ohne Nervenkitzel laufen?

Wir prüfen bestehende GitLab-Pipelines auf fragile Deployment-Schritte und fehlende Absicherung und bauen daraus einen Release-Prozess mit Zero-Downtime-Deployments, automatisierten Checks und einem Rollback, dem ihr im Ernstfall vertrauen könnt.

Pipeline-Review

Bestehende .gitlab-ci.yml auf Fragilität, fehlende Stages und Sicherheitslücken prüfen.

Zero-Downtime-Deployment

Symlink-Releases, Health-Checks und Rollback-Strategien für Magento-Shops aufbauen.

CI/CD-Automatisierung

Tests, Security-Scans und Deployments zu einer zuverlässigen Pipeline verbinden.

10. Zusammenfassung

needs und DAG-Pipelines: Das Wichtigste auf einen Blick

Kernidee von needs

Jobs starten sobald ihre expliziten Abhaengigkeiten fertig sind, statt auf das Ende der gesamten vorherigen Stage zu warten.

Groesster Effekt

Deutliche Zeitersparnis bei Pipelines mit mehreren parallelen, ungleich langen Abhaengigkeitszweigen.

Wichtigste Falle

Artefakt-Scope aendert sich mit needs, nur die genannten Jobs liefern automatisch ihre Artefakte.

Migrationstipp

Zunaechst echte Abhaengigkeiten kartieren, dann hybrid mit bestehenden Stages plus needs schrittweise einfuehren.

11. FAQ: needs und DAG-Pipelines: Das Wichtigste auf einen Blick

1Muss ich stages entfernen, wenn ich needs verwende?
Nein, needs funktioniert auch mit weiterhin definierten Stages. Stages dienen dann nur noch der Gruppierung und Anzeige, waehrend needs die tatsaechliche Ausfuehrungsreihenfolge bestimmt. Ein vollstaendiger Verzicht auf stages ist optional und eher fuer neu aufgesetzte Pipelines sinnvoll.
2Was passiert mit Artefakten, wenn ich needs nutze?
Ein Job mit needs laedt standardmaessig nur die Artefakte der in needs genannten Jobs herunter, nicht automatisch alle Artefakte aller vorherigen Stages wie im klassischen Modell. Das laesst sich mit der Objekt-Syntax und dem Feld artifacts pro Abhaengigkeit gezielt steuern.
3Wie viele needs-Eintraege darf ein Job haben?
GitLab begrenzt die Anzahl standardmaessig auf 50 Eintraege pro Job. Fuer die allermeisten Pipelines ist das ausreichend, in sehr verzweigten Monorepos kann es sinnvoll sein, Abhaengigkeiten ueber Zwischenjobs zu buendeln, um unter dem Limit zu bleiben.
4Erkennt GitLab zirkulaere Abhaengigkeiten in needs?
Ja, GitLab prueft den needs-Graphen bereits bei der Pipeline-Validierung auf Zyklen und lehnt eine Pipeline mit einer zirkulaeren Abhaengigkeit ab, bevor ein einziger Job gestartet wird. Ein Zyklus faellt damit schon beim Commit oder in der CI-Lint-Pruefung auf.
5Kann needs auch auf Jobs aus anderen Pipelines oder Projekten verweisen?
Ja, ueber die Felder pipeline und project in der erweiterten needs-Syntax lassen sich Cross-Pipeline- und Cross-Projekt-Abhaengigkeiten abbilden. Das wird vor allem in Organisationen mit mehreren lose gekoppelten Repositories genutzt.
6Bringt needs bei jeder Pipeline einen Geschwindigkeitsvorteil?
Nein, der Vorteil haengt stark davon ab, wie ungleichmaessig die Job-Laufzeiten innerhalb der Stages verteilt sind und wie viele parallele Abhaengigkeitszweige existieren. Bei sehr kleinen, ohnehin sequenziellen Pipelines ist der Effekt gering.
7Was bedeutet optional: true bei needs?
optional: true erlaubt, dass die referenzierte Abhaengigkeit unter bestimmten rules-Bedingungen gar nicht in der Pipeline existiert, ohne dass die Pipeline dadurch fehlschlaegt. Das ist bei bedingt erzeugten Jobs in Kombination mit rules haeufig notwendig.
8Kann needs die Runner-Kapazitaet zum Engpass machen?
Ja, wenn viele Jobs durch needs gleichzeitig startbereit werden, aber nur wenige Runner zur Verfuegung stehen, muessen die Jobs trotzdem auf einen freien Runner warten. In solchen Faellen sollte vor der needs-Optimierung die Runner-Kapazitaet geprueft werden.
9Ist die Migration von Stages zu needs riskant?
Bei sorgfaeltiger Kartierung der tatsaechlichen Abhaengigkeiten und einem hybriden Vorgehen mit weiterhin bestehenden Stages ist das Risiko gering. Die groesste Gefahr ist eine unvollstaendige needs-Liste, die zu fehlenden Artefakten in nachgelagerten Jobs fuehrt.
10Wie sehe ich, ob needs tatsaechlich etwas bringt?
Die Pipeline-Analytics-Ansicht im GitLab-Projekt zeigt die Gesamtdauer von Pipelines vor und nach der Umstellung, und die Pipeline-Grafik visualisiert den entstehenden Abhaengigkeitsgraphen direkt, sodass sich Parallelisierungseffekte unmittelbar nachvollziehen lassen.