Skalowanie SaaS po starcie bez psucia produktu
Start był łatwą częścią. Niebezpieczny odcinek to kolejny rok, gdy wzrost po cichu rozsadza prosty produkt, który Państwa tu doprowadził. Oto spokojny, praktyczny przewodnik po skalowaniu bez powolnego załamania.

Każdy świętuje start. Niemal nikt nie ostrzega przed tym, co przychodzi później — dziwnym, nerwowym rokiem, gdy produkt, który zdobył pierwszą setkę klientów, zaczyna uginać się pod ciężarem następnego tysiąca. Nic dramatycznego się nie dzieje. Po prostu wszystko robi się wolniejsze, bardziej kapryśne, trudniejsze do zmiany. Pewnego wtorku uświadamiają sobie Państwo, że funkcja, która kiedyś zajmowała dzień, teraz zajmuje tydzień, i nikt nie potrafi do końca powiedzieć, dlaczego. To tam, a nie przy starcie, większość produktów SaaS po cichu wygrywa lub przegrywa.
Siedzieliśmy z wieloma założycielami właśnie w tym punkcie. Oni nie ponoszą porażki — to jest właśnie mylące. Przychody rosną, zespół się powiększa, demo wypadają dobrze. Ale pod spodem produkt jęczy. Zgłoszenia do wsparcia rosną szybciej niż liczba użytkowników. Wdrożenia, które kiedyś były nudne, teraz odbywają się z wstrzymanym oddechem. Baza kodu, która rok temu wydawała się sprytna, teraz przypomina pole minowe, gdzie każda zmiana grozi uruchomieniem czegoś innego. Nie zrobili nic źle. Po prostu wyrośli z tego, co zbudowali, a nikt im nie powiedział, że tak miało być.
Oto przewodnik, który chcielibyśmy, by więcej założycieli miało, zanim pojawiły się pęknięcia. Nie chodzi o hiperskalę, Kubernetes ani o to, co zrobił jakiś jednorożec przy pięćdziesięciu milionach użytkowników. Chodzi o nudny, decydujący środek — przejście od działa dla nielicznych do działa dla wielu — bez przepisywania wszystkiego, odstraszania klientów czy wypalania zespołu. Celem nie jest idealna architektura. To produkt, który dalej rośnie, zamiast takiego, który po cichu zaczyna się psuć.
Co naprawdę pęka, gdy SaaS rośnie
Oto część, która najbardziej zaskakuje założycieli: problemy ze skalowaniem niemal nigdy nie przychodzą jako dramatyczna awaria, na którą się Państwo przygotowują. Serwer nie staje w płomieniach. Zamiast tego produkt rozwija coś w rodzaju utajonej gorączki. Strony, które ładowały się natychmiast, zaczynają zajmować trzy sekundy. Raport, który działał dobrze u wczesnych klientów, przekracza limit czasu u dużego, który właśnie podpisał umowę. Ten sam błąd wraca, bo dwie części kodu skrycie zależą od siebie w sposób, którego nikt nie udokumentował.
To, co naprawdę pęka, to rzadko Państwa serwery — to Państwa założenia. Na początku budowali Państwo pod kształt pierwszych użytkowników: kilka kont, mało danych, proste przepływy pracy, wszyscy mniej więcej tacy sami. Wzrost nie dodaje tylko więcej tego samego. Dodaje różnorodność. Klient z dziesięciokrotnie większą ilością danych. Zespół, który używa funkcji w sposób, jakiego Państwo nigdy nie przewidzieli. Skok o 9 rano w poniedziałek, gdy wszyscy logują się naraz. Każdy z nich po cichu łamie założenie wpisane w kod rok temu, gdy jego złamanie było nie do pomyślenia.
“Produkt nie pęka dlatego, że zyskali Państwo więcej użytkowników. Pęka dlatego, że ci użytkownicy różnią się między sobą bardziej, niż kiedykolwiek różnili się pierwsi.”
Cztery miejsca, w których zwykle ujawnia się to najpierw, są przewidywalne. Baza danych jest niemal zawsze kanarkiem — zapytania, które były natychmiastowe na małych tabelach, pełzną w miarę wzrostu danych. Wolny endpoint: jedna lub dwie strony wykonujące zbyt dużo pracy na żądanie, w porządku do momentu, gdy ruch się spiętrzy. Kruche wdrożenie, gdzie wypuszczenie czegokolwiek stało się przerażające, bo kod jest zbyt splątany, by go ogarnąć. I obciążenie wsparcia, które w ogóle nie jest infrastrukturą, ale jest najprawdziwszym wczesnym sygnałem, że produkt już nie pasuje do tego, jak ludzie naprawdę go używają.

Pułapka rozwiązywania problemów, których jeszcze Państwo nie mają
Zanim porozmawiamy o naprawianiu, ostrzeżenie, które uratowało więcej produktów niż jakakolwiek optymalizacja. Największym zagrożeniem dla rosnącego SaaS nie jest ignorowanie skali — to ściganie jej zbyt wcześnie. W chwili, gdy założyciel poczuje pierwsze spowolnienie, instynkt każe sięgnąć po architekturę, o której czytał na słynnym blogu inżynierskim. Mikroserwisy. Kolejka komunikatów. Konfiguracja wieloregionalna. Sharding bazy danych, zanim ma ona milion wierszy.
Tak właśnie wydaje się sześć miesięcy i fortunę na budowę infrastruktury dla skali, której się nie osiągnęło, podczas gdy sam produkt przestaje się ruszać. Co gorsza, każda przyszła zmiana stała się teraz trudniejsza, bo system rozproszony jest dramatycznie bardziej złożony w budowie i debugowaniu niż prosty, który Państwo mieli. Wymienili Państwo problem, którego jeszcze nie mieli, na gwarantowany, który mają dziś: nic nie wychodzi na produkcję.
Dyscyplina jest tu ta sama, która w ogóle tworzy dobre produkty: rozwiązuj problem, który masz przed sobą, a nie ten, który schlebia ci wyobrażać. Nudny, dobrze rozumiany monolit, który można szybko zmienić, przeskaluje modny system rozproszony, którego boją się Państwo dotknąć. Złożoność to koszt płacony każdego dnia, a nie jednorazowy zakup.
Mierz, zanim cokolwiek zmienisz
Niemal każdy założyciel, którego spotykamy na tym etapie, jest przekonany, że wie, gdzie jest problem. W połowie przypadków się myli — nie z niedbalstwa, ale dlatego, że intuicja to fatalny profiler. Część kodu, która wydaje się wolna, często jest w porządku; prawdziwym winowajcą jest jakieś ciche zapytanie uruchamiane czterdzieści razy na stronie, o której nikt nie pomyślał. Nie da się naprawić tego, czego się nie zmierzyło, a zgadywanie to sposób, w jaki zespoły spędzają tygodnie na optymalizacji nie tego, co trzeba.
Aby zacząć, nie potrzebują Państwo wymyślnego stosu observability. Potrzebują trzech nudnych liczb przed oczami, przez cały czas. Które endpointy są najwolniejsze i jak wolne pod realnym ruchem. Które zapytania do bazy zabierają najwięcej łącznego czasu — nie najwolniejsze pojedyncze zapytanie, lecz to, którego czas sumuje się przez tysiące wywołań. I gdzie naprawdę występują błędy, z dostatecznym kontekstem, by je odtworzyć. Z tymi trzema mgła zwykle opada w ciągu dnia.
- 1Włącz podstawowy monitoringCzasy odpowiedzi na endpoint, wskaźniki błędów i logowanie wolnych zapytań w bazie. Narzędzia hostowane robią to w jedno popołudnie. Nie da się poprawić liczby, której się nie widzi.
- 2Znajdź prawdziwą pierwszą trójkęSortuj według łącznie zużytego czasu, a nie według przeczucia. Trzech winowajców niemal zawsze odpowiada za większość bólu. Zapisz je — to Państwa prawdziwa mapa drogowa.
- 3Napraw jedno, zmierz ponownieZmień jedną rzecz, potem sprawdź liczby ponownie. Potwierdź, że pomogło, zanim ruszysz dalej. Dwie zmiany naraz i nigdy nie dowiesz się, która miała znaczenie.
- 4Przestań, gdy jest wystarczająco dobrzeZdefiniuj 'wystarczająco szybko', zanim zaczniesz — powiedzmy, każda strona poniżej sekundy przy obecnym obciążeniu. Powyżej tego optymalizacja to pochłaniacz czasu, nie wygrana.
Ten ostatni krok znaczy więcej, niż się wydaje. Praca nad wydajnością jest naprawdę uzależniająca; zawsze jest jeszcze jedna milisekunda do ścięcia. Ale klienci nie czują różnicy między 200 ms a 120 ms, a godziny poświęcone na jej gonienie to godziny niespędzone nad funkcją, która naprawdę rozwinęłaby firmę. Zmierz, napraw pierwszą trójkę, ogłoś zwycięstwo, idź dalej.
Baza danych to niemal zawsze pierwsza ściana
Gdybyśmy mieli postawić pieniądze na to, gdzie rosnący SaaS uderza w pierwszy prawdziwy sufit, za każdym razem postawilibyśmy na bazę danych. To jedna część systemu, w której małe wczesne decyzje kumulują się najmocniej. Zapytanie bez indeksu działa w mgnieniu oka na tysiącu wierszy i grzęźnie na milionie. Kod się nie zmienił. Zmieniły się dane — a dane tylko rosną.
Dobra wiadomość jest taka, że baza danych to także miejsce, gdzie tkwią najtańsze poprawki o największym wpływie. Klasyczną jest brakujący indeks: pojedyncza linijka, która zamienia wielosekundowe zapytanie w natychmiastowe, bo baza przestaje skanować każdy wiersz, by znaleźć tych kilka, których potrzebuje. Tuż za nim jest problem zapytań N+1 — strona, która zamiast zadać jedno pytanie, po cichu zadaje bazie to samo małe pytanie setki razy w pętli. Oba są powszechne, oba niewidoczne, dopóki się nie spojrzy, i oba zwykle są naprawą na jeden dzień, gdy się je znajdzie.
Jest tu kolejność, na której warto się oprzeć, i opłaca się podążać za nią po kolei, a nie przeskakiwać na koniec. Najpierw napraw zapytania — indeksy, N+1, wolny raport. Potem dodaj cache dla danych czytanych nieustannie, ale rzadko zmienianych. Dopiero potem ma sens rozmowa o replikach do odczytu, większych instancjach czy rozdzielaniu danych. Większość produktów SaaS nigdy nie potrzebuje późniejszych kroków. Potrzebowały tylko porządnie wykonanych pierwszych.

Skalowanie produktu oznacza skalowanie tego, jak go zmieniacie
Oto zwrot, który zaskakuje założycieli: powyżej pewnego punktu skalowanie przestaje dotyczyć tego, jak produkt obsługuje więcej użytkowników, a zaczyna dotyczyć tego, jak Państwa zespół obsługuje więcej zmian. Gdy byli Państwo we dwoje z jednym programistą, każdy trzymał cały system w głowie. Można było zmienić cokolwiek, bo wiedziało się, czego to dotknie. Przy pięciu czy dziesięciu osobach ten model myślowy się rozpada — a kod, który zakładał, że każdy wie wszystko, staje się obciążeniem.
To prawdziwy powód, dla którego wdrożenia stają się przerażające. Nie chodzi o to, że kod pogorszył się z dnia na dzień; chodzi o to, że nikt nie potrafi już w pełni przewidzieć zasięgu rażenia zmiany. Rozwiązaniem nie jest bohaterstwo ani zamrożenie wydań. To inwestycja w nieefektowne rusztowanie, które pozwala większemu zespołowi działać, nie wchodząc sobie w drogę: automatyczny zestaw testów wyłapujący oczywiste awarie, wdrożenia będące rutyną zamiast ceremonią oraz sposób na wyłączenie złego wydania w sekundy zamiast improwizowania.
- Zestaw testów pokrywający tę garstkę przepływów, które byłyby katastrofalne, gdyby się zepsuły — logowanie, płatność, kluczowa akcja. Nie wszystko; te krytyczne nieliczne.
- Wdrożenia uruchamiane jednym przyciskiem, a nie rytuałem, by wypuszczanie małe i częste stawało się bezpieczne, a nie stresujące.
- Szybki sposób na wycofanie, by złe wydanie było pięciominutowym zdarzeniem, a nie całonocnym incydentem.
- Feature flagi, by można było wypuścić kod najpierw do kilku klientów i natychmiast go wyłączyć, jeśli się źle zachowa.
- Tyle dokumentacji, by urlop jednej osoby nie zamrażał całego obszaru produktu.
Nic z tego nie pojawia się w demo. Nic z tego nie dodaje wprost funkcji. I to dokładnie ta praca odróżnia produkt, który dalej przyspiesza, od takiego, który z każdym nowym pracownikiem miele wolniej. Zespoły, które dobrze skalują, to te, które traktują swoją zdolność do bezpiecznej zmiany produktu jako funkcję samą w sobie — bo przy skali to właśnie nią jest.
Krótka historia z punktu pękania
Aby to skonkretyzować, oto kompozyt oparty na pracy, którą wykonaliśmy — szczegóły rozmyte, kształt wierny życiu. Mały SaaS do zarządzania zespołami serwisu terenowego dobrze wystartował i urósł do kilkuset płacących firm. Założyciele byli w równej mierze zachwyceni i wyczerpani. Wtedy podpisał największy w historii klient: firma z większą liczbą użytkowników i większą ilością danych historycznych niż dziesięciu poprzednich klientów razem wziętych.
W ciągu tygodnia pulpit, w którym wszyscy żyli, zwolnił do pełzania dla tego klienta — i, co dziwne, dla wszystkich innych też. Zgłoszenia do wsparcia wystrzeliły. Założyciele zakładali, że potrzebują znacznie większego serwera, i szykowali się na bolesną, kosztowną przebudowę architektury. To był moment, w którym nas wezwano, a instynkt był zrozumiały, lecz błędny.
Nie tknęliśmy architektury. Włączyliśmy logowanie wolnych zapytań i obserwowaliśmy przez popołudnie. Winowajca był niemal żenująco mały: główny pulpit ładował listę zadań każdego użytkownika klasycznym wzorcem N+1, odpalając jedno zapytanie na zadanie. Dla małego klienta oznaczało to kilkadziesiąt nieszkodliwych zapytań. Dla nowego giganta oznaczało tysiące na załadowanie strony — co na współdzielonej infrastrukturze ściągało cały system w dół dla wszystkich.
Lekcja, którą wynieśli założyciele, nie była techniczna. Było nią to, że przerażający problem skalowania, który sobie wyobrazili — ten wymagający przebudowy i rundy finansowania — po zmierzeniu okazał się dwudniową naprawą ukrytą za strasznym objawem. Mieli właśnie spędzić miesiące na rozwiązywaniu nie tego problemu. Ta przepaść, między wyobrażonym kryzysem a zmierzonym, to miejsce, gdzie marnuje się większość pieniędzy na skalowanie.
Kiedy naprawdę nadszedł czas przebudować jakiś element
Cała ta ostrożność wobec przedwczesnego skalowania może brzmieć jak nigdy nie refaktoryzuj, nigdy nie przebudowuj. Nie o to chodzi. Czasem część produktu naprawdę dobiegła kresu swojego życia, a kolejne łatanie jej to kosztowny wybór. Sztuką jest odróżnienie prawdziwego ograniczenia strukturalnego od zwykłych bólów wzrostu, z którymi poradziłaby sobie zmierzona naprawa.
Uczciwy sygnał jest taki: przebuduj komponent, gdy koszt jego zmiany stał się konsekwentnie wyższy niż koszt jego wymiany. Nie wtedy, gdy jest brzydki — brzydki kod, który jest stabilny i rzadko ruszany, jest w porządku. Szukają Państwo części systemu, gdzie każda zmiana jest wolna i ryzykowna, gdzie te same błędy wciąż wracają, gdzie nowi programiści nie mogą bezpiecznie pracować i gdzie próbowali już Państwo tańszych poprawek, trafiając na ścianę. Gdy kilka z tych rzeczy jest prawdziwych naraz, ukierunkowane przepisanie tego jednego elementu jest słusznym wyborem.
| Sygnał | Prawdopodobnie tylko naprawa | Prawdopodobnie przebudowa |
|---|---|---|
| Objaw | Jedna wolna strona lub zapytanie | Każda zmiana w obszarze jest wolna i ryzykowna |
| Błędy | Sporadyczne, do naprawienia | Te same błędy wciąż wracają |
| Tanie poprawki | Jeszcze nie próbowane | Już wyczerpane, wciąż utknięcie |
| Zakres | Ograniczony do jednej funkcji | Rozlewa się na cały moduł |
| Słuszny ruch | Zmierzyć i połatać | Świadomie przebudować ten jeden element |
A gdy już przebudowują Państwo, przebudujcie element — nie produkt. Pełne przepisanie od zera to syreni śpiew skalowania, rzecz, która wydaje się czysta, a kończy się zatopieniem roku, gdy konkurenci wypuszczają. Wymieńcie ten jeden zepsuty komponent, za wyraźną granicą, podczas gdy reszta produktu dalej działa i zarabia. Chirurgicznie, nie heroicznie.

Uderzyli Państwo w ścianę i nie wiecie, czy to naprawa, czy przebudowa?
To decyzja, którą drogo jest pomylić, a tanio trafić. Zmierzymy, gdzie Państwa produkt naprawdę się napina, i uczciwie powiemy, czy to dwudniowa naprawa, czy coś głębszego — zanim ktokolwiek napisze linijkę nowego kodu.
Zobacz, jak podchodzimy do skalowania oprogramowaniaCzęste pytania
Jak rozpoznać, że mój SaaS zaraz uderzy w ścianę skalowania?
Czy powinienem przejść na mikroserwisy, by skalować?
Taniej jest optymalizować kod czy po prostu kupić większy serwer?
Kiedy pełne przepisanie jest naprawdę słuszną decyzją?
Ile powinienem zainwestować w skalowanie, zanim mam użytkowników?

Have a nice day to studio programistyczne, które pomaga małym i średnim firmom w cyfryzacji — automatyzacja, sztuczna inteligencja i oprogramowanie na zamówienie, które działa w codziennej pracy, a nie tylko na slajdach.