Tech Choices

Jak a proč vybrat technologii — anti-patterny, tabulky, ADR.

Jedna z nejcennějších dovedností zkušeného backend engineera není psát kód, ale vybrat správný nástroj a umět obhájit proč — a stejně tak odmítnout nástroj, který je sice populární, ale na tenhle problém se nehodí. Většina architektonických katastrof totiž nevzniká špatně napsaným kódem, ale špatně zvolenou technologií. Tahle kapitola tě naučí o volbách přemýšlet.


Pár pojmů na úvod

  • Provozní náklad = kolik práce dá technologii dlouhodobě provozovat: naučit se ji, monitorovat, aktualizovat, opravovat, najít na ni lidi. Nová technologie nikdy není „zadarmo".
  • Throughput (průtok) = kolik toho nástroj zvládne za jednotku času (např. zpráv za sekundu).
  • Lock-in = uvíznutí u dodavatele nebo technologie, ze které se pak těžko přechází jinam.
  • Škála (scale) = jak velký provoz/objem dat musíš zvládnout.

Zlaté pravidlo: nudná technologie vyhrává

Choose Boring Technology („vybírej nudné technologie"). Každá nová technologie má skrytý provozní náklad. Máš jen omezený „rozpočet na inovaci" — utrať ho tam, kde je to tvoje konkurenční výhoda, ne na infrastruktuře, kterou má vyřešenou kdekdo.

  • Postgres + jeden monolit + jeden server uvezou překvapivě velký provoz. Většina firem Kafku, Kubernetes ani microservices nepotřebuje — nasadí je z módy a zaplatí to složitostí.
  • YAGNI (You Aren't Gonna Need It — „nebudeš to potřebovat") — neřeš škálu, kterou nemáš. Předčasná složitá architektura tě zabije dřív než úspěch.

Anti-patterny výběru (poznej je i u sebe)

  • 🚩 Resume-driven development — vybírám podle toho, co chci mít v životopise, ne podle toho, co řeší problém.
  • 🚩 Hype-driven — „všichni dělají microservices/Kafku/Mongo, tak my taky".
  • 🚩 Big-tech cargo cult — „Netflix to dělá takhle". Jenže ty nejsi Netflix a nemáš jeho škálu ani stovky lidí na provoz.
  • 🚩 Golden hammer („zlaté kladivo") — umím jeden nástroj, tak ho cpu na všechno.
  • 🚩 Shiny new thing — nezralá novinka bez komunity = ty jsi její testovací oddělení.

Rozhodovací postup (projdi ho pokaždé)

Než nasadíš jakoukoli technologii, zodpověz si:

  1. Jaký konkrétní problém řeší? Pojmenuj ho. Když to nedokážeš, nástroj nepotřebuješ.
  2. Co je nejjednodušší věc, která by fungovala? Začni od ní (soubor? tabulka v Postgresu? cron?).
  3. Mám ten problém opravdu teď? Nebo „možná za dva roky při 100× provozu"? → YAGNI.
  4. Jaký je provozní náklad? Kdo to bude provozovat, hlídat a opravovat ve 3 ráno?
  5. Je to zralé a má to komunitu? Stabilní verze? Dokumentace? Najdu na to lidi a odpovědi?
  6. Jak se to spojí s tím, co už mám? Každá další databáze = další záloha a další věc, co se rozbije.
  7. Jak z toho ven? Jak těžké bude to za dva roky vyměnit (lock-in)?

Dobrá obhajoba zní: „Mám problém X, nejjednodušší řešení je A, ale naráží na konkrétní limit L, proto sahám po B a beru na sebe náklad N." Špatná zní: „B je moderní / rychlé / cool."


Konkrétní volby

Jazyk / runtime

Nejde o „nejrychlejší", ale o vhodnost + ekosystém + tým.

  • Node / TypeScript — skvělý na I/O práci (API, realtime), sdílí jazyk s frontendem, obří ekosystém knihoven.
  • Go — jednoduchost a výkon, ideální na síťové služby a infra nástroje; snadné nasazení (jedna binárka).
  • Python — data, ML, skripty, rychlý vývoj; pomalejší běh.
  • Java / C# — velký enterprise, zralé a výkonné, ale upovídané.
  • Rust — maximální výkon a bezpečnost paměti tam, kde záleží na každé mikrosekundě; pomalejší vývoj.

Rozhoduj: Je problém spíš o čekání (I/O), nebo o počítání (CPU)? Co umí tým? Jaké knihovny potřebuju?

Pozn.: porovnání konkrétních možností (databáze, broker, API styl, architektura, hosting) najdeš v tabulkách níže — tady je jen princip, jak se rozhodnout. Záměrně to neopakuju dvakrát.

SQL vs NoSQL — a KTERÁ

Výchozí volba = Postgres (zvládne relace, JSON, fulltext… jeden nástroj na 90 % potřeb). Po jiné databázi sáhni jen s konkrétním limitem, který Postgres neuveze. Pravidlo: jedna databáze, dokud tě limit nedonutí přidat druhou — každá další je další záloha, monitoring a věc, co se může rozejít.

Message broker — Kafka vs RabbitMQ vs nic

Nejdřív se zeptej: potřebuju vůbec broker? Na pár asynchronních úloh stačí tabulka v Postgresu jako fronta nebo Redis; broker přidej, až to přeroste. 🚩 „Nasadíme Kafku" bez odpovědi na jaký průtok a proč ne tabulka v Postgresu = červená vlajka.

Monolit vs Microservices ⭐ (nejdražší rozhodnutí)

Začni monolitem. Skoro vždy — jednodušší vývoj, nasazení, debug i transakce, žádná síťová režie. Microservices řeší organizační, ne technický problém (víc týmů, co se nechtějí blokovat; části s různými nároky na škálu) a platíš za ně daň: distribuované transakce (saga!), výpadky sítě, eventual consistency, složitější provoz. Cesta: dobře rozčleněný monolit → vyřízni z něj službu, teprve až to reálně bolí.

Hosting / cloud

Začni jednoduše — jeden server nebo PaaS (Railway, Render, Fly, Coolify); vydrží to déle, než čekáš. Kubernetes ber, až máš mnoho služeb a tým, který ho uveze (pro malý projekt provozní peklo). Serverless na nepravidelný provoz (pozor na cold start a lock-in). A managed vs vlastní provoz: managed stojí víc peněz, ale šetří tvůj čas a noční pohotovosti.


📊 Rozhodovací tabulky (kus po kuse)

Rychlá reference. Sloupec „Sáhni po tom, když" je důležitější než výčet vlastností — rozhoduj se podle problému, ne podle počtu ✅.

Databáze — kterou jako hlavní

PostgresMySQLMongoDBRedisCassandra/DynamoElasticsearch
ModelRelační + JSONRelačníDokumentovýKlíč-hodnotaWide-columnVyhledávací index
Transakce✅ silné ACID✅ ACID⚠️ omezené⚠️ základní❌ (eventual)
JOINy
Škála zápisuSilnější stroj + shardingSilnější strojHorizontálníSilnější strojHorizontální ⭐Horizontální
Latencemsmsmszlomky ms ⭐msms
Sáhni po tom, kdyžDefault na 90 %Máte už MySQLHodně proměnlivé schéma, žádné JOINyCache, rate limit, frontyObří objem zápisů, OK s eventualFulltext, logy

Výchozí volba = Postgres. Ostatní přidávej až s konkrétním limitem, který Postgres neuveze.

Message broker

Postgres/Redis frontaRabbitMQKafkaSQS (cloud)
Jak na to mysletTabulka úkolůChytrá frontaTrvalý záznamSpravovaná fronta
PrůtokNízký–středníStřední–vysokýVelmi vysoký ⭐Vysoký
Přehrávání historie✅ ⭐
Víc nezávislých konzumentů⚠️✅ ⭐⚠️
Provozní náklad~nula ⭐StředníVysokýNula (managed)
Sáhni po tom, kdyžPár úloh, malý objemÚkoly, složité routováníStreaming, přehrávání, velký objemJsi v cloudu, nechceš nic provozovat

🚩 Kafka má smysl od vysokého průtoku / potřeby přehrávání / mnoha konzumentů. Na pár zpráv denně = tabulka v Postgresu.

API styl

RESTgRPCGraphQL
VýkonDobrýNejlepší ⭐Dobrý
Typovost⚠️✅ ⭐
Z prohlížeče napřímo⚠️ jen přes gRPC-Web/proxy
Cachování✅ snadné ⭐❌ těžké❌ těžké
Složitost serveruNízkáStředníVysoká
Sáhni po tom, kdyžDefault, veřejné APIMezi vlastními službami, nízká latenceMobil / proměnlivé potřeby klienta

Architektura

MonolitModular monolithMicroservices
Vývoj/debugSnadné ⭐SnadnéTěžké (distribuované)
Transakce✅ lokální ⭐✅ lokální❌ saga, eventual
Nezávislé škálování/deploye⚠️✅ ⭐
Provozní/síťová režieNízká ⭐NízkáVysoká
Sáhni po tom, kdyžSkoro vždy na startuRoste, chceš hranice modulůVíc týmů se blokuje, různé nároky na škálu

Cesta zleva doprava, až když to bolí. Ne naopak.

Hosting

1 server / VPSPaaS (Railway, Render, Coolify)ServerlessKubernetes
SetupRučníSnadný ⭐SnadnýSložitý
Provozní nákladStředníNízkýNízkýVysoký
Cena při malém provozuFixníNízká~nula ⭐Vysoká
Sáhni po tom, kdyžPlná kontrolaDefault pro malé/středníNepravidelný provozMnoho služeb + tým na k8s

🌳 Rychlý rozhodovací strom

Strom je start, ne dogma. Vždy ještě projdi rozhodovací postup výše a obhaj volbu konkrétním problémem.


Jak rozhodnutí zaznamenat (ADR)

Důležitá rozhodnutí si zapiš do krátkého dokumentu: kontext → zvažované možnosti → rozhodnutí → důsledky. Tomu se říká ADR (Architecture Decision Record). Za rok si nebudeš pamatovat proč, a nováček to nepřekope naslepo. Jeden .md soubor stačí:

# ADR-001: Postgres jako hlavní databáze
Kontext: Potřebujeme relační data + občas JSON, malý provoz.
Možnosti: Postgres / MongoDB / MySQL.
Rozhodnutí: Postgres — relace i JSON pokryje obojí a tým ho zná.
Důsledky: Při extrémním objemu zápisů budeme později řešit repliky/sharding.

Failure modes — nejčastější chyby ve výběru

  • Over-engineering — Kafka/Kubernetes/microservices na projekt, co uveze jeden Postgres. Nejčastější.
  • Zbytečně moc databází — pět úložišť, pětkrát víc provozní zátěže, nikdo neví, kde co je.
  • Hype lock-in — vsadíš na nezralou technologii, komunita vymře a držíš ji sám.
  • Under-engineering — opačný extrém: ignoruješ známý limit, který přijde za měsíc.

🛠️ Cvičení

  1. Obhaj, nebo zamítni. Junior navrhuje Kafku na appku se 100 zprávami denně. Napiš protiargument a co bys použil místo toho.
  2. Vyber databázi. Pro tři případy — relační data s občasným JSON, bleskově rychlá cache, fulltext nad logy — vyber úložiště a zdůvodni, proč ne (nebo proč ano) Postgres na všechno.
  3. Monolit, nebo microservices? Pro startup se čtyřmi vývojáři a jasným produktem rozhodni a vyjmenuj, co bys volbou microservices obětoval.
  4. Napiš ADR. Vyber reálné rozhodnutí (např. fronta: tabulka v Postgresu vs RabbitMQ) a sepiš ho: kontext → možnosti → rozhodnutí → důsledky.
  5. Poznej anti-pattern. U pěti výroků urči, jestli jde o resume-driven / hype-driven / golden hammer volbu, nebo o legitimní rozhodnutí.
Náčrt řešení — rozbal, až si cvičení zkusíš sám
  1. Obhaj, nebo zamítni — zamítni: 100 zpráv denně je zlomek QPS, na který je Kafka kanón na vrabce a navíc drahá na provoz. Použij tabulku v Postgresu jako frontu (nebo Redis). Pozor: brokera přidej, až máš konkrétní důvod — vysoký průtok, přehrávání historie nebo víc nezávislých konzumentů.
  2. Vyber databázi — relační data s občasným JSON → Postgres (umí obojí, default); bleskově rychlá cache → Redis (zlomky ms); fulltext nad logy → Elasticsearch. Pozor: Postgres na všechno nedáš jen proto, že je default — pro cache a fulltext naráží na konkrétní limit (latence, vyhledávací index), a to je legitimní důvod sáhnout po druhém úložišti.
  3. Monolit, nebo microservices — pro startup se čtyřmi vývojáři a jasným produktem zvol monolit: jednodušší vývoj, nasazení, debug i transakce. Microservices řeší organizační problém (víc týmů, co se blokují), který tu nemáš. Obětoval bys: lokální transakce (nastoupila by saga + eventual consistency), jednoduchý provoz a žádnou síťovou režii. Pozor: cesta k službám až „když to bolí", ne preventivně.
  4. Napiš ADR — sepiš čtyři části: kontext (jaký problém a v jakém objemu), možnosti (Postgres fronta vs RabbitMQ), rozhodnutí (např. Postgres fronta — malý objem, žádné nové úložiště) a důsledky (při růstu/složitém routování přejdeme na broker). Pozor: drž to krátké a uchovej proč, ne jen co — jeden .md stačí.
  5. Poznej anti-pattern — u každého výroku rozhodni podle motivace: „chci to v životopise" = resume-driven, „všichni to dělají / dělá to Netflix" = hype-driven či cargo cult, „umím jen tohle, tak to cpu všude" = golden hammer; pojmenovaný problém + trade-off = legitimní volba. Pozor: legitimitu nedělá technologie, ale jestli za ní stojí konkrétní problém a limit.

🧠 Otázky & odpovědi

Co znamená zásada choose boring technology a proč platí?

Každá nová technologie má skrytý provozní náklad (naučit se ji, provozovat, opravovat ve 3 ráno, najít lidi, aktualizovat). Máš jen omezený rozpočet na inovaci — utrať ho tam, kde je to tvoje konkurenční výhoda, ne na infrastruktuře, kterou má vyřešenou každý. Osvědčený nudný Postgres + monolit uvezou překvapivě velký provoz; exotika se zaplatí složitostí.

Kdy NEnasadit Kafku?

Když pro ni nemáš důvod: vysoký průtok, potřebu přehrávat historii, nebo víc nezávislých konzumentů téhož proudu. Na pár zpráv denně je to kanón na vrabce — a navíc náročný na provoz. Pro málo asynchronních úloh stačí tabulka v Postgresu jako fronta nebo Redis. Brokera přidej, až přerosteš jednodušší řešení.

Proč začít monolitem a kdy teprve microservices?

Monolit je jednodušší na vývoj, nasazení, debug i transakce a nemá síťovou režii — pro start skoro vždy správně. Microservices řeší hlavně organizační problém (víc týmů, které se nechtějí blokovat, různé nároky na škálu), ne technický, a platíš za ně distribuovanými transakcemi, eventual consistency a provozní složitostí. Vyřízni službu z monolitu, teprve až to reálně bolí.

Jaký je dobrý a špatný způsob, jak obhájit volbu technologie?

Dobrý: „mám problém X, nejjednodušší řešení je A, ale naráží na konkrétní limit L, proto sahám po B a beru na sebe náklad N." Špatný: „B je moderní / rychlé / cool / dělá to Netflix." Volba má vycházet z pojmenovaného problému a trade-offů, ne z módy, životopisu nebo napodobování velkých firem.

K čemu je ADR (Architecture Decision Record)?

Je to krátký zápis důležitého rozhodnutí: kontext → zvažované možnosti → rozhodnutí → důsledky. Za rok si nebudeš pamatovat proč jste to udělali takhle, a nováček to nepřekope naslepo. Jeden .md soubor stačí. Dělá rozhodnutí dohledatelným a brání tomu, aby se osvědčené volby měnily z neznalosti kontextu.