Gevangen in de technologenfabriek
De eerste keer dat ik betaald kreeg om Clojure te gebruiken, was slechts twee jaar nadat de taal was uitgebracht. Het spreekt voor zich dat dit was bij een startup in een vroeg stadium.
Het idee achter Runa was dat we dynamische prijsbepaling zouden verzorgen voor kleinere online retailers, waarbij we gerichte kortingen boden op basis van het individuele gedrag van shoppers. In de praktijk boden we een vaste korting aan iedereen die hun winkelwagentje verliet. Door een klein percentage van de klanten als controlegroep te behandelen, konden we ons effect op de verkoop van de retailer berekenen en een percentage van de winst claimen. Ons grootste probleem was het overtuigen van retailers om ons hun prijzen te laten beheren, nauw gevolgd door het overtuigen van hen dat de wiskunde achter onze berekende "lift" correct was.
We praatten onszelf aan dat er altijd een groot contract op het punt van sluiten stond, wat ons verkeer permanent met een factor tien zou verhogen. We gebruikten HBase als onze primaire datastore, omdat het was ontworpen om te schalen, net als wij.[^1] In de toekomst zouden we een losjes gefedereerde Amazon aandrijven, bestaande uit onafhankelijke online retailers, samengebonden door onze software. Als we het zouden bouwen, zouden ze wel komen.
Maar dat gebeurde niet. Het enige dat ons overeind hield, was een maatwerkproduct dat we hadden gebouwd voor eBay, omdat onze CEO een connectie had met een executive daar. Later, nadat ik was vertrokken, verhuisde diezelfde executive naar Staples en overtuigde hen om de startup volledig over te nemen. Niets van wat we hadden gebouwd was nuttig voor Staples; het was slechts bewijs van ons vermogen om te "innoveren". Het daaruit voortvloeiende "skunk works"-team is sindsdien ontbonden.
De overgang naar Factual
Mijn volgende baan was bij Factual, een meer gevestigde startup die hun product had gebouwd met Java en embedded Javascript, en die begonnen was met het adopteren van Clojure. Hun product was een index van alle plaatsen ter wereld, gegenereerd door honderden verschillende heuristieken toe te passen op webcrawl-data. Elk item had een canoniek ID en diverse eigenschappen zoals naam, adres en openingstijden. Interessanter was dat het ook de equivalente ID's had van verschillende platforms zoals Yelp en Foursquare, en we boden een API aan die een onvolledige (of zelfs gedeeltelijk incorrecte) set eigenschappen kon koppelen aan de overeenkomstige entiteit in onze index.
Ons product kon duizenden uiteenlopende datasets aan elkaar knopen, zolang ze maar een geografische component hadden; ik beschreef het graag als een "foreign key voor de wereld". Helaas is er niet veel geld te verdienen aan ontologieën. Tegen de tijd dat ik was begonnen, was de dataset al gebruikt als basis voor Facebook Places en als onderdeel van het toen nieuwe kaartaanbod van Apple. Dit waren grote contracten, maar er zijn maar een beperkt aantal grote techbedrijven ter wereld, en nog minder met een geografische component in hun data. Ongeacht hoeveel we probeerden het verschil aan te vullen met onze kleinere klanten, hadden we geen pad naar een waardering van een miljard dollar.
We begonnen diensten aan te bieden die werden aangedreven door onze data. Intern werd dit gepresenteerd als minder een pivot en meer als een demonstratie van de intrinsieke waarde van onze data; zodra mensen zagen wat we met onze data konden doen, zouden ze vast zelf ook ideeën krijgen. Onze eerste klanten waren adtech-bedrijven, die hoopten op betere geografische targeting voor mobiele advertenties. We namen verkopers en marketing executives aan met een achtergrond in digitale advertising, en toen de verkoop begon te groeien, namen we er meer aan. Zelfs terwijl ik services bouwde om miljarden dagelijkse ad-impressies te verwerken en bijna-databases op maat maakte om on-premise services te leveren voor onze adtech-partners, vertelde ik mezelf dat dit allemaal incidenteel was; onze business was data, niet advertenties.
Ik had het natuurlijk mis. De advertentie-kant van het bedrijf was waar alle groei plaatsvond, en onze productrichting was alles wat hen hielp om deals te sluiten. Maar ik was niet de enige die traag was in het erkennen van dit feit. In mijn exitgesprek met de CEO, vlak nadat ik mijn ontslag had ingediend, vertelde ik hem dat hij directer tegen iedereen moest zijn over het feit dat de focus van Factual permanent was verschoven. Hij vertelde me wat ikzelf net was gestopt met geloven: advertenties waren een tijdelijke afleiding, en we zouden voor uzun terugkeren naar de onderliggende data. In de jaren die volgden werd Factual echter steeds meer gefocust op locatiegebaseerde advertising, totdat het uiteindelijk fuseerde met Foursquare.
De dynamiek van startup-groei
Wanneer een startup durfkapitaal (venture funding) aantrekt, wordt groei het enige doel; het bedrijf zal ofwel een waardering van een miljard dollar bereiken, of sterven in de poging. Met die groei gaan steeds grotere technische uitdagingen gepaard. Sommige hiervan zijn duidelijk: meer gebruikers vereisen niet alleen meer machines, maar een complexere infrastructuur.[^2] Andere zijn minder duidelijk: naarmate de gebruikersbasis groeit, wordt elk individu steeds verder geabstraheerd in de businesslogica van onze software. Om de eerste uitdaging aan te pakken, moeten we technische expertise hebben. Om de tweede aan te pakken, moeten we een diepgaand begrip hebben van ons businessdomein.
Dit betekent dat zolang een startup blijft groeien, zijn engineers hun kennis en expertise kunnen (en moeten) blijven verbeteren. Maar de meeste startups falen. Sommige van die mislukkingen komen doordat het bedrijf niet kon meekomen met de eigen groei, maar dat zijn de uitzonderingen. De algemene, saaie reden voor falen is dat de startup nauwelijks groeide.
Confronteerd met stagnatie kan een engineeringorganisatie twee reacties hebben: ze kunnen proberen te helpen het bedrijf opnieuw uit te vinden, of ze kunnen doorgaan met het voorbereiden op de groei die onvermijdelijk moet komen. Bij Runa kozen we voor het laatste.
In eerste instantie adopteerde de engineeringleiding veelbelovende, slecht begrepen technologieën (Clojure! HBase!) die hen later de nodige hefboomwerking zouden geven. Maar zodra ze live gingen en de stagnatie inzette, werd die voorbereiding een noodzaak voor constante gereedheid. Eventuele vroege technische fouten, hoe spijtig ook, waren inmiddels ingebakken. Proberen deze te herzien of iets beters te bouwen, zou ons alleen maar kwetsbaar maken wanneer de groei uiteindelijk zou komen.
Ik trad bij Runa in slechts enkele maanden voordat de engineeringorganisatie deze defensieve houding aannam. Ik was te onervaren en te afgeleid[^3] om dit in twijfel te trekken. Elke dag speelden we Jenga: we probeerden de bestaande codebase bij elke nieuwe commit zo min mogelijk te verstoren. Later, toen ik besefte dat ik niet trots was op enig werk dat ik tot dan toe had gedaan, begon ik energiek te lobbyen voor het herbouwen van cruciale delen van het systeem.
Na een paar maanden werd me verteld dat ik dit moest laten vallen of drie weken severance pay (ontslagvergoeding) kon nemen. Ik koos voor de vergoeding.
Natuurlijk zou er niets zijn veranderd, zelfs als ik mijn zin had gekregen. We negeerden allemaal zorgvuldig het werkelijke probleem: ons businessmodel werkte simpelweg niet. Zowel ons product als ons prijsmodel vereisten onrechtvaardig hoge niveaus van vertrouwen van onze potentiële klanten, maar niemand van ons zag dat als een probleem dat wij moesten oplossen. Wij stonden stroomafwaarts van het businessmodel; onze taak was simpelweg wachten en ons voorbereiden op het uiteindelijke succes ervan.
De daling in adtech
Ik ging bij Factual omdat ik de probleemruimte fascinerend vond, maar tegen de tijd dat ik daar kwam, was het grootste deel al opgelost. Ongeveer zes maanden later begon de leiding te erkennen dat ons businessmodel, hoewel succesvol, ons niet naar een waardering van een miljard dollar zou brengen. Zo begon mijn afdaling in de adtech.
Ik wilde bewijzen dat ik mijn les had geleerd; als het huidige businessmodel niet werkte, zou ik helpen een nieuw model te bouwen. Ik bouwde services om de ruwe data te consumeren en on-premise servers om het verwerkte resultaat aan onze klanten te leveren. Ik woonde sales-meetings bij, schreef design-docs en analyseerde nauwgezet packet-dumps om aan partners te bewijzen dat latency-spikes elders in hun systeem optraden.
Uiteindelijk leerde ik dat ik niet erg veel van de advertentie-industrie hield. Wanneer een merk een digitale advertentiecampagne wilde voeren, gingen ze naar een bureau, dat verantwoordelijk was voor het zo effectief mogelijk besteden van het budget. Het bureau ging vervolgens naar een demand-side platform (DSP), dat verantwoordelijk was voor het doen van real-time biedingen op individuele ad-impressies op een exchange. Om die beslissingen te onderbouwen, ging de DSP naar een bedrijf als Factual, dat de huidige en eerdere locaties van een telefoon kon distilleren tot binaire kenmerken die relevant waren voor de campagne.
Cruciaal is dat wanneer je niet online verkoopt, het bijna onmogelijk is om de effectiviteit van een digitale advertentiecampagne te meten.[^4] Dit betekent dat het bureau bijna alles kon zeggen, zolang het maar hielp om de deal te sluiten. De DSP op zijn beurt verkocht wat zij dachten dat bureaus zou helpen om hun deals te sluiten. En aan het einde van deze keten stond Factual, die verkocht wat wij dachten dat de verkopers zou lokken, die op hun beurt de verkopers lokten, die weer de merken lokten.
Ik dacht dat ik productgericht was geworden, klaar om elk probleem op te lossen dat het bedrijf zou helpen slagen. In werkelijkheid besteedde ik alleen aandacht aan de technische problemen. Zodra die grotendeels waren opgelost, werd het moeilijker om mijn ambivalentie over wat het product daadwerkelijk deed te negeren. Uiteindelijk vertrok ik.
De technoloog versus de product engineer
Ik heb twee lessen geleerd uit deze periode. De eerste was persoonlijk: ik ben in essentie een technoloog. Ik houd van generaliseren, van abstraheren. Hoewel ik geloof dat het cruciaal is om de context rondom je software te begrijpen, ben ik het gelukkigst wanneer die context de software van anderen is.
De tweede les was breder en minder duidelijk:[^5] onze industrie is ontworpen om mensen zoals ik te koesteren.
Dit was verrassend, omdat het zo duidelijk tegen ons eigen belang in lijkt te gaan. In bijna elk geval falen bedrijven omdat ze het verkeerde product bouwen. Tenzij je klanten zelf engineers zijn, ben ik de verkeerde persoon om daarbij te helpen. Je wilt iemand die zich comfortabel voelt aan de periferie van je systeem, die wil leren over het concurrentielandschap, die met klanten wil praten. Je wilt een product engineer.
Maar overweeg onze standaard interviewvragen: datastructuren, recursie en computationele complexiteit. Het voelt altijd een beetje vreemd wanneer ik iemand hoor beweren dat deze zaken niet reflecteren wat de "echte" dagelijkse softwaretaken zijn; ik schrijf constant recursieve functies. Maar dat is een gevolg van de abstractie: wat een simpele geneste lookup op een specifiek datatype zou kunnen zijn, wordt recursie wanneer je probeert te generaliseren over een set mogelijke datatypes.
Hetzelfde geldt voor het argument dat het verschil tussen bijvoorbeeld $\text{O}(\log N)$ en $\text{O}(N)$ niet belangrijk is, omdat $N$ in de praktijk vaak klein genoeg is. Dat mag waar zijn voor sommige domeinen, misschien zelfs voor de meeste, maar als je een algemeen hulpmiddel bouwt, moet je je richten op de pathologische gevallen.
Natuurlijk zullen anderen beweren dat dit materiaal uit het eerste jaar Informatica de essentie is van wat we doen. Dit was zeker de houding toen ik bij Google werkte;[^6] aangezien hun bestaande medewerkers alles in het werk stelden om het schrijven van Javascript te vermijden, besloten ze dat iedereen met frontend-ervaring aan een lagere technische standaard zou worden getoetst. Deze nieuwe medewerkers werden breed gezien als tweederangs; mensen die er alleen mochten zijn omdat ze bereid waren het werk te doen dat niemand anders wilde.
Maar als we product engineers willen aannemen, welke vragen moeten we dan in plaats daarvan stellen? Het is onpraktisch, gezien de enorme omvang van onze industrie, om alleen kandidaten te overwegen met ervaring in exact onze productruimte. Evenzo is het onrealistisch om te verwachten dat wij expertise hebben in de eerdere productruimtes van een kandidaat. We missen een gemeenschappelijke woordenschat, een gemeenschappelijk begrip van de nuances die goede ontwerpkeuzes scheiden van middelmatige.
En dus blijven we zoeken naar onze sleutels onder de lantaarnpaal; ze kunnen overal liggen, maar hier is het licht. Als we geluk hebben, zullen de technologen die we aannemen ook alle andere vaardigheden bezitten die nodig zijn om humane, nuttige software te maken.
Dit betekent dat zelfs als je geen technoloog bent, je moet leren om dat te veinzen.[^7] En dit brengt ons terug naar het begin, toen het duidelijk was dat mijn eerste Clojure-baan, slechts twee jaar na de release van de taal, bij een startup in een vroeg stadium zou zijn.
De cyclus van nieuwe technologieën
De meeste nieuwe technologieën volgen, mits ze worden geadopteerd, een bekend pad: eerst komen de hobbyisten, en daarna de bedrijven die deze hobbyisten aannemen. Deze tweede stap is het makkelijkst wanneer het bedrijf weinig tot geen proces heeft rondom het adopteren van nieuwe technologie; met andere woorden, een startup in een vroeg stadium. Het standaardverhaal achter dit fenomeen is dat bepaalde technologieën simpelweg krachtiger zijn, maar dat alleen startups durven aan te nemen uit de niche-pool van talent die weet hoe ze deze moeten hanteren.
Maar nieuwe technologieën[^8] hebben geen "kracht"; daarvoor zouden ze een gemeenschap, documentatie en een bloeiend ecosysteem van aanvullende technologie nodig hebben. Wat ze wél hebben is potentieel, wat resoneert met het potentieel binnen de startup en de early adopter; wellicht kunnen ze over tijd samen groeien.
Zoals velen hebben opgemerkt, is dit geen rationele strategie voor het bouwen van een bedrijf. Het is echter een fenomenale manier om nieuwe technologen op te leiden. Ongeacht Chesterton is de snelste manier om te leren waarom een hek bestaat, het neerhalen ervan om te zien wat er gebeurt.
Vanuit dit perspectief lijkt het niet zo irrationaal; de meeste startups falen voordat ze een schaal bereiken die existentiële technische risico's met zich meebrengt. Het enige gegarandeerde voordeel dat ze hun engineers kunnen bieden, is de vrijheid om hun eigen uitdagingen te verzinnen en te leren door iteratief falen.[^9] Als de startup faalt, is er geen schade aangericht. Als de startup tractie krijgt, kunnen de engineers hun nieuwverworven wijsheid toepassen.
Dit betekent dat startups nieuwe technologieën niet adopteren ondanks hun onrijpheid, maar vanwege die onrijpheid. Dit drijft een constante churn van nieuwheid en veroudering aan, wat het belang van de vaardigheden van de technoloog vergroot, wat startups weer aanzet tot het adopteren van nieuwe technologieën.
Dit vliegwiel draait al lange tijd en zal niet stoppen simpelweg omdat ik erop wijs dat we nieuwheid verwarren met technologische vooruitgang. Hopelijk kunnen we het vertragen, want ik geloof dat het werkelijke schade aanricht.
Door abstractie te introduceren in elk probleem dat we oplossen, distantiëren we onszelf van hoe ons werk uiteindelijk wordt gebruikt. We vertellen onszelf dat we in de business zitten van het maken van scherpe messen; als we ze veiliger zouden maken, zouden ze nutteloos zijn voor alles behalve het besmeren van boter. We zweven boven de effecten van wat we hebben gecreëerd en behandelen deze als onvermijdelijke gevolgen van vooruitgang.
Het is waar dat we onze waarden niet kunnen coderen in general-purpose software,[^10] maar we zijn niet simpelweg geïsoleerde technologen, en onze werelden worden niet begrensd door de interfaces die we ontsluiten. We delen een collectieve verantwoordelijkheid voor wat we creëren en zijn in staat om collectief naar die verantwoordelijkheid te handelen.
Maar wat betekent een geloof in collectieve verantwoordelijkheid in praktische termen? Welke acties houdt dit in? Eerlijk gezegd weet ik het niet. Alles wat ik weet is dat we niet eeuwig onder de lantaarnpaal kunnen blijven staan. Op een gegeven moment zullen we moeten kijken naar wat er daar in het donker is.
***
[^1]: In een wending die niemand zal verbazen, kon de manier waarop we het gebruikten nooit schalen. Om geordende scans over keys te ondersteunen, partitioneert HBase op aaneengesloten bereiken in de keyspace. Omdat we wilden scannen over de events van een bepaalde dag, begonnen al onze keys met een timestamp. Dit betekende dat elke write voor een bepaalde tijdsperiode zich richtte op een enkele shard, wat HBase ertoe dreef om constant zijn shards te herpartitioneren in een vruchteloze poging om de load gelijkmatig te verdelen. Onze HBase-cluster stond altijd op het punt om om te vallen. [^2]: Zelfs in het uiterst zeldzame geval dat je kernservices horizontaal kunnen schalen, zal het verwerken van de toenemende volumes data die ze genereren complexiteit introduceren op andere plekken in je systeem. [^3]: Mijn eerste jaar bij Runa viel samen met een periode van grotendeels ongerelateerde depressie, en de "één voet voor de andere"-benadering van softwareontwikkeling spiegelde perfect hoe ik bijna alles in mijn leven benaderde. [^4]: De enige mogelijke uitzondering hierop is Google. Als je een Android-telefoon hebt, kan Google je bezoek aan een Walmart-winkel koppelen aan een advertentie voor Walmart die ze je een aantal dagen eerder hebben getoond. Als je Google Pay gebruikt, kunnen ze zelfs je aankopen koppelen. Ze kunnen misschien geen causaal verband bewijzen, maar het is nog steeds lichtjaren vooruit op wat iedereen anders kan bieden. [^5]: Het is moeilijk om te redeneren over structurele krachten in tech, en vooral in startups, vanwege de heersende mythe dat we allemaal protagonisten zijn binnen de narratieve boog van het bedrijf. Als iets mislukte, was dat alleen omdat we niet hard genoeg werkten of geen beter idee hadden. Zelfs nu, jaren later, brengt het denken aan deze periode in mijn carrière een vleugje schuldgevoel met zich mee; had ik de afloop van het verhaal niet kunnen veranderen? [^6]: Dit was terug in 2010, maar ik zou verbaasd zijn als er wezenlijk iets is veranderd. [^7]: Ik ken een paar manieren om deze beproeving over te slaan, maar geen enkele heeft een universele aantrekkingskracht. Als iemand bij een startup in een vroeg stadium voor je instaat, slaan ze vaak direct door naar het controleren of je een "culture fit" bent. Dit werkt echter alleen voor een kandidaat met een sterk netwerk, die bij een kleine startup wil werken en die in de betreffende cultuur past. Evenzo kun je simpelweg je eigen bedrijf oprichten, maar als oprichter bevind je je primair op de interface tussen business en investeerder; de interface tussen product en gebruiker staat altijd lager op de lijst. [^8]: En de niche-technologieën die door startups worden geadopteerd zijn, bijna zonder uitzondering, nieuw. De Lisp-evangelisatie van Graham leidde niet tot een wijdverspreide adoptie van Common Lisp, maar tot de adoptie van Clojure, een gloednieuwe Lisp die nog vol potentieel zat. [^9]: Gezien onze huidige situatie kan het adviseren van junior engineers om alleen "saaie" technologieën te gebruiken, worden gepresenteerd als de oudere generaties engineers die de ladder omhoog trekken. Zij mochten leren door falen, waarom mag de nieuwe generatie dat niet? [^10]: Ik smeek iedereen die denkt dat een softwarelicentie kan bepalen wanneer iets voor een slecht doel wordt gebruikt of niet, om één boek over ethiek te lezen.
Gevangen in de technologenfabriek
De eerste keer dat ik betaald kreeg om Clojure te gebruiken, was slechts twee jaar nadat de taal was uitgebracht. Het spreekt voor zich dat dit was bij een startup in een vroeg stadium.
Het idee achter Runa was dat we dynamische prijsbepaling zouden verzorgen voor kleinere online retailers, waarbij we gerichte kortingen boden op basis van het individuele gedrag van shoppers. In de praktijk boden we een vaste korting aan iedereen die hun winkelwagentje verliet. Door een klein percentage van de klanten als controlegroep te behandelen, konden we ons effect op de verkoop van de retailer berekenen en een percentage van de winst claimen. Ons grootste probleem was het overtuigen van retailers om ons hun prijzen te laten beheren, nauw gevolgd door het overtuigen van hen dat de wiskunde achter onze berekende "lift" correct was.
We praatten onszelf aan dat er altijd een groot contract op het punt van sluiten stond, wat ons verkeer permanent met een factor tien zou verhogen. We gebruikten HBase als onze primaire datastore, omdat het was ontworpen om te schalen, net als wij.[^1] In de toekomst zouden we een losjes gefedereerde Amazon aandrijven, bestaande uit onafhankelijke online retailers, samengebonden door onze software. Als we het zouden bouwen, zouden ze wel komen.
Maar dat gebeurde niet. Het enige dat ons overeind hield, was een maatwerkproduct dat we hadden gebouwd voor eBay, omdat onze CEO een connectie had met een executive daar. Later, nadat ik was vertrokken, verhuisde diezelfde executive naar Staples en overtuigde hen om de startup volledig over te nemen. Niets van wat we hadden gebouwd was nuttig voor Staples; het was slechts bewijs van ons vermogen om te "innoveren". Het daaruit voortvloeiende "skunk works"-team is sindsdien ontbonden.
De overgang naar Factual
Mijn volgende baan was bij Factual, een meer gevestigde startup die hun product had gebouwd met Java en embedded Javascript, en die begonnen was met het adopteren van Clojure. Hun product was een index van alle plaatsen ter wereld, gegenereerd door honderden verschillende heuristieken toe te passen op webcrawl-data. Elk item had een canoniek ID en diverse eigenschappen zoals naam, adres en openingstijden. Interessanter was dat het ook de equivalente ID's had van verschillende platforms zoals Yelp en Foursquare, en we boden een API aan die een onvolledige (of zelfs gedeeltelijk incorrecte) set eigenschappen kon koppelen aan de overeenkomstige entiteit in onze index.
Ons product kon duizenden uiteenlopende datasets aan elkaar knopen, zolang ze maar een geografische component hadden; ik beschreef het graag als een "foreign key voor de wereld". Helaas is er niet veel geld te verdienen aan ontologieën. Tegen de tijd dat ik was begonnen, was de dataset al gebruikt als basis voor Facebook Places en als onderdeel van het toen nieuwe kaartaanbod van Apple. Dit waren grote contracten, maar er zijn maar een beperkt aantal grote techbedrijven ter wereld, en nog minder met een geografische component in hun data. Ongeacht hoeveel we probeerden het verschil aan te vullen met onze kleinere klanten, hadden we geen pad naar een waardering van een miljard dollar.
We begonnen diensten aan te bieden die werden aangedreven door onze data. Intern werd dit gepresenteerd als minder een pivot en meer als een demonstratie van de intrinsieke waarde van onze data; zodra mensen zagen wat we met onze data konden doen, zouden ze vast zelf ook ideeën krijgen. Onze eerste klanten waren adtech-bedrijven, die hoopten op betere geografische targeting voor mobiele advertenties. We namen verkopers en marketing executives aan met een achtergrond in digitale advertising, en toen de verkoop begon te groeien, namen we er meer aan. Zelfs terwijl ik services bouwde om miljarden dagelijkse ad-impressies te verwerken en bijna-databases op maat maakte om on-premise services te leveren voor onze adtech-partners, vertelde ik mezelf dat dit allemaal incidenteel was; onze business was data, niet advertenties.
Ik had het natuurlijk mis. De advertentie-kant van het bedrijf was waar alle groei plaatsvond, en onze productrichting was alles wat hen hielp om deals te sluiten. Maar ik was niet de enige die traag was in het erkennen van dit feit. In mijn exitgesprek met de CEO, vlak nadat ik mijn ontslag had ingediend, vertelde ik hem dat hij directer tegen iedereen moest zijn over het feit dat de focus van Factual permanent was verschoven. Hij vertelde me wat ikzelf net was gestopt met geloven: advertenties waren een tijdelijke afleiding, en we zouden voor uzun terugkeren naar de onderliggende data. In de jaren die volgden werd Factual echter steeds meer gefocust op locatiegebaseerde advertising, totdat het uiteindelijk fuseerde met Foursquare.
De dynamiek van startup-groei
Wanneer een startup durfkapitaal (venture funding) aantrekt, wordt groei het enige doel; het bedrijf zal ofwel een waardering van een miljard dollar bereiken, of sterven in de poging. Met die groei gaan steeds grotere technische uitdagingen gepaard. Sommige hiervan zijn duidelijk: meer gebruikers vereisen niet alleen meer machines, maar een complexere infrastructuur.[^2] Andere zijn minder duidelijk: naarmate de gebruikersbasis groeit, wordt elk individu steeds verder geabstraheerd in de businesslogica van onze software. Om de eerste uitdaging aan te pakken, moeten we technische expertise hebben. Om de tweede aan te pakken, moeten we een diepgaand begrip hebben van ons businessdomein.
Dit betekent dat zolang een startup blijft groeien, zijn engineers hun kennis en expertise kunnen (en moeten) blijven verbeteren. Maar de meeste startups falen. Sommige van die mislukkingen komen doordat het bedrijf niet kon meekomen met de eigen groei, maar dat zijn de uitzonderingen. De algemene, saaie reden voor falen is dat de startup nauwelijks groeide.
Confronteerd met stagnatie kan een engineeringorganisatie twee reacties hebben: ze kunnen proberen te helpen het bedrijf opnieuw uit te vinden, of ze kunnen doorgaan met het voorbereiden op de groei die onvermijdelijk moet komen. Bij Runa kozen we voor het laatste.
In eerste instantie adopteerde de engineeringleiding veelbelovende, slecht begrepen technologieën (Clojure! HBase!) die hen later de nodige hefboomwerking zouden geven. Maar zodra ze live gingen en de stagnatie inzette, werd die voorbereiding een noodzaak voor constante gereedheid. Eventuele vroege technische fouten, hoe spijtig ook, waren inmiddels ingebakken. Proberen deze te herzien of iets beters te bouwen, zou ons alleen maar kwetsbaar maken wanneer de groei uiteindelijk zou komen.
Ik trad bij Runa in slechts enkele maanden voordat de engineeringorganisatie deze defensieve houding aannam. Ik was te onervaren en te afgeleid[^3] om dit in twijfel te trekken. Elke dag speelden we Jenga: we probeerden de bestaande codebase bij elke nieuwe commit zo min mogelijk te verstoren. Later, toen ik besefte dat ik niet trots was op enig werk dat ik tot dan toe had gedaan, begon ik energiek te lobbyen voor het herbouwen van cruciale delen van het systeem.
Na een paar maanden werd me verteld dat ik dit moest laten vallen of drie weken severance pay (ontslagvergoeding) kon nemen. Ik koos voor de vergoeding.
Natuurlijk zou er niets zijn veranderd, zelfs als ik mijn zin had gekregen. We negeerden allemaal zorgvuldig het werkelijke probleem: ons businessmodel werkte simpelweg niet. Zowel ons product als ons prijsmodel vereisten onrechtvaardig hoge niveaus van vertrouwen van onze potentiële klanten, maar niemand van ons zag dat als een probleem dat wij moesten oplossen. Wij stonden stroomafwaarts van het businessmodel; onze taak was simpelweg wachten en ons voorbereiden op het uiteindelijke succes ervan.
De daling in adtech
Ik ging bij Factual omdat ik de probleemruimte fascinerend vond, maar tegen de tijd dat ik daar kwam, was het grootste deel al opgelost. Ongeveer zes maanden later begon de leiding te erkennen dat ons businessmodel, hoewel succesvol, ons niet naar een waardering van een miljard dollar zou brengen. Zo begon mijn afdaling in de adtech.
Ik wilde bewijzen dat ik mijn les had geleerd; als het huidige businessmodel niet werkte, zou ik helpen een nieuw model te bouwen. Ik bouwde services om de ruwe data te consumeren en on-premise servers om het verwerkte resultaat aan onze klanten te leveren. Ik woonde sales-meetings bij, schreef design-docs en analyseerde nauwgezet packet-dumps om aan partners te bewijzen dat latency-spikes elders in hun systeem optraden.
Uiteindelijk leerde ik dat ik niet erg veel van de advertentie-industrie hield. Wanneer een merk een digitale advertentiecampagne wilde voeren, gingen ze naar een bureau, dat verantwoordelijk was voor het zo effectief mogelijk besteden van het budget. Het bureau ging vervolgens naar een demand-side platform (DSP), dat verantwoordelijk was voor het doen van real-time biedingen op individuele ad-impressies op een exchange. Om die beslissingen te onderbouwen, ging de DSP naar een bedrijf als Factual, dat de huidige en eerdere locaties van een telefoon kon distilleren tot binaire kenmerken die relevant waren voor de campagne.
Cruciaal is dat wanneer je niet online verkoopt, het bijna onmogelijk is om de effectiviteit van een digitale advertentiecampagne te meten.[^4] Dit betekent dat het bureau bijna alles kon zeggen, zolang het maar hielp om de deal te sluiten. De DSP op zijn beurt verkocht wat zij dachten dat bureaus zou helpen om hun deals te sluiten. En aan het einde van deze keten stond Factual, die verkocht wat wij dachten dat de verkopers zou lokken, die op hun beurt de verkopers lokten, die weer de merken lokten.
Ik dacht dat ik productgericht was geworden, klaar om elk probleem op te lossen dat het bedrijf zou helpen slagen. In werkelijkheid besteedde ik alleen aandacht aan de technische problemen. Zodra die grotendeels waren opgelost, werd het moeilijker om mijn ambivalentie over wat het product daadwerkelijk deed te negeren. Uiteindelijk vertrok ik.
De technoloog versus de product engineer
Ik heb twee lessen geleerd uit deze periode. De eerste was persoonlijk: ik ben in essentie een technoloog. Ik houd van generaliseren, van abstraheren. Hoewel ik geloof dat het cruciaal is om de context rondom je software te begrijpen, ben ik het gelukkigst wanneer die context de software van anderen is.
De tweede les was breder en minder duidelijk:[^5] onze industrie is ontworpen om mensen zoals ik te koesteren.
Dit was verrassend, omdat het zo duidelijk tegen ons eigen belang in lijkt te gaan. In bijna elk geval falen bedrijven omdat ze het verkeerde product bouwen. Tenzij je klanten zelf engineers zijn, ben ik de verkeerde persoon om daarbij te helpen. Je wilt iemand die zich comfortabel voelt aan de periferie van je systeem, die wil leren over het concurrentielandschap, die met klanten wil praten. Je wilt een product engineer.
Maar overweeg onze standaard interviewvragen: datastructuren, recursie en computationele complexiteit. Het voelt altijd een beetje vreemd wanneer ik iemand hoor beweren dat deze zaken niet reflecteren wat de "echte" dagelijkse softwaretaken zijn; ik schrijf constant recursieve functies. Maar dat is een gevolg van de abstractie: wat een simpele geneste lookup op een specifiek datatype zou kunnen zijn, wordt recursie wanneer je probeert te generaliseren over een set mogelijke datatypes.
Hetzelfde geldt voor het argument dat het verschil tussen bijvoorbeeld $\text{O}(\log N)$ en $\text{O}(N)$ niet belangrijk is, omdat $N$ in de praktijk vaak klein genoeg is. Dat mag waar zijn voor sommige domeinen, misschien zelfs voor de meeste, maar als je een algemeen hulpmiddel bouwt, moet je je richten op de pathologische gevallen.
Natuurlijk zullen anderen beweren dat dit materiaal uit het eerste jaar Informatica de essentie is van wat we doen. Dit was zeker de houding toen ik bij Google werkte;[^6] aangezien hun bestaande medewerkers alles in het werk stelden om het schrijven van Javascript te vermijden, besloten ze dat iedereen met frontend-ervaring aan een lagere technische standaard zou worden getoetst. Deze nieuwe medewerkers werden breed gezien als tweederangs; mensen die er alleen mochten zijn omdat ze bereid waren het werk te doen dat niemand anders wilde.
Maar als we product engineers willen aannemen, welke vragen moeten we dan in plaats daarvan stellen? Het is onpraktisch, gezien de enorme omvang van onze industrie, om alleen kandidaten te overwegen met ervaring in exact onze productruimte. Evenzo is het onrealistisch om te verwachten dat wij expertise hebben in de eerdere productruimtes van een kandidaat. We missen een gemeenschappelijke woordenschat, een gemeenschappelijk begrip van de nuances die goede ontwerpkeuzes scheiden van middelmatige.
En dus blijven we zoeken naar onze sleutels onder de lantaarnpaal; ze kunnen overal liggen, maar hier is het licht. Als we geluk hebben, zullen de technologen die we aannemen ook alle andere vaardigheden bezitten die nodig zijn om humane, nuttige software te maken.
Dit betekent dat zelfs als je geen technoloog bent, je moet leren om dat te veinzen.[^7] En dit brengt ons terug naar het begin, toen het duidelijk was dat mijn eerste Clojure-baan, slechts twee jaar na de release van de taal, bij een startup in een vroeg stadium zou zijn.
De cyclus van nieuwe technologieën
De meeste nieuwe technologieën volgen, mits ze worden geadopteerd, een bekend pad: eerst komen de hobbyisten, en daarna de bedrijven die deze hobbyisten aannemen. Deze tweede stap is het makkelijkst wanneer het bedrijf weinig tot geen proces heeft rondom het adopteren van nieuwe technologie; met andere woorden, een startup in een vroeg stadium. Het standaardverhaal achter dit fenomeen is dat bepaalde technologieën simpelweg krachtiger zijn, maar dat alleen startups durven aan te nemen uit de niche-pool van talent die weet hoe ze deze moeten hanteren.
Maar nieuwe technologieën[^8] hebben geen "kracht"; daarvoor zouden ze een gemeenschap, documentatie en een bloeiend ecosysteem van aanvullende technologie nodig hebben. Wat ze wél hebben is potentieel, wat resoneert met het potentieel binnen de startup en de early adopter; wellicht kunnen ze over tijd samen groeien.
Zoals velen hebben opgemerkt, is dit geen rationele strategie voor het bouwen van een bedrijf. Het is echter een fenomenale manier om nieuwe technologen op te leiden. Ongeacht Chesterton is de snelste manier om te leren waarom een hek bestaat, het neerhalen ervan om te zien wat er gebeurt.
Vanuit dit perspectief lijkt het niet zo irrationaal; de meeste startups falen voordat ze een schaal bereiken die existentiële technische risico's met zich meebrengt. Het enige gegarandeerde voordeel dat ze hun engineers kunnen bieden, is de vrijheid om hun eigen uitdagingen te verzinnen en te leren door iteratief falen.[^9] Als de startup faalt, is er geen schade aangericht. Als de startup tractie krijgt, kunnen de engineers hun nieuwverworven wijsheid toepassen.
Dit betekent dat startups nieuwe technologieën niet adopteren ondanks hun onrijpheid, maar vanwege die onrijpheid. Dit drijft een constante churn van nieuwheid en veroudering aan, wat het belang van de vaardigheden van de technoloog vergroot, wat startups weer aanzet tot het adopteren van nieuwe technologieën.
Dit vliegwiel draait al lange tijd en zal niet stoppen simpelweg omdat ik erop wijs dat we nieuwheid verwarren met technologische vooruitgang. Hopelijk kunnen we het vertragen, want ik geloof dat het werkelijke schade aanricht.
Door abstractie te introduceren in elk probleem dat we oplossen, distantiëren we onszelf van hoe ons werk uiteindelijk wordt gebruikt. We vertellen onszelf dat we in de business zitten van het maken van scherpe messen; als we ze veiliger zouden maken, zouden ze nutteloos zijn voor alles behalve het besmeren van boter. We zweven boven de effecten van wat we hebben gecreëerd en behandelen deze als onvermijdelijke gevolgen van vooruitgang.
Het is waar dat we onze waarden niet kunnen coderen in general-purpose software,[^10] maar we zijn niet simpelweg geïsoleerde technologen, en onze werelden worden niet begrensd door de interfaces die we ontsluiten. We delen een collectieve verantwoordelijkheid voor wat we creëren en zijn in staat om collectief naar die verantwoordelijkheid te handelen.
Maar wat betekent een geloof in collectieve verantwoordelijkheid in praktische termen? Welke acties houdt dit in? Eerlijk gezegd weet ik het niet. Alles wat ik weet is dat we niet eeuwig onder de lantaarnpaal kunnen blijven staan. Op een gegeven moment zullen we moeten kijken naar wat er daar in het donker is.
***
[^1]: In een wending die niemand zal verbazen, kon de manier waarop we het gebruikten nooit schalen. Om geordende scans over keys te ondersteunen, partitioneert HBase op aaneengesloten bereiken in de keyspace. Omdat we wilden scannen over de events van een bepaalde dag, begonnen al onze keys met een timestamp. Dit betekende dat elke write voor een bepaalde tijdsperiode zich richtte op een enkele shard, wat HBase ertoe dreef om constant zijn shards te herpartitioneren in een vruchteloze poging om de load gelijkmatig te verdelen. Onze HBase-cluster stond altijd op het punt om om te vallen. [^2]: Zelfs in het uiterst zeldzame geval dat je kernservices horizontaal kunnen schalen, zal het verwerken van de toenemende volumes data die ze genereren complexiteit introduceren op andere plekken in je systeem. [^3]: Mijn eerste jaar bij Runa viel samen met een periode van grotendeels ongerelateerde depressie, en de "één voet voor de andere"-benadering van softwareontwikkeling spiegelde perfect hoe ik bijna alles in mijn leven benaderde. [^4]: De enige mogelijke uitzondering hierop is Google. Als je een Android-telefoon hebt, kan Google je bezoek aan een Walmart-winkel koppelen aan een advertentie voor Walmart die ze je een aantal dagen eerder hebben getoond. Als je Google Pay gebruikt, kunnen ze zelfs je aankopen koppelen. Ze kunnen misschien geen causaal verband bewijzen, maar het is nog steeds lichtjaren vooruit op wat iedereen anders kan bieden. [^5]: Het is moeilijk om te redeneren over structurele krachten in tech, en vooral in startups, vanwege de heersende mythe dat we allemaal protagonisten zijn binnen de narratieve boog van het bedrijf. Als iets mislukte, was dat alleen omdat we niet hard genoeg werkten of geen beter idee hadden. Zelfs nu, jaren later, brengt het denken aan deze periode in mijn carrière een vleugje schuldgevoel met zich mee; had ik de afloop van het verhaal niet kunnen veranderen? [^6]: Dit was terug in 2010, maar ik zou verbaasd zijn als er wezenlijk iets is veranderd. [^7]: Ik ken een paar manieren om deze beproeving over te slaan, maar geen enkele heeft een universele aantrekkingskracht. Als iemand bij een startup in een vroeg stadium voor je instaat, slaan ze vaak direct door naar het controleren of je een "culture fit" bent. Dit werkt echter alleen voor een kandidaat met een sterk netwerk, die bij een kleine startup wil werken en die in de betreffende cultuur past. Evenzo kun je simpelweg je eigen bedrijf oprichten, maar als oprichter bevind je je primair op de interface tussen business en investeerder; de interface tussen product en gebruiker staat altijd lager op de lijst. [^8]: En de niche-technologieën die door startups worden geadopteerd zijn, bijna zonder uitzondering, nieuw. De Lisp-evangelisatie van Graham leidde niet tot een wijdverspreide adoptie van Common Lisp, maar tot de adoptie van Clojure, een gloednieuwe Lisp die nog vol potentieel zat. [^9]: Gezien onze huidige situatie kan het adviseren van junior engineers om alleen "saaie" technologieën te gebruiken, worden gepresenteerd als de oudere generaties engineers die de ladder omhoog trekken. Zij mochten leren door falen, waarom mag de nieuwe generatie dat niet? [^10]: Ik smeek iedereen die denkt dat een softwarelicentie kan bepalen wanneer iets voor een slecht doel wordt gebruikt of niet, om één boek over ethiek te lezen.