Dług techniczny: szczera perspektywa platform engineera
Summary
Czym jest dług techniczny? To nie metryka jakości kodu, ale ryzyko operacyjne, które narasta w tempie potęgowym. Artykuł analizuje go przez pryzmat platform engineering i SRE: jak się akumuluje, klasyfikuje się według ryzyka, mierzy metrykami DORA i zarządza jak alertem produkcyjnym.
Dług techniczny: szczera perspektywa platform engineera
Czym jest dług techniczny? To nie jest problem kodowania czy braku czyszczenia kodu. To rzeczywiste, mierzalne ryzyko operacyjne, które narasta w tempie potęgowym i pojawia się w najgorszy możliwy moment: podczas incident response o 2 rano. Dla platform engineerów i SRE dług techniczny to kategoria ryzyka deploymentu, a nie metryka SonarQube.
W ciągu ostatnich pięciu lat obserwowaliśmy wspólny wzorzec u zespołów o wysokim MTTR i niskiej deployment frequency: nigdy nie mówili "mamy dług techniczny". Zamiast tego mówili "musimy być ostrożni z tym deploymentem" lub "to jest zbyt ryzykowne". Są to oznaki długu technicznego, który zaczyna kontrolować twoją architekturę.
Scena: 3 rano, alerta PagerDuty o timeoucie aplikacji
Budzisz się. Na dashboardzie widzisz, że czasy odpowiedzi p99 skoczyły z 150ms do 3500ms. Deployment z wczoraj wydawał się OK w canary. Czemu się rozpadł?
Zaglądasz do kodu. Refaktoryzacja z trzech miesięcy temu pozwoliła deweloperom dodać logikę bez modyfikowania cache'u. Wtedy nikomu się nie spieszyło, była to zmiana niskopriorytetowa. Teraz, pod obciążeniem, ta "niedokończona praca" to jedyne wyjaśnienie degradacji.
To jest dług techniczny. Nie jako metryka SonarQube. Jako awaria mająca miejsce w produkcji. I będzie to pojawiać się w raporcie post-mortem jako punkt "root cause: incomplete refactoring from 3 months ago".
Dług techniczny to nie "brudny kod" - to operacyjne ryzyko
Większość zespołów myśli o długu technicznym jako o problecie jakości kodu. Linter zgłasza, metryka spada, Dev Lead pisze memo. Ale dla SRE i platform engineerów to coś zupełnie innego.
Dług techniczny to wszystko, co zmniejsza twoją zdolność do bezpiecznego deploymentu i szybkiego powrotu do stanu zdolności obsługi. To może być:
Dokumentacja wdrażania zamiast automation w Terraform
Manualne kroki w runbook zamiast self-healing mechanizmów
Brana usytuowana w jednym data center zamiast multi-region setup
Kod monolityczny, którego zmiana może zburzyć pół systemu
Alerting, który mówi "coś się stało", ale nie "co się stało"
Brak contract testing między serwisami
Rollback proces, który wymaga ręcznych weryfikacji
Obserwacja, która może obejmować 70% request flow, ale brakuje ostatnich 30%
Wszystkie te rzeczy są długiem technicznym. Nie dlatego że kod jest "niechlujny", ale dlatego że zwiększają blast radius, wydłużają MTTR i ograniczają SLO budget.
Jak mówi się na post-mortem: "To było do przewidzenia". I zawsze prawda jest taka: była możliwość zainteresowania się tym wcześniej, zanim się awaria zdarzyła.
Jak dług techniczny narasta - i dlaczego metryki DORA cię o tym powiedzą
Dług techniczny nie pojawia się nagle. Pojawia się stopniowo, w decyzjach, które wydają się rozsądne w momencie ich podjęcia. Zespół pod presją, deadline tuż za rogiem, business czeka na feature. Wtedy padają takie zdania:
"Wdrażamy, ale bez testu integracyjnego - mamy SLA do spełnienia."
"Zmieniamy topologię sieci - najpierw w staging, deployment do prod jutro."
"Alerting mówi tylko o CPU - obserwacja aplikacyjna może poczekać."
"Rollback manual, bo automation zajęłoby sprint."
"Dokumentacja? Wiemy jak to działa, nie potrzebujemy runbook."
"Testy integracyjne? Mamy staging environment, tego wystarczy."
Każda z tych decyzji to mały dług. Razem? To kombinacja, którą zobaczysz pierwsza na dashboardzie DORA:
Deployment Frequency: pada. Bo każdy deployment wymaga więcej testów ręcznych.
Change Failure Rate: rośnie. Bo brakuje ci observability, aby wziąć pod uwagę edge case'y.
MTTR: wydłuża się. Bo runbook wymaga ręcznych kroków i bez automacji.
MTBF (Mean Time Between Failures): maleje. Bo blast radius robi się większy z każdą zmianą.
Patrz na te metryki przed 2 rano. Jeśli spadają systematycznie, dług techniczny się akumuluje. Nie jest to wróżba - to matematyka operacyjna.
Klasyfikacja długu technicznego: ryzyka operacyjne, które się liczą
Nie każdy dług techniczny jest równie niebezpieczny. Platform engineer musi wiedzieć, co priorytetyzować. Dlatego właśnie klasyfikujemy dług wg ryzyka operacyjnego, nie wg czystości kodu.
Klasyfikuj dług techniczny wg operacyjnego ryzyka:
Kategoria A - Dług o wysokim blast radius (Priorytet 1)
Zmiana w jednym miejscu kodu może zawalić usługę
Brakuje feature flag lub canary deployment
Brakuje automatycznego rollbacku
Single point of failure w infrastrukturze
Przykład: Monolith, gdzie zmiana w jednym module może zburzyć routing dla całej aplikacji. Blast radius = 100% ruchu. MTTR = 30 minut manualnego debuggingu. Ryzyko operacyjne: KRYTYCZNE.
Kategoria B - Dług ze średnim wpływem (Priorytet 2)
Brakuje obserwacji, ale failover jest automatyczny
Zmiana wymaga testów ręcznych, ale rollback jest szybki
Dokumentacja zamiast IaC, ale procedura jest zautomatyzowana
Obserwacja aplikacji bez SLO alarmów
Przykład: Microservice z dobrą remediacją, ale bez metryk dotyczących SLO. Jeśli coś pójdzie nie tak, deteksja zajmie 5 minut, ale powrót do zdolności zajmie 20 minut.
Kategoria C - Dług techniczny o niskim wpływie (Priorytet 3)
Brakuje optimizacji wydajności
Kod może być czytelniejszy
Metrics'i mogą być bardziej szczegółowe
Stare zależności, ale bez luk bezpieczeństwa
Przykład: Stara biblioteka, którą można zaaktualizować, ale która działa stabilnie w produkcji od lat bez żadnych problemów.
Priorytety to klucz. Zawsze załataj Kategorię A i B zanim zaśpisz w backlogu Kategorię C. Można pracować na obu równocześnie, ale A/B muszą być zawsze w focus.
Narzędzia do deteksji długu technicznego - co mierzyć, co ignorować
Podczas gdy linter i SonarQube mogą być przydatne dla zespołu dev, platform engineer musi mierzyć inne rzeczy. Musisz wiedzieć, co się łamie, kiedy się łamie i jak szybko się naprawia.
Narzędzia właściwe dla SRE:
Datadog: SLO tracking, obserwacja deployment'u, korelacja zmiany z incydentem, error tracking i flame graphs
CodeScene: Analiza historii zmian - gdzie się zmieniało, ile czasu zajęło, ile było rollback'ów, hotspot detection
SonarQube: Architektura kodu i cycle metrics (ale to dopiero drugorzędne dla SRE)
GitHub Copilot: Nie mierzy długu - ale pomaga go redukować szybko w daily work
Priorytetizuj narzędzia, które odpowiadają na pytania:
"Jak długo zajmuje wdrożenie zmian?" (Deployment Frequency)
"Ile zmian powoduje incydent?" (Change Failure Rate)
"Jak szybko się odzyskujemy?" (MTTR)
"Jaki jest mój SLO budget?" (Error Budget - ile czasu możemy być down)
"Gdzie są hotspoty w kodzie?" (Code churn analysis)
Dobre narzędzie to takie, które może odpowiedzieć: "W ostatnich 30 dni 3 deployments z 120 spowodowały incident. Średni MTTR wynosił 45 minut. Najczęstszym punktem awarii była brana usytuowana w jednym data center."
Trójkąt kompromisu: szybkość, bezpieczeństwo, zakres
Każde główne wdrażanie to kompromis. Matematyka jest prosta: możesz mieć dwa z trzech parametrów, ale nie wszystkie trzy naraz.
Scenario A - Szybkość High, Bezpieczeństwo High, Zakres Mały (krytyczne systemy) Scenario B - Szybkość High, Bezpieczeństwo Średnie, Zakres Duży (feature release) Scenario C - Szybkość Średnia, Bezpieczeństwo High, Zakres Duży (strategiczny projekt)
Dług techniczny to wynik wyboru kompromisu bez jasnego zdefiniowania go. Kiedy wybierasz "szybkość + zakres" bez powiedzenia "zaakceptuję wzrost blast radius", to już zaciągnąłeś dług bez umowy. Równiez nie powiedziałeś zespołowi, jakie ryzyko przyjmujesz.
Dyskusja powinna być jawna i udokumentowana: "Chcemy wdrożyć to w 2 tygodnie bez zmian w architekturze. Oznacza to x dni manualnego testowania i y dodatkowych alertów. Zaakceptowaliśmy to świadomie, a oto nasz plan redukcji tego długu w Q4."
Zarządzanie długiem technicznym - metodyka i rytm
Dług techniczny się nie redukuje samym chęciami. Redukuje się przez systematyczne działania i budżetowanie czasu.
Tygodniowy rytm:
Przeglądaj DORA metryki. Jeśli trend pada, dług się akumuluje.
Przeanalizuj 3 ostatnie incydenty. Jaki był wspólny mianownik? Niemal zawsze to dług techniczny.
W backlogu: 20% czasu zespołu na redukcję długu kategorii A/B.
Dokumentuj każdą decyzję o akceptacji kompromisu.
Co miesiąc:
Porównaj szybkość deploymentu z podobnymi zespołami (benchmark)
Zbadaj, które komponenty mają największy MTTR
Decyduj, co refaktoryzować - zawsze podając powód w DORA metrykach, nie w "czystości kodu"
Przywołaj te metryki w retrospektywach
Co kwartał:
Retrospektywa infrastruktury. Jak zmienił się blast radius?
Plan czyszczenia - które schematy zmienić na IaC?
Analiza post-mortem: czy dług techniczny był czynnikiem?
Business case dla refaktoryzacji: ile czasu zaoszczędzę na redukcji MTTR?
Prawda o long-termu: najlepsze zespoły nie mają mniej długu - mają kontrolę
Tutaj przychodzi kluczowa obserwacja. Najstare, największe systemy mają również największy dług techniczny. Google. Amazon. Shopify. Wszyscy wiedzą, że mają go, bo to naturalny wynik ewolucji systemu.
Różnica między zespołami, które cierpią, a tymi, które radzą sobie dobrze:
Zespoły, które cierpią:
Nie widzą długu (metryki DORA są "w porządku" - ale to fałszywa pewność)
Nie klasyfikują go (wszystko jest priorytet 1)
Nie budżetują go (nie ma czasu na jego redukcję)
Dowiadują się o nim podczas outage
Nie mają procesu wyceny decyzji o kompromisach
Zespoły, które mają kontrolę:
Mierzą dług przez operacyjne ryzyko, nie przez lintera
Klasyfikują go na A/B/C i działają na tej podstawie
Budżetują 20% capacity na redukcję długu A/B
Monitorują trendy DORA i reagują przed incydentem
Dokumentują każdy kompromis i plan jego redukcji
Jeśli zaczeńcie mierzyć dług techniczny przez operacyjne ryzyko (nie przez linter), priorytety staną się jasne. Jeśli zabudżetujecie 20% czasu na jego redukcję, zmiana będzie widoczna w ciągu kwartału. MTTR spadnie, deployment frequency pójdzie w górę.
A jeśli będzie 2 rano i budzisz się na alerta - będziesz wiedzieć, że to dług, który mogłeś wczoraj zmierzyć na dashboardzie. I masz plan, jak go zmniejszać systematycznie.