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.
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.

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:
Twój platform team utrzymuje repo shared-libraries, którego nikt wyraźnie nie posiada
Wersjonowanie między serwisami zdriftowało na tyle, że bump shared library to projekt na dwa tygodnie
Nowy inżynier nie może być produktywny bez zrozumienia, które z 23 repozytoriów sklonować najpierw
Patche bezpieczeństwa do shared dependencies wymagają skoordynowanych PR-ów w kilkunastu repozytoriach, śledzone w arkuszu kalkulacyjnym
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.

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:
Częstotliwość zmian cross-service przekroczyła 30%, a czasy CI się kumulują
Zatrudniłeś platform engineerów z możliwością inwestowania w monorepo tooling
Incydent blast radius ujawnił, że izolacja polyrepo była fałszywa -- serwisy współdzieliły wystarczająco dużo infrastruktury, że izolacja zapewniała komfort, nie bezpieczeństwo
Sygnał, że decyzja jest na razie dobra:
Zespoły są naprawdę niezależne, a overhead koordynacji jest niski
Twój najgorszy incydent nie był spowodowany dryftem cross-service dependency
Możliwości platform engineering nie istnieją, by utrzymać monorepo tooling bez spowalniania dostarczania produktu
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.