Kdy je správné shipnout rychle a kdy se vyplatí zpomalit?

Vojtěch Bobek, Zakladatel

Ve vývoji se často staví proti sobě dvě rady.

Jedna říká, že máme vydávat změny co nejrychleji. Dostat produkt mezi lidi, sbírat zpětnou vazbu a neztrácet týdny perfekcionismem nad něčím, co možná nikdo nebude používat.

Druhá říká, že máme věci dělat pořádně. Myslet na architekturu, testování, bezpečnost a technický dluh, protože rychlá řešení se nám později vrátí i s úroky.

Obě rady jsou správně. A obě mohou být zároveň velmi špatně.

Problém podle mě není rozhodnout se, jestli obecně preferujeme rychlost, nebo kvalitu. Potřebujeme poznat, ve kterých částech systému si rychlost můžeme dovolit a kde je chyba natolik drahá, že se vyplatí zpomalit už na začátku.

První verze landing page a migrace produkční databáze nejsou stejné rozhodnutí. Experimentální onboarding a platební proces nemají stejnou míru rizika. Stejně tak něco jiného znamená napsat za odpoledne interní nástroj pro tři lidi a navrhovat datový model produktu, na kterém může za dva roky stát celá firma.

Proto dnes při vývoji mnohem méně přemýšlím stylem „rychle vs. správně“ a mnohem víc řeším vratnost rozhodnutí, cenu chyby a množství nejistoty, které v danou chvíli máme.

Rychlost a kvalita nemusí být protiklady

Na první pohled je kompromis jednoduchý. Když věnujeme více času návrhu, testům a kontrole, vydání trvá déle. Když některé kroky přeskočíme, dostaneme změnu do produkce rychleji.

Krátkodobě to tak skutečně může být. Dlouhodobě už méně.

Pokud rychlost znamená velké změny, které se složitě testují, obtížně kontrolují a po nasazení se těžko vracejí zpět, každé další vydání začne být rizikovější. Tým potom paradoxně zpomalí právě proto, že se původně snažil pohybovat rychle.

Stejně tak ale nemusí být pomalejší tým kvalitnější. Může strávit týdny návrhem abstrakcí pro budoucí scénáře, které nikdy nevzniknou, nebo postavit perfektní infrastrukturu pro produkt, o který nakonec nebude zájem.

DORA dlouhodobě upozorňuje, že vysoká rychlost dodávání změn a stabilita nejsou pro dobře fungující týmy nutně protiklady. Jedním z mechanismů, který pomáhá obě vlastnosti kombinovat, jsou malé změny: lépe se jim rozumí, jednodušeji se testují a při problému se snáz vracejí.

To mi přijde jako mnohem zdravější pohled na rychlost.

Shipovat rychle nemusí znamenat stavět ledabyle. Může to znamenat dělat malé, bezpečné kroky a rychle se z nich učit.

Nejdřív bych řešil, jak snadno lze rozhodnutí změnit

Ne všechna technická rozhodnutí mají stejnou životnost.

Změnit text tlačítka stojí několik minut. Předělat barevnost rozhraní je nepříjemné, ale většinou neohrozí celý produkt. Když zjistíme, že experimentální funkci nikdo nepoužívá, můžeme ji často jednoduše odstranit.

Jiná rozhodnutí se mění výrazně hůř.

Datový model, veřejné API, autentizace, způsob oddělení zákaznických prostředí, billing, struktura oprávnění nebo způsob ukládání kritických zákaznických dat mohou postupně vytvořit desítky dalších závislostí. Jakmile na nich stojí produkční data a další části systému, jejich změna už nemusí být refaktor na odpoledne.

Proto mi dává smysl rozdělovat rozhodnutí podle jejich vratnosti.

U snadno vratných rozhodnutí můžeme být agresivnější. Nemusíme tři meetingy diskutovat nad detailem, který můžeme zítra změnit za hodinu.

U obtížně vratných rozhodnutí bych naopak chtěl mnohem více jistoty. Ne nutně dokonalost, ale vědomí, že rozumíme hlavním kompromisům a že si nevytváříme problém, jehož cena bude za několik měsíců násobně vyšší.

Prakticky to znamená, že rychlost by neměla být rozdělená rovnoměrně po celém systému. Někde chci experimentovat téměř bez tření. Jinde chci být konzervativní.

Cena chyby je často důležitější než cena implementace

Řekněme, že máme dvě změny a obě dokážeme implementovat za jeden den.

První upravuje doporučování článků na blogu. Když bude algoritmus chvíli fungovat špatně, několik lidí uvidí méně relevantní obsah.

Druhá mění logiku výpočtu částky, kterou zákazník skutečně zaplatí.

Z pohledu vývojové kapacity jsou obě změny podobně velké. Z pohledu rizika vůbec.

U první můžeme experimentovat, měřit a při problému změnu rychle vrátit. U druhé bych chtěl kvalitní testy, přesně definované krajní případy, dobrý monitoring a pravděpodobně i důkladnější kontrolu kódu.

Tohle je podle mě důležitější než obecné pravidlo „každý kód musí splňovat stejný standard“.

Standard kvality má být vysoký všude, ale množství kontroly by mělo odpovídat potenciálnímu dopadu chyby.

Jiný přístup potřebuje interní administrační rozhraní a jiný systém spravující osobní data milionu uživatelů. Jiný ověřovací prototyp a jiný produkt, ze kterého už firma generuje většinu příjmů.

Čím větší je potenciální rozsah škody, tím dražší je slepá honba za rychlostí.

Technický dluh není automaticky špatně

Pojem technický dluh se často používá tak, jako by každá neideální implementace byla selhání.

Já bych ho vnímal podobně jako skutečný dluh. Někdy může být racionální ho přijmout, pokud přesně víme proč.

Máme například příležitost spustit experiment během týdne. Čisté dlouhodobé řešení by trvalo měsíc, ale zatím vůbec nevíme, jestli daná funkce přežije další dva týdny. V takové situaci může být jednodušší implementace správné rozhodnutí.

Problém nastává, když přestaneme vnímat úrok.

Dočasná výjimka začne ovlivňovat další kód. Přidáme druhou a třetí. Každá nová změna je trochu pomalejší, protože musí obcházet staré rozhodnutí. Po několika měsících zjistíme, že něco, co nám původně ušetřilo dva dny, stojí tým několik hodin každý týden.

Martin Fowler tento princip popisuje pomocí design stamina hypothesis: zanedbání návrhu může krátkodobě zvýšit rychlost, ale postupně snižuje schopnost systému dál se efektivně měnit. Existuje tedy bod, za kterým už další „šetření času“ ve skutečnosti způsobuje pomalejší vývoj.

Za mě proto není problém technický dluh přijmout. Problém je přijmout ho nevědomě.

Pokud zvolíme dočasně horší řešení, měli bychom vědět, co tím získáváme, jaká je jeho budoucí cena a za jakých okolností ho chceme odstranit.

Minimální verze produktu nemusí znamenat špatně napsaný produkt

Občas se pod rychlou MVP schová úplně všechno.

Žádné testy. Žádné ošetření chyb. Přístupové údaje někde v kódu. Data strukturovaná podle toho, co bylo nejrychlejší napsat. Každá další funkce se přilepí na předchozí.

Argument je jednoduchý: „Stejně ještě nevíme, jestli to bude fungovat.“

Jenže MVP podle mě znamená minimalizovat rozsah produktu, ne nutně kvalitu jeho základů.

Pokud ověřujeme, jestli lidé chtějí nový způsob reportingu, nemusíme stavět dvacet typů reportů. Můžeme udělat jeden. To ale neznamená, že musíme ignorovat autentizaci nebo záměrně vytvořit kód, který se rozpadne při druhé iteraci.

Velký rozdíl je mezi „Postavíme méně“ a „Postavíme to špatně“.

První je často správná strategie v rané fázi produktu. Druhé musí mít mnohem lepší důvod.

Právě proto mám rád malé funkční řezy produktem. Místo obrovského systému, jehož polovinu zatím nepotřebujeme, vytvořit malou část, která funguje od začátku do konce. Reálný uživatel ji může použít, my můžeme sledovat výsledek a architektura nemusí předstírat, že známe příštích pět let roadmapy.

DORA práci v malých dávkách spojuje s rychlejší zpětnou vazbou a zároveň nižším rizikem změn. Důležité je přitom změny skutečně dostávat až do produkce, ne je pouze rozdělit na malé části a před vydáním z nich znovu vytvořit jeden obrovský balík.

Přehnané navrhování je také technický problém

Když se bavíme o technickém dluhu, většinou řešíme nedostatek struktury. Existuje ale i opačný extrém.

Projekt může být příliš dobře připravený na budoucnost, která nikdy nepřijde.

Můžeme od prvního dne vytvořit event-driven architekturu, několik mikroslužeb, abstrakční vrstvu nad každou závislostí, obecný systém oprávnění a infrastrukturu připravenou na milion uživatelů.

Technicky může být řešení působivé.

Pokud máme prvních třicet uživatelů a ještě nevíme, jestli produkt za půl roku vůbec bude existovat ve stejné podobě, může být zároveň velmi špatné.

Každá abstrakce má vlastní cenu. Člověk jí musí rozumět, testovat ji a při změně respektovat pravidla, která jsme si sami vytvořili. Komplexita není zdarma jen proto, že je architektonicky čistá.

Proto se u návrhu snažím odlišit dvě věci: komplexitu, kterou vyžaduje dnešní problém, a komplexitu, kterou přidáváme kvůli představované budoucnosti.

Ta druhá může být oprávněná, pokud je budoucí požadavek velmi pravděpodobný a pozdější změna by byla extrémně drahá. Jinak bych většinou preferoval systém, který je jednoduchý dnes a má jasnou cestu k rozšíření zítra.

To je podle mě lepší než stavět budoucí systém předem.

Rychlé vydávání změn potřebuje bezpečnostní síť

Velkou rychlost si můžeme dovolit hlavně tehdy, když je levné zjistit chybu a levné ji opravit.

Proto bych rychlé vydávání změn nikdy neodděloval od infrastruktury kolem něj.

Automatické testy snižují pravděpodobnost, že změna rozbije něco známého. CI umožní dostat zpětnou vazbu ještě před sloučením změny. Přepínače funkcí dovolí nasadit nový kód bez okamžitého zapnutí všem uživatelům. Monitoring ukáže, jestli se po vydání zvýšila chybovost nebo doba odezvy. Dobrý proces nasazení umožní změnu rychle vrátit.

Tohle všechno může na první pohled působit jako práce navíc, její hodnota se ale skládá s každým dalším vydáním.

Pokud trvá nasazení půl dne, je rizikové a návrat na předchozí verzi je ještě horší, tým bude přirozeně spojovat změny do velkých balíků. Ty budou rizikovější, takže se bude ještě více testovat ručně a vydávat ještě méně často.

Stejná smyčka může fungovat opačně. Když je změna malá, automaticky otestovaná, snadno nasaditelná a rychle vratná, můžeme si dovolit vydávat častěji. Menší změna se jednodušeji hledá při chybě a případný problém má menší rozsah.

Právě tady se podle mě rychlost a kvalita přestávají prát.

Kvalitní proces vývoje a nasazování umožňuje rychlost.

Kde bych schválně zpomalil

Existují části produktu, u kterých bych raději strávil více času předem, i když tím vydání posunu.

Typicky tam, kde pracujeme s penězi a billingem, kritickými zákaznickými daty, autentizací a autorizací, bezpečností, nenávratnými operacemi, migracemi dat, veřejnými API kontrakty nebo rozhodnutími, na která velmi rychle navážou desítky dalších částí systému.

Neznamená to, že je musíme navrhovat několik měsíců. Znamená to pouze, že přínos několika hodin nebo dnů navíc může být oproti ceně chyby zanedbatelný.

Stejně tak bych zpomalil ve chvíli, kdy začínáme vytvářet další obcházení problému, který už několikrát obcházíme. Tam často nejde o rychlou cestu vpřed, ale o signál, že základní model přestává fungovat.

Naopak rychlost bych preferoval tam, kde je největším rizikem učit se příliš pomalu. Nová produktová hypotéza, změna textů, experimentální onboarding, interní workflow, prototyp nové funkce nebo landing page pro nabídku, u které ještě nevíme, jestli bude existovat poptávka.

Pokud špatné rozhodnutí dokážeme rychle vrátit a jeho dopad je malý, dlouhá příprava může být větší riziko než technická nedokonalost. U těchto změn mě nezajímá, jestli jsme vytvořili definitivní řešení. Zajímá mě hlavně, jestli jsme se co nejrychleji dostali k informaci, která nám umožní udělat další rozhodnutí lépe.

Největší problém je, když „dočasné“ řešení nemá konec

Prakticky každý projekt obsahuje věci, o kterých někdo kdysi řekl: „Teď to uděláme takhle a později to předěláme.“

To samo o sobě není problém. Problém je, že ono „později“ nemá žádný konkrétní spouštěč.

Pokud dočasné řešení funguje a zákazník nevidí problém, refaktor bude v roadmapě vždycky soupeřit s novou funkcí, kterou lze prodat nebo ukázat. Je velmi jednoduché technickou investici odsouvat tak dlouho, až začne výrazně brzdit celý tým.

Proto se mi u vědomě přijatého dluhu líbí definovat podmínku, kdy se k němu vrátíme. Dokud máme méně než určitý objem dat, jednodušší řešení stačí. Pokud tuto část systému budeme upravovat potřetí, nejdřív ji refaktorujeme. Před otevřením API externím zákazníkům stabilizujeme jeho kontrakt.

Nejde o přesná pravidla pro každý projekt. Jde o to, aby „dočasně“ neznamenalo „navždy, dokud něco nezačne hořet“.

Správný poměr rychlosti a kvality se během života produktu mění

Stejná implementace může být správná v jednom období a špatná v jiném.

Produkt se stovkou uživatelů má jinou toleranci rizika než produkt se sto tisíci. Startup hledající product-market fit řeší něco jiného než firma, jejíž hlavní produkt generuje miliony a každá hodina výpadku má přímou cenu.

Proto je nebezpečné vytvořit si jednu vývojovou filozofii a aplikovat ji všude.

„Vždy shipujeme rychle.“

„Nikdy nebereme technický dluh.“

„Všechno musí mít test coverage X %.“

„Neoptimalizujeme, dokud nemusíme.“

Bez kontextu se z dobrých principů velmi rychle stanou špatná pravidla.

Čím zralejší produkt je, tím větší hodnotu podle mě získávají spolehlivost, přehled o stavu systému, konzistence a schopnost systému dlouhodobě se měnit. U úplného začátku je naopak často nejdražší věcí perfektně vyřešit problém, který se ukáže jako irelevantní.

Správný poměr rychlosti a investice do kvality se tedy musí vyvíjet společně s produktem.

Je tedy lepší shipovat rychle, nebo stavět správně?

Podle mě je ta otázka postavená špatně.

Cílem není být rychlý navzdory kvalitě ani kvalitní navzdory rychlosti. Cílem je minimalizovat celkovou cenu učení a změny.

U vratných rozhodnutí s nízkým rizikem to znamená malé experimenty a rychlou zpětnou vazbu. U kritických a těžko vratných rozhodnutí se vyplatí investovat více předem. A všude mezi tím potřebujeme vývojové prostředí, které nám dovolí dělat malé změny, rychle odhalit problémy a bezpečně je vrátit.

Nejhorší kombinace totiž není rychlý vývoj. Je to rychlý vývoj v systému, kde se každá chyba odhalí pozdě a opravuje draze.

Stejně tak není výhra perfektní architektura, pokud ji postavíme pro produkt, který zákazník nikdy nepotřeboval.

Proto bych se před důležitějším technickým rozhodnutím neptal jen „Jak rychle to dokážeme shipnout?“ ani „Jak to uděláme dokonale?“

Spíš:

„Jak drahé bude, když se v tomhle rozhodnutí spleteme — a jak snadno ho potom dokážeme změnit?“

Odpověď většinou docela dobře napoví, kde můžeme zrychlit a kde je naopak rozumnější na chvíli sundat nohu z plynu.

Zdroje

  • DORA — Software Delivery Performance Metrics
  • DORA — Working in Small Batches
  • Martin Fowler — Design Stamina Hypothesis
  • Martin Fowler — Technical Debt
  • Kent Beck et al. — Manifesto for Agile Software Development

Další články

Kolik stojí web v roce 2026? Co skutečně ovlivňuje jeho cenu?

Proč může jeden web stát desítky tisíc a jiný stovky? Vysvětlujeme, co cenu webu skutečně ovlivňuje a za co při tvorbě platíte.

Přečíst článek

WordPress, Shopify, Shoptet, nebo web na míru? Jak vybrat správné řešení

WordPress, Shopify, Shoptet, nebo vlastní vývoj? Porovnáváme, kdy jednotlivá řešení dávají smysl a kdy vám naopak začnou překážet.

Přečíst článek

Pojďme probrat Váš projekt

Máte konkrétní zadání, nápad nebo problém, který potřebujete vyřešit? Ozvěte se nám a společně se podíváme na to, jaký další krok dává smysl.

Ozvěte se nám

Kde nás najdete

  • Praha
    Příčná 1892/4
    110 00 Praha 1, Česká republika