Monorepo vs Polyrepo Porównanie: Kiedy Dane Decydują

Summary

Monorepo vs polyrepo porównanie sprowadza się do jednego wskaźnika: jaki procent twoich ficzerów przekracza granicę serwisową? Faros AI zmierzył 320 zespołów -- monorepo ma medianę PR cycle time 19h, polyrepo 2h, różnica 9,5x. Ale dane opisują typowe PR-y, nie worst-case cross-cutting. Rzeczywisty wybór zależy od blast radius, strategii rolloutów i zdolności platform team do utrzymania toolingu. Reguła 30% daje kierunek.

Diagram architektury monorepo vs polyrepo: zunifikowane drzewo i izolowane klastry na ciemnym tle

Odpowiedź na pytanie o monorepo vs polyrepo porównanie to nie rekomendacja -- to pomiar. Konkretnie: jaki procent twoich ficzerów wymaga zmian w więcej niż jednej granicy serwisowej?

Jeśli nie znasz tej liczby, podejmujesz decyzję infrastrukturalną na podstawie preferencji zespołu, a nie danych. W organizacji 50 inżynierów ta preferencja będzie kosztować kogoś niedzielę.

Słowo klucz: kalkulacja. Oba podejścia generują realne koszty operacyjne. Pytanie brzmi, które koszty twoja organizacja lepiej absorbuje -- podatek koordynacyjny polyrepo czy inwestycja w tooling monorepo.

Dane PR Cycle Time Powinny Rozstrzygnąć Debatę. Nie Rozstrzygają.

Faros AI przeanalizował 320 zespołów inżynierskich przez 12 miesięcy i stwierdził, że środowiska monorepo mają medianę PR cycle time wynoszącą 19 godzin. Środowiska polyrepo: 2 godziny.

To przepaść 9,5x przy medianie. Na 90. percentylu różnica zawęża się do 8,6 dnia wobec 5,5 dnia -- ale oba ogony są wolne. Średnia też się zacieśnia: 3,6 dnia dla monorepo, 2,8 dnia dla polyrepo.

Kontrargument jest dobrze znany: monorepo ma szybsze czasy budowania, gdy cache działa. Zespół polyrepo koordynujący zmianę cross-service przez pięć repozytoriów z pięcioma oddzielnymi pipeline'ami CI i pięcioma oddzielnymi wymaganiami sign-off CODEOWNERS też nie zamknie PR-a w dwie godziny.

Dane rejestrują czas cyklu dla typowych PR-ów, nie dla worst-case zmian cross-cutting. To rozróżnienie ma znaczenie. Zespoły polyrepo cytują swoją medianę (szybka, bo większość ich PR-ów jest izolowanych). Zwolennicy monorepo cytują ból koordynacji między repozytoriami (też realny, udokumentowany w ogonach najgorszych PR-ów). Obie strony mają rację o różnych scenariuszach.

Dane nie rozstrzygają debaty. Opisują kompromis precyzyjniej niż intuicja.

Inżynier SRE monitorujący metryki deploymentu przy stanowisku pracy z wieloma dashboardami

Blast Radius, Którego Nie Kalkulujesz

Oto co rzadko pojawia się na slajdach konferencyjnych: w monorepo uszkodzona shared dependency trafia do każdego serwisu, który ją importuje, w tym samym commicie, zanim ktokolwiek z downstream ownership przejrzał zmianę.

W polyrepo uszkodzona wersja pakietu psuje serwisy, które ją aktualizują -- ale tylko wtedy, gdy to zrobią. Blast radius jest odroczony i ograniczony przez decyzję konsumenta.

To ma znaczenie dla rolloutów z bramą SLO. Zepsuta shared library w monorepo nie daje okna canary. Daje cross-service blast radius w jednym zdarzeniu deploymentu. Twój error budget zaczyna się palić na wielu SLO jednocześnie, zanim automatyzacja rolloutów wykryje wzorzec i wyzwoli revert.

W polyrepo rollout zmiany shared dependency jest z natury sekwencyjny. Serwis A aktualizuje i obserwujesz jego SLO. Serwis B aktualizuje trzy dni później. Blast radius w danym momencie jest ograniczony przez tych, którzy już przyjęli zmianę.

Pytanie nie brzmi, która struktura jest inherentnie bezpieczniejsza -- lecz czym jest twój deployment primitive. Jeśli jednostką deploymentu jest serwis z własną bramą SLO, polyrepo daje naturalną izolację. Jeśli jednostką jest atomiczna zmiana ficzeru lądująca spójnie na frontendzie, w API i w background workerze jednocześnie, monorepo daje tę koordynację bez dryftu wersjonowania.

Większość zespołów shippujących mikroserwisy ma pierwszy problem. Większość zespołów shippujących ściśle powiązaną powierzchnię produktową ma drugi.

Praktyczny test: weź swój ostatni incydent P1. Czy jego root cause wymagał śledzenia stanu przez więcej niż jedno repozytorium? Jeśli tak, zapłaciłeś już koszt, który ponosisz przy polyrepo, nie licząc go formalnie.

Dlaczego Zespoły Polyrepo Uderzają w Ścianę Koordynacyjną przy 50 Inżynierach

Podatek koordynacyjny kumuluje się. Przy 8 inżynierach zarządzanie czterema repozytoriami jest irytujące, ale wykonalne. Przy 50 staje się etatem dla kilku osób.

Konkretne sygnały, że overhead koordynacji polyrepo stał się strukturalny:

To nie są wymyślone patologie. To udokumentowane tryby awarii zespołów, które dotarły do 80 inżynierów i spojrzały wstecz na swoje decyzje dotyczące repo z żalem.

Polyrepo działa, gdy zespoły są naprawdę niezależne -- różne cykle wydań, różne tech stacki, różne on-call rotacje. Gdy zespoły współdzielą wystarczająco dużo kodu, że zmiana w jednym serwisie wymaga rozumowania o trzech innych, izolacja, którą polyrepo miało zapewniać, staje się mechanizmem utrudniającym koordynację.

Organizacyjny wskaźnik: policz, ile kanałów Slack istnieje wyłącznie po to, by koordynować release'y między repozytoriami. Jeśli odpowiedź brzmi więcej niż zero, zacząłeś już płacić podatek koordynacyjny regularnie.

Znany wzorzec z organizacji 80+ inżynierów: platform team zaczyna utrzymywać arkusz kalkulacyjny śledzący, które wersje shared library ma każdy serwis. To moment, w którym decyzja o polyrepo powinna zostać poddana ponownemu przeglądowi -- nie dlatego, że polyrepo jest złe, ale dlatego, że arkusz kalkulacyjny oznacza, że izolacja przestała działać jako zakładana.

Rozróżnienie, które pomaga: polyrepo między zespołami o genuinely różnych domenach (payments vs. ML vs. mobile) to poprawna izolacja. Polyrepo między serwisami współdzielącymi ten sam model danych, tę samą shared library auth i ten sam cykl wydań to tylko administracyjna separacja z kosztami koordynacji bez korzyści izolacji.

Rzeczywisty Koszt Monorepo na 95. Percentylu

Dane P90 od Faros AI są instruktywne: 8,6 dnia dla PR-ów monorepo na 90. percentylu. To nie jest wolny zespół -- to strukturalna konsekwencja dużych zmian cross-cutting wymagających koordynacji między wieloma code ownerami, szerszymi matrycami CI i cyklami review przekraczającymi granice organizacyjne.

Google ma Bazel. Meta zbudowało Buck. Nx Cloud i Turborepo remote cache istnieją, bo inwestycja w tooling niezbędna do sprawnego działania monorepo nie jest trywialna. Monorepo dla 200 inżynierów bez affected-only build selection, distributed caching i automatycznych merge queues produkuje 45-minutowe uruchomienia CI na PR-ach dotykających współdzielonej funkcji narzędziowej.

Koszt toolingu jest realny i rutynowo niedoszacowany. Zespoły, które skutecznie obsługują monorepo w skali, zazwyczaj zatrudniły platform engineerów skupionych konkretnie na tej infrastrukturze. Doposażanie monorepo tooling w rosnącą codebase przy jednoczesnym shippowaniu produktu to obciążenie, które pojawia się w częstotliwości deploymentów, zanim pojawi się w post-mortemie.

Jeśli twój platform team jest już przeciążony, dodanie utrzymania monorepo tooling to znaczące zobowiązanie -- nie wybór konfiguracji.

Diagram architektury na tablicy pokazujący struktury pipeline'ów dla monorepo i polyrepo

Reguła 30 Procent, Której Faktycznie Używają Wysokowydajne Zespoły

Użyteczna heurystyka od zespołów, które podjęły tę decyzję świadomie: jeśli ponad 30% twoich ficzerów wymaga zmian w wielu granicach serwisowych, overhead koordynacji polyrepo z czasem przekroczy inwestycję w dobrze prowadzone monorepo.

Poniżej 30% -- gdzie siedzi większość organizacji mikroserwisowych -- korzyści z izolacji polyrepo zwykle przeważają nad podatkiem koordynacyjnym. Zmiany cross-service zdarzają się, ale nie na tyle często, by shared tooling opłacił się szybciej niż izolacja.

To jest mierzalne. Wyciągnij swoje zmergowane PR-y z ostatnich sześciu miesięcy i policz, ile wymagało zmian w więcej niż jednym repozytorium, żeby dostarczyć jeden ficzere widoczny dla użytkownika. Ten wskaźnik to twoje wejście. Nie będzie dokładny do dziesiątej części, ale będzie kierunkowy -- a kierunkowy wystarczy, żeby zatrzymać debatę napędzaną preferencjami zespołu.

Zespół ze wskaźnikiem cross-service 12% nie potrzebuje monorepo. Zespół na 38% i rosnący płaci podatek koordynacyjny, który będzie się kumulować.

Jak Strategia Rolloutów Zmienia Kalkulację

Jest wymiar tej decyzji, który prawie nie pojawia się w omówieniach: twój deployment primitive.

Jeśli uruchamiasz rollout procentowy z bramami SLO -- shippujesz ficzere do 5% ruchu, obserwujesz error budgety, a następnie stopniowo rozszerzasz -- twoja kalkulacja blast radius zmienia się w zależności od tego, czy ficzere obejmuje jeden serwis czy kilka.

W polyrepo rollout multi-service ficzere wymaga koordynacji stanu rolloutów między serwisami. Serwis A może być na 20%, podczas gdy Serwis B jest wciąż na 0%, tworząc niespójne stany, które są naprawdę trudne do rozumowania podczas incydentu. Feature flagi pomagają, ale wciąż zarządzasz cross-service flag state bez jednego źródła prawdy dla postępu rolloutu.

W monorepo z atomicznymi commitami ficzere ląduje spójnie we wszystkich serwisach. Rollout może być nadal procentowy na poziomie infrastruktury, ale kod jest spójny od momentu deploymentu. Twoje bramy SLO odpalają się na spójnym stanie.

Zespoły realizujące wiele atomicznych multi-service ficzerów, uruchamiające progressive rollouts z automatycznym rollbackiem przy naruszeniu SLO, często odkrywają, że spójność monorepo eliminuje całą kategorię incydentów, których polyrepo nie ma czystej nazwy -- incydent cross-service state divergence, który wygląda jak bug, ale w rzeczywistości jest problemem koordynacji deploymentu.

To nie jest teoretyczny scenariusz. Incydenty tego typu mają charakterystyczny pattern w post-mortemach: timeline deploymentu pokazuje dwie zmiany w dwóch repozytoriach, każda osobno zatwierdzona przez CODEOWNERS, żadna z nich nie jest bugiem samodzielnie -- ale razem tworzą niespójny stan, który pojawia się tylko w produkcji, pod rzeczywistym ruchem.

Co Faktycznie Powie Post-Mortem

Większość organizacji inżynierskich kończy na hybrydzie, której nikt nie nazywa hybrydą, bo brzmi jak architektoniczny kompromis.

Jedno lub dwa monorepo dla ściśle powiązanych powierzchni produktowych. Osobne repozytoria dla naprawdę autonomicznych serwisów z niezależnymi cyklami deploymentu, własną on-call rotacją i zespołem, który od sześciu miesięcy nie musiał koordynować zmiany shared library.

Sygnał, żeby ponownie ocenić swoje aktualne ustawienie:

Sygnał, że decyzja jest na razie dobra:

Post-mortem powie ci, w którym z tych konkretnych scenariuszy faktycznie żyjesz. Ten dokument jest zazwyczaj bardziej szczery niż Architecture Decision Record, który poprzedził opisywany przez niego system.

Frequently asked questions

Czym jest monorepo vs polyrepo?
Monorepo to jedno repozytorium Git zawierające kod wielu serwisów lub komponentów. Polyrepo to strategia, gdzie każdy serwis ma własne, oddzielne repozytorium. Oba podejścia mają kompromisy zależne od wielkości organizacji, struktury teamów i częstotliwości zmian cross-service.
Kiedy wybrać monorepo?
Monorepo sprawdza się, gdy ponad 30% ficzerów wymaga zmian w wielu serwisach jednocześnie, gdy potrzebujesz atomicznych commitów dla spójności multi-service, lub gdy masz platform team z możliwością utrzymania dedykowanego toolingu (Bazel, Nx, Turborepo).
Kiedy wybrać polyrepo?
Polyrepo działa dobrze, gdy serwisy są naprawdę niezależne -- różne cykle release'ów, różne tech stacki, różne on-call rotacje. Poniżej 30% współczynnika zmian cross-service, izolacja polyrepo zwykle przewyższa koszty koordynacji.
Jakie są rzeczywiste dane porównujące monorepo vs polyrepo?
Faros AI przeanalizował 320 zespołów przez 12 miesięcy. Mediana PR cycle time: monorepo 19h, polyrepo 2h (9,5x różnicy). Na 90. percentylu: monorepo 8,6 dnia, polyrepo 5,5 dnia. Dane opisują typowe PR-y, a nie worst-case scenariusze cross-cutting.
Czy duże firmy używają monorepo?
Google i Meta używają monorepo na dużą skalę z niestandardowymi systemami budowania -- odpowiednio Bazel i Buck. Ta skala wymaga dedykowanych platform teams. Dla organizacji 50-200 inżynierów inwestycja toolingowa jest znacząca i często niedoszacowana.
Co to jest blast radius w kontekście wyboru między monorepo a polyrepo?
Blast radius to zakres wpływu uszkodzonej zmiany. W monorepo zepsuta shared dependency trafia atomicznie do wszystkich serwisów ją importujących w jednym commicie. W polyrepo blast radius jest odroczony -- serwisy adoptują zmianę gdy wybiorą, dając naturalne okno canary dla obserwacji SLO.
Jak zmierzyć, czy moja organizacja potrzebuje monorepo?
Wyciągnij zmergowane PR-y z ostatnich sześciu miesięcy i policz, ile wymagało zmian w więcej niż jednym repozytorium, żeby dostarczyć jeden ficzere widoczny dla użytkownika. Powyżej 30% -- rozważ monorepo. Poniżej 12% -- polyrepo jest prawdopodobnie wystarczające.