E-NO
DevOps 10 min de lecture

GitLab CI/CD : guide pratique d'optimisation des performances

calendar_today Publié : 2026-08-17
update Dernière mise à jour : 2026-08-17
analytics Efficacité SEO : 100%
Illustration du guide technique pour « GitLab CI/CD : guide pratique d'optimisation des performances ».

Les performances de GitLab CI/CD influencent directement la vélocité des équipes d'ingénierie. Des files d'attente trop longues retardent le retour d'information, des runners surchargés provoquent des échecs aléatoires, et des caches mal configurés gaspillent la bande passante et le stockage. Ce guide propose une approche progressive et mesurable pour identifier et corriger les goulets d'étranglement sans mettre en péril votre pipeline de livraison. Vous allez inventorier votre environnement, établir des références, appliquer des optimisations ciblées, valider chaque modification et instaurer une routine d'exploitation reproductible.

Inventorier votre environnement avant tout

Avant toute modification, capturez l'état actuel. Cela clarifie les leviers d'optimisation disponibles et la documentation applicable. Enregistrez les éléments suivants :

  • Édition et version de GitLab (SaaS vs autogéré)
  • Versions des runners et exécuteurs (shell, Docker, Kubernetes)
  • Backends de cache et d'artéfacts (disque local, S3, GCS, NFS)
  • Localité réseau (où se situent les runners par rapport à GitLab, aux registres et aux miroirs de paquets)
  • Caractéristiques des dépôts (taille, sous-modules, utilisation de LFS)
  • Droits d'accès réels (configuration des runners, paramètres de projet, jeton API)

Commandes rapides pour collecter ces données :

# Depuis un journal de job
echo "$CI_SERVER_VERSION $CI_RUNNER_EXECUTOR $CI_PROJECT_PATH"

# Depuis l'hôte du runner
gitlab-runner --version
gitlab-runner list

# Depuis l'API GitLab (remplacez les valeurs entre crochets)
curl -s --header "PRIVATE-TOKEN: <token>" https://<gitlab_url>/api/v4/version

Utilisez ce tableau pour standardiser votre inventaire :

ChampExemple de valeurNotes
Version GitLab16.11 SaaSInfluence les fonctionnalités et valeurs par défaut disponibles
Version(s) runner16.11Maintenir aligné avec le serveur dans la mesure du possible
Exécuteurs runnershell, dockerDétermine la stratégie de cache et l'isolation
Backend cacheS3, bucket gitlab-runner-cachePermet le partage de cache entre runners
Politique artéfactsexpire_in: 2 daysGarder les artéfacts petits et de courte durée
Traits du dépôt2,1 Go, 5 sous-modules, LFS activéClone lourd si non optimisé
Localité réseauRunners dans la même région que GitLabRéduit la latence de transfert
AccèsConfig runner, maintainer projet, token read_apiRequis pour appliquer les modifications

Chemin de configuration sécurisé

Appliquez les changements par petites étapes avec un retour arrière clair. Suivez cette séquence : (1) métriques de référence, (2) gains rapides, (3) dimensionnement du débit, (4) optimisation de la latence et du cache, (5) parallélisation prudente, (6) re-mesure et extension seulement après validation.

1. Établir une référence mesurable

Choisissez un ou deux pipelines représentatifs (par exemple, build et tests de la branche principale) et capturez trois à cinq exécutions récentes. Enregistrez la durée du pipeline, les durées des jobs critiques, le temps de file d'attente et les temps de téléversement/téléchargement des artéfacts. Ajoutez un chronométrage simple autour des étapes lourdes dans vos scripts :

set -euo pipefail
stamp() { date +"%Y-%m-%d %H:%M:%S"; }
step() { echo "[STEP] $(stamp) $*"; }

step "Installation dépendances"
# vos commandes d'installation

step "Exécution tests"
# vos commandes de test

Utilisez l'API pour collecter les données de référence :

# 10 derniers pipelines réussis et leurs durées
curl -s --header "PRIVATE-TOKEN: <token>" \
 "https://<gitlab_url>/api/v4/projects/<id>/pipelines?status=success&per_page=10" | jq '[.[] | {id, status, duration}]'

# Jobs d'un pipeline spécifique
curl -s --header "PRIVATE-TOKEN: <token>" \
 "https://<gitlab_url>/api/v4/projects/<id>/pipelines/<pipeline_id>/jobs" | jq '[.[] | {name, status, duration, queued_duration}]'

2. Gains rapides dans .gitlab-ci.yml

Réduisez la surcharge du clone Git avec un fetch superficiel :

variables:
  GIT_STRATEGY: fetch
  GIT_DEPTH: "1"
  GIT_SUBMODULE_STRATEGY: none

Dimensionnez correctement les artéfacts. N'archiver pas de gros résultats reproductibles. Gardez des expirations courtes :

artifacts:
  when: on_success
  expire_in: 2 days
  paths:
    - build/reports/

Ajoutez des caches pour les répertoires de dépendances que vous savez réutilisables sans risque. Cléyez les caches par les fichiers de verrouillage pour qu'ils s'invalident seulement quand les dépendances changent.

Exemple Node.js :

cache:
  key:
    files:
      - package-lock.json
  paths:
    - node_modules/
  policy: pull-push

Exemple Python :

cache:
  key:
    files:
      - requirements.txt
  paths:
    - .venv/
    - $PIP_CACHE_DIR
  policy: pull-push

Exemple Maven :

cache:
  key: maven-$CI_COMMIT_REF_SLUG
  paths:
    - .m2/repository
  policy: pull-push

3. Dimensionnement du débit sur les runners

Définissez la concurrence globale pour que l'hôte reste occupé sans être surchargé. Pour des jobs liés au CPU, commencez avec concurrent proche du nombre de vCPU, puis ajustez selon la pression I/O et mémoire.

Dans /etc/gitlab-runner/config.toml, examinez ces paramètres :

concurrent = 6
check_interval = 0

runners
  name = "build-runner-01"
  url = "https://gitlab.example.com/"
  token = "REDACTED"
  executor = "docker"
  request_concurrency = 2
  [runners.cache]
    Type = "s3"
    Path = "runner"
    Shared = true
    [runners.cache.s3]
      ServerAddress = "s3.amazonaws.com"
      BucketName = "gitlab-runner-cache"
      BucketLocation = "us-east-1"
      Insecure = false

Redémarrez le runner pour appliquer les changements :

systemctl restart gitlab-runner

Lignes directrices de dimensionnement (points de départ ; ajustez à votre charge) :

  • Builds CPU-bound : concurrent ≈ nombre de vCPU, request_concurrency = 2 à 4
  • Builds I/O-intensifs : concurrent < vCPU (par exemple, 0,5 × vCPU)
  • Tests gros consommateurs de mémoire : plafonnez concurrent pour que le plus gros job ait au moins 1,5× sa mémoire de pointe disponible

4. Optimisation de la latence et du cache

  • Colocalisez les runners près de GitLab et de vos registres de conteneurs/paquets pour réduire les temps de transfert.
  • Préférez un cache distant (S3/GCS) pour les flottes afin que les caches survivent aux redémarrages et soient partagés entre machines.
  • Gardez les clés de cache stables au sein d'une branche mais différentes entre branches pour éviter l'empoisonnement.
  • Évitez d'archiver d'énormes caches ; mettez en cache seulement ce qui ne se re-télécharge pas vite (répertoires de dépendances, pas les sorties de build).

5. Parallélisation prudente

Divisez les longs jobs de test avec parallel de GitLab. Commencez petit et assurez l'isolation.

Exemple à nombre fixe :

unit_tests:
  stage: test
  script: run_tests.sh "$CI_NODE_INDEX" "$CI_NODE_TOTAL"
  parallel: 4

Exemple matrice :

build:
  stage: build
  parallel:
    matrix:
      - PLATFORM: [linux, darwin]
        ARCH: [amd64, arm64]
  script:
    - ./build.sh "$PLATFORM" "$ARCH"

Notes d'implémentation :

  • Assurez-vous que les tests ne partagent pas d'état global mutable (bases de données, ports, répertoires temporaires). Paramétrez par nœud avec $CI_NODE_INDEX.
  • Protégez la parallélisation derrière un drapeau de fonctionnalité pour pouvoir revenir en arrière vite :
workflow:
  rules:
    - if: '$ENABLE_PARALLEL == "1"'

6. Re-mesurer et décider des prochaines étapes

Comparez durées, temps de file d'attente et temps de transfert d'artéfacts à votre référence. Ne conservez que les changements qui produisent des gains constants sur plusieurs exécutions.

Vérification et diagnostics

La vérification prouve que vous avez amélioré le bon indicateur. Utilisez ces contrôles.

Chronométrage pipeline et jobs

  • Comparez trois à cinq exécutions avant et trois à cinq après un changement pour lisser la variance aléatoire.
  • Inspectez les détails des jobs pour Temps en file vs Temps d'exécution. Le temps en file signale un problème de capacité ; le temps d'exécution signale une inefficacité au niveau du job.

Santé des runners

  • Sur les hôtes runners, surveillez CPU, mémoire, I/O disque et réseau aux heures de pointe. Si le CPU est inactif alors que des jobs attendent, il faut probablement plus de runners enregistrés ou augmenter concurrent.
  • Validez la connectivité du runner :
gitlab-runner verify

Guide symptôme-métrique

SymptômeMétrique à vérifierCause probablePremière action
Long temps en filequeued_durationCapacité runner insuffisanteAugmenter concurrent ou ajouter runners
Temps de clone longsJournaux, taille repoHistorique profond, sous-modulesUtiliser GIT_DEPTH, désactiver sous-modules
Étapes dépendances lentesChronos par étapeCaches absents ou instablesAjouter cache clé par fichiers de verrou
Artéfacts lentsTemps upload/downloadArtéfacts surdimensionnésRéduire paths, définir expire_in
Tests flaky après splitTaux d'échec par nœudRessources partagéesIsoler avec CI_NODE_INDEX

Modes de défaillance et récupération

Problèmes courants et comment récupérer sans risque.

1. Empoisonnement de cache ou ratés de cache

Symptômes : Le build utilise de mauvaises versions de dépendances, ou les caches ne touchent jamais. Cause probable : Clés de cache trop larges ou instables. Récupération :

  • Restreignez les clés aux fichiers de verrouillage ou manifestes (pour Node : key.files: package-lock.json).
  • Purgez les caches. Pour caches locaux, supprimez /var/lib/gitlab-runner/cache/* sur le runner. Pour S3, effacez le préfixe concerné.

2. Surcharge runner et timeouts

Symptômes : queued_duration en hausse, échecs sporadiques sous charge. Causes : concurrent trop élevé pour le matériel, saturation réseau. Récupération :

  • Réduisez concurrent dans config.toml et redémarrez gitlab-runner.
  • Ajoutez des runners ou déplacez les jobs lourds vers des machines plus grosses.

3. Tests flaky après parallélisation

Symptômes : Échecs intermittents, collisions de ports, répertoires temporaires partagés. Récupération :

  • Paramétrez les ressources par nœud avec $CI_NODE_INDEX. Isolez répertoires temporaires et bases de données par nœud.
  • Revenir en arrière : mettez ENABLE_PARALLEL=0 dans les variables du projet, ou annulez le changement dans .gitlab-ci.yml.

4. Gonflement d'artéfacts ralentissant les pipelines

Symptômes : Longs temps d'upload/download. Causes : Archivage de gros binaires reproductibles ou d'espaces de travail entiers. Récupération :

  • Limitez les artéfacts aux rapports nécessaires et petits livrables. Définissez expire_in agressivement.
  • Utilisez les caches pour le contenu réutilisé fréquemment et les artéfacts pour les livrables minimaux.

5. Clones superficiels cassant la gestion de versions

Symptômes : Les scripts de build ne trouvent pas les tags ou l'historique. Cause : GIT_DEPTH=1 alors que les scripts nécessitent les tags. Récupération :

  • Augmentez GIT_DEPTH pour inclure l'historique nécessaire, ou récupérez les tags explicitement :
script:
  - git fetch --tags --depth=50

6. Erreurs de permissions sur cache distant

Symptômes : 403 ou 404 lors du push/pull de cache. Récupération :

  • Vérifiez les identifiants et politiques de bucket pour le profil d'instance runner ou les clés d'accès.
  • Désactivez temporairement le cache (policy: pull) pour débloquer les builds, puis corrigez les permissions.

Liste de contrôle opérationnelle

Utilisez cette routine pour maintenir les performances sous contrôle.

Quotidien

  • Surveillez queued_duration sur les jobs les plus sollicités.
  • Traitez le job le plus lent des dernières 24 heures.

Hebdomadaire

  • Revoyez les tendances de durée des pipelines et les graphiques de ressources runners.
  • Purgez les caches plus anciens que la durée de vie moyenne de vos branches.

Par changement

  • Référencez trois exécutions, appliquez un changement, re-mesurez trois exécutions.
  • Documentez les deltas et conservez ou annulez le changement.

Modèle de journal des changements :

ChangementMétrique référenceMétrique aprèsDeltaConserver/AnnulerResponsable
GIT_DEPTH=1 sur repo XClone 180sClone 35s-81%ConserverA. Dev
Cache node_modulesInstall 240sInstall 55s-77%ConserverB. Ops
Tests parallèles ×4Test 28mTest 9m-68%ConserverC. QA
Réduire paths artéfactsUpload 120sUpload 20s-83%ConserverD. Dev

Exemples pratiques

1. Réduire le temps de file en ajoutant de la capacité

  • Référence : queued_duration ~ 300s aux heures de pointe.
  • Changement : Augmenter concurrent de 4 à 8 sur deux runners (capacité logique totale de 8 à 16), en gardant l'utilisation CPU sous 75%.
  • Résultat attendu : queued_duration tombe sous 60s.
  • Vérification : Comparer la moyenne queued_duration sur 10 pipelines avant/après.
  • Retour arrière : Si CPU dépasse 90% et échecs montent, revenez sur concurrent et planifiez un troisième runner.

2. Réduire les temps de clone avec fetch superficiel

  • Référence : Clone 150s sur repo 2 Go avec sous-modules.
  • Changement : GIT_STRATEGY: fetch, GIT_DEPTH: 1, GIT_SUBMODULE_STRATEGY: none.
  • Résultat attendu : Clone sous 40s.
  • Vérification : Chronométrage début-job à première commande dans les logs.
  • Retour arrière : Si le build nécessite tags ou sous-modules, augmentez GIT_DEPTH ou réactivez les sous-modules sélectivement.

3. Accélérer les dépendances avec cache clé par fichier de verrou

  • Référence : Install Node 200s à froid, 200s à chaque build.
  • Changement : Cache node_modules clé par package-lock.json.
  • Résultat attendu : Install en cache ~40-60s, invalide seulement au changement de dépendances.
  • Vérification : Observer message de restauration cache et durée d'install.
  • Retour arrière : Si conflits de cache entre branches, incluez $CI_COMMIT_REF_SLUG dans la clé.

4. Diviser les longs tests en toute sécurité

  • Référence : Job de test unique 30min.
  • Changement : parallel: 4 et passer $CI_NODE_INDEX pour sharder les tests.
  • Résultat attendu : 8-12min temps total selon surcoût.
  • Vérification : S'assurer que chaque shard dure dans 10-20% des autres ; ajuster la logique de sharding sinon.
  • Retour arrière : Mettre ENABLE_PARALLEL=0 pour désactiver pendant l'investigation des flakiness.

À quoi ressemble un bon état

  • Temps de file : Sous 60s pour les pipelines courants aux heures ouvrées.
  • Temps de clone : Proportionnel à GIT_DEPTH et taille du repo ; sous 60s pour la plupart des repos avec fetch superficiel.
  • Étapes dépendances : Sous 1 minute avec caches chauds pour les écosystèmes de langages typiques.
  • Artéfacts : Upload/download sous 30s quand limités aux rapports et petits livrables.
  • Stabilité : Taux d'échec n'augmente pas après optimisation ; sinon, annulez le dernier changement.

Conclusion

Vous disposez désormais d'une méthode sûre et progressive pour optimiser les performances de GitLab CI/CD : inventorier l'existant, mesurer ce qui compte, appliquer de petits changements réversibles, vérifier les résultats et opérationnaliser la routine. Commencez par le plus petit pilote facile à mesurer et inspecter, conservez ce qui améliore constamment le débit ou la latence, et déployez délibérément. Revisitez votre inventaire et votre dimensionnement chaque trimestre ou après des changements majeurs de charge (nouveaux langages, dépôts plus gros, nouvelles suites de tests). Avec une mesure disciplinée et des retours arrière prudents, la vitesse des pipelines devient une composante gérée et prévisible de votre système d'ingénierie.

Recherches connexes

Score de qualité de l’article

Utilité pour le lecteur 100%
  • check_circle Guide prêt à lire
  • check_circle Exemples pratiques inclus
  • check_circle URL d’article optimisée pour le SEO