Kies voor Saaie Technologie

Sinds mijn vertrek bij Etsy een jaar geleden, is mijn vermogen om me echt voor technologie aan te thekenen teruggekeerd. Mijn gedachten zijn inmiddels zo gekristalliseerd dat ik ze coherent op papier kan zetten. Wat volgt is een distillatie van de "Kellan-gestalt", die hopelijk slechts een lichte verschrikking bij hem zal opwekken.

Omarm Verveling

Stel dat elk bedrijf ongeveer drie 'innovatietokens' krijgt. Je kunt deze besteden hoe je wilt, maar de voorraad is voor lange tijd beperkt. Misschien krijg je er later een paar bij zodra je een bepaald niveau van stabiliteit en volwassenheid hebt bereikt, maar de algemene neiging is om de inhoud van je portemonnee te overschatten. Dit model is een benadering, maar ik denk dat het helpt.

Als je besluit je website in NodeJS te schrijven, heb je zojuist één van je innovatietokens uitgegeven. Als je kiest voor MongoDB, heb je een token uitgegeven. Kies je voor service discovery-technologie die pas een jaar of minder bestaat? Dan ben je weer een token kwijt. En als je besluit je eigen database te schrijven: help, dan heb je een groot probleem.

Al die keuzes kunnen verstandig zijn als je een JavaScript-consultancy bent, of een databasebedrijf. Maar dat ben je waarschijnlijk niet. Je werkt waarschijnlijk voor een bedrijf dat (althans officieel) de wereldhandel heroverweegt, betalingen op het web opnieuw uitvindt of een andere epische missie nastreeft. In die context is het besteden van je beperkte aandacht aan het innoveren van SSH een uitstekende manier om te falen, of in het beste geval: succes uit te stellen[^1].

Wat telt als "saai"? Dat is lastig. "Saai" moet niet worden verward met "slecht". Er bestaat technologie die zowel saai als slecht is[^2]; dat zou je niet moeten gebruiken. Maar er zijn veel technologische keuzes die saai én goed zijn, of in ieder geval goed genoeg. MySQL is saai. Postgres is saai. PHP is saai. Python is saai. Memcached is saai. Squid is saai. Cron is saai.

Het mooie aan "saaiheid" (in deze beperkte zin) is dat de mogelijkheden van deze tools goed begrepen zijn. Maar belangrijker nog: hun faalmodi zijn goed bekend. Iedereen die mij goed kent, weet dat ik met een overweldigend gevoel van onbehagen de geest van Don Rumsfeld moet oproepen, maar dat moet ik doen (om duidelijk te zijn: ik heb niets met deze man).

Bij het kiezen van technologie heb je zowel bekende onbekenden als onbekende onbekenden[^3].

  • Een bekende onbekende is iets als: we weten niet wat er gebeurt als deze database 100% CPU bereikt.
  • Een onbekende onbekende is iets als: "Jeetje, het is ons helemaal niet occurred dat het schrijven van statistieken GC-pauzes (garbage collection) zou veroorzaken."

Beide categorieën zijn meestal niet leeg, zelfs voor technologie die al decennia bestaat. Maar bij glimmende nieuwe technologie is de hoeveelheid onbekende onbekenden significant groter, en dat is cruciaal.

Optimaliseer Globaal

Ik vind een voorkeur voor saaie technologie absoluut een goed ding, maar het is niet de enige factor die meegewogen moet worden. Technologische keuzes gebeuren niet in isolatie. Ze hebben een reikwijdte die je hele team, organisatie en het systeem dat voortkomt uit de som van je keuzes raakt.

Het toevoegen van technologie aan je bedrijf brengt kosten met zich mee. Als abstracte stelling is dit duidelijk: als we al Ruby gebruiken, voelt het toevoegen van Python niet logisch, omdat de resulterende complexiteit zwaarder weegt dan de marginale winst van Python. Maar zodra mensen praten over Python versus Scala, of MySQL versus Redis, lijken ze alle beperkingen te vergeten en beginnen ze te roepen dat je "het beste gereedschap voor de klus" moet gebruiken.

Je functie is in essentie het vertalen van zakelijke problemen naar een oplossingsruimte die bestaat uit softwarekeuzes. Als softwarekeuzes echt geen "bagage" zouden hebben, zou je inderdaad een verzameling van lokaal-optimale tools kunnen kiezen voor je verschillende problemen.

In een wereld waar keuzes goedkoop zijn, kies je technologie door simpelweg het juiste gereedschap voor de klus te pakken. Maar in de realiteit bestaat die bagage wel. We noemen die bagage "operations" en, in mindere mate, "cognitieve overhead". Je moet het monitoren, unit-tests bedenken, basiskennis hebben om erin te kunnen sleutelen en een init-script maken. Dit loopt snel op.

Het probleem met het denken in termen van "het beste gereedschap voor de klus" is dat het een myope (bijziende) kijk heeft op de woorden "beste" en "klus". Je klus is om het bedrijf in stand te houden. En het "beste" gereedschap is degene die de "minst slechte" positie inneemt voor zoveel mogelijk van je problemen.

Het is bijna altijd zo dat de langetermijnkosten van het betrouwbaar draaiende houden van een systeem vele malen groter zijn dan de ongemakken die je ervaart tijdens het bouwen ervan. Volwassen en productieve developers begrijpen dit.

Kies Soms Nieuwe Technologie

Als je deze redenering tot het uiterste zou drijven (reductio ad absurdum), zou dat betekenen dat je Java kiest en vervolgens probeert een website te implementeren zonder iets anders te gebruiken. Dat zou krankzinnig zijn. Je hebt manieren nodig om je gereedschapskist uit te breiden.

Een belangrijke eerste stap is erkennen dat dit een proces en een gesprek is. Nieuwe technologie heeft uiteindelijk organisatiebrede effecten, dus het toevoegen ervan is een beslissing die zichtbaar moet zijn voor de hele organisatie. Afhankelijk van je organisatiestructuur kan dit gesprek geforceerd worden, of kunnen developers juist zonder overleg nieuwe databases en queues toevoegen. In elk geval moet er een cultuur komen waarin we hierover praten.

Een van de meest waardevolle oefeningen die ik aanbeveel, is jezelf afvragen hoe je het huidige probleem zou oplossen zonder iets nieuws toe te voegen. Ten eerste spoort deze vraag situaties op waarbij het "probleem" eigenlijk is dat iemand heel graag een bepaalde technologie wil gebruiken. Als dat het geval is, moet je het proces direct staken: "Ik heb net een webinar gezien over deze grafiekdatabase, we moeten die eens proberen."

Het is verbazingwekkend hoe ver een kleine set technologiekeuzes kan komen. Het antwoord op de vraag of iets zonder nieuwe tools kan, is in de praktijk bijna nooit "dat kan niet", maar meestal ergens op het spectrum van "nou, het zou kunnen, maar het zou te moeilijk zijn"[^4]. Als je denkt dat je je doelen niet kunt bereiken met wat je nu hebt, denk je waarschijnlijk niet creatief genoeg.

Het helpt om precies op te schrijven wat het is aan de huidige stack waardoor het oplossen van het probleem prohibitief duur of moeilijk is. Dit is gerelateerd aan de vorige oefening, maar subtiel anders.

Nieuwe technologische keuzes kunnen puur additief zijn (bijvoorbeeld: "we hebben nog geen caching, dus laten we Memcached toevoegen"). Maar ze kunnen ook overlappen met of zaken vervangen die je al gebruikt. In dat geval moet je duidelijke verwachtingen scheppen over de migratie van oude functionaliteit naar het nieuwe systeem. Het beleid zou doorgaans moeten zijn: "we verbinden ons aan migratie," inclusief een voorgestelde tijdlijn. De bedoeling hiervan is om de hoeveelheid 'puin' beheersbaar te houden en te voorkomen dat er te veel lokaal-optimale oplossingen ontstaan.

Dit proces is niet ontmoedigend en is geen grote last. Het gaat om een handvol vragen als huiswerk, gevolgd door een vergadering om erover te praten. Ik geloof dat als een nieuwe technologie (of een nieuwe service op je infrastructuur) ongeschonden door dit proces komt, het prima is om deze toe te voegen.

Lever Gewoon Op

Polyglotte programmering wordt verkocht met de belofte dat het developers effectiever maakt als ze volledige vrijheid hebben in hun toolkeuze. Dit is in het beste geval een naïeve definitie van problemen en in het slechtste geval motivated reasoning. De last van de dagelijkse operationele rompslomp die dit creëert, drukt je uiteindelijk tot de grond.

Een bewuste keuze voor technologie geeft engineering-geesten juist echte vrijheid: de vrijheid om na te denken over grotere vragen. Technologie omwille van de technologie is snake oil.

Etsy leed hier in de beginjaren behoorlijk onder. We namen een groep Python-programmeurs aan en besloten dat we iets voor hen moesten verzinnen om in Python te doen. Het enige wat ons te binnen schoot, was het creëren van een zinloze tussenlaag die jaren aan inspanning kostte om weer weg te snijden. Ondertussen was de latency van de zoekfunctie in het 90ste percentiel ongeveer twee minuten. Etsy is niet failliet gegaan, maar het duurde meerdere jaren voordat er überhaupt iets werd opgeleverd. Hierdoor duurde het langer om succesvol te worden dan nodig was.

***

[^1]: Dit kan het succes vertragen. [^2]: We refereren vaak informeel aan de intersectie van "saai" en "slecht" als "enterprise software", hoewel die terminologie misschien onnauwkeurig is. [^3]: Hiermee verwees Rumsfeld, bewust of onbewust, naar de Socratische paradox. Socrates was overigens in veel opzichten een bedachtzamer individu dan Rumsfeld dat was. [^4]: Een goed voorbeeld hiervan zijn de activiteitsfeeds van Etsy. Toen we deze feature bouwden, probeerden we bijna alles te consolideren op PHP, MySQL, Memcached en Gearman (een PHP job server). Het was veel ingewikkelder om de feature op die stack te implementeren dan met iets als Redis. Maar het was absoluut mogelijk. Het resultaat was dat onze aandacht daarna jarenlang naar andere zaken uitging. In die tijd schaalde de activiteitsfeed 20x op terwijl niemand er naar keek; alles bleef werken omdat we een gedeeld platform gebruikten. Dit is het langetermijnvoordeel van terughoudendheid in technologiekeuzes. Dit is geen absolutistische positie: terwijl feeds in Memcached praktisch waren, was het implementeren van full-text search met faceting in rauw PHP dat niet. Daarom gebruikte Etsy Solr.