Het verbeteren van de werkstroom

In het begin van 2022 besloot ons Product Development team dat efficiënter wilde werken, omdat het moeilijker was geworden om releasedata te halen. Daarom deden we een stap terug om uit te zoeken wat er aan de hand was. We zochten naar manieren om dit te verbeteren.

Deze blog beschrijft hoe we de problemen identificeerden en welke stappen we ondernamen om sneller waarde te creëren met een hogere kwaliteit.

Gepubliceerd 18 oktober 2022

Het productontwikkelingsteam van Olympus Mobility is een multidisciplinair team met backendontwikkelaars, een webontwikkelaar, een ontwikkelaar van mobiele apps, een productontwerper, en een CTO en CEO die instaan voor het productmanagement.

Wij bouwen aan het Olympus Mobility-platform en werken ook samen met KBC Group om onze diensten te integreren in de KBC Mobile Banking-app.

Aan het begin van 2022 besloot het productontwikkelingsteam dat het sneller wilde kunnen leveren, omdat het moeilijker was geworden om de releasedata te respecteren. Wij wilden een stap terug zetten om uit te zoeken wat er aan de hand was en manieren te vinden om te verbeteren. Dit blogbericht beschrijft de stappen die wij hebben genomen om de problemen te identificeren en hoe wij ze hebben aangepakt, zodat wij eerder waarde konden leveren met een hogere kwaliteit.

1. Het werk visualiseren

Op werkitemniveau

Eerst zochten wij uit hoe wij nuttige gegevens over het uitgevoerde werk konden krijgen en vonden manieren om het werk van de voorbije maand te visualiseren in de hoop dat dit tot inzichten zou leiden.

Wij keken eerst op werkitemniveau en exporteerden gegevens uit JIRA. Een werkitem kan een verhaal of een bug zijn.

Wij exporteerden de doorlooptijd voor werkitems voor ons leveringsproces voor de periode tussen 1 oktober 2021 en 15 april 2022. De doorlooptijd is de tijd die een werkitem doorbrengt als werk in uitvoering binnen vooraf bepaalde procesgrenzen. Als procesgrenzen beschouwden we het moment waarop een ontwikkelaar een werkitem oppikt voor implementatie tot het klaar is om het in productie te zetten. Dit omvat de tijd om het werkitem te implementeren, een peerreview te houden en een QA-fase te doorlopen. Wij concentreerden ons op dat deel van het proces, omdat de medewerkers in het team zich gestrest voelden vanwege de werkdruk, het schakelen tussen verschillende contexten en het gebrek aan focus, en wij betrouwbare gegevens hadden voor dat deel.

De doorlooptijd die wij berekenden, omvatte niet het in productie zetten, omdat dat elke twee weken gebeurde en het niet werd bijgehouden in JIRA met een aparte werkstroomstatus. De doorlooptijd voor al ons featurewerk wordt hier weergegeven in een spreidingsdiagram van de doorlooptijden [1]:

In een spreidingsdiagram van de doorlooptijden staat elke stip voor een werkitem. De horizontale as van het diagram geeft aan wanneer het werkitem werd voltooid. De verticale as geeft aan hoelang het werkitem in uitvoering is gebleven binnen de door ons gekozen procesgrenzen. In dit diagram kozen we dagen als tijdseenheid.

Wat dit diagram ons laat zien, is dat 50% van de werkitems die werden voltooid tussen 1 oktober 2021 en 15 april 2022 binnen 3 dagen werd voltooid. 85% van alle werkitems werd binnen 11 dagen voltooid en 95% van de items werd binnen 32 dagen voltooid.

Hoe minder variabiliteit er is in de doorlooptijd, hoe voorspelbaarder je bent als team, en in ons geval vinden we dat het met 85% van de werkitems die binnen 11 dagen werden voltooid er helemaal niet slecht uitziet.

De lessen die wij uit deze oefening hebben geleerd:

  • Wij moeten opletten wanneer werkitems ‘in uitvoering’ de 8-10 dagen overschrijden, omdat ze, zodra ze die drempel hebben overschreden, blijkbaar vaak langdurig in uitvoering blijven. Wij moeten meer aandacht besteden aan de leeftijd van werkitems en actie ondernemen om lange doorlooptijden te voorkomen.
  • Wij kunnen ook naar de uitschieters kijken om te achterhalen waarom ze zo lang duurden en of ze iets gemeen hebben waar wij op moeten letten.
  • Over het algemeen zijn wij erg tevreden over de doorlooptijd van de afzonderlijke werkitems voor dit deel van ons productontwikkelingsproces en wij denken niet dat wij nu dieper moeten graven.

Op featureniveau

Vervolgens keken wij een niveau hoger naar het featureniveau. Met een feature bedoelen wij een grotere deliverable waarvoor veel werkitems moeten worden voltooid voordat er waarde wordt geleverd. Enkele voorbeelden van features zijn: onze mobiele app uitbreiden zodat gebruikers een carpoolservice kunnen gebruiken of een treinkaartje kunnen bestellen.

Het team had het gevoel dat het aan veel dingen tegelijk werkte en toen wij naar de gegevens keken, ontdekten we het volgende:

  • in oktober 2021 werkten wij parallel aan 5 features;
  • in november 2021 werkten wij parallel aan 4 features, maar 2 van de features waren nieuw. Voor 3 van de features waar wij in oktober aan werkten, werd het werk onderbroken;
  • in december 2021 werkten wij parallel aan 6 features, gelukkig waren daar geen nieuwe bij;
  • in januari 2022 werkten wij ook aan 5 features, geen daarvan was nieuw;
  • in februari 2022 werkten wij parallel aan 8 features, waarvan er 3 nieuw waren;
  • in maart 2022 werkten wij parallel aan 8 features;
  • in april 2022 werkten wij ook parallel aan 8 features.

Wij werkten parallel aan meer features dan wij medewerkers in het team hadden in dit tijdsbestek (7 medewerkers maakten deel uit van het productontwikkelingsteam).

Dus hoewel het team een geweldige prestatie leverde door afzonderlijke werkitems af te ronden, werkten wij parallel aan veel features, wat resulteerde in een lange doorlooptijd voor elk van de afzonderlijke features.

Mijn verwachting was dat wij een lage stroomefficiëntie zouden hebben voor de afzonderlijke features vanwege het vele schakelen tussen verschillende contexten. Stroomefficiëntie voor een feature is de verhouding tussen de totale actieve tijd waarin aan een feature is gewerkt en de doorlooptijd die nodig is om de feature te voltooien.

Bijvoorbeeld, als het 10 dagen duurt om een feature te voltooien, maar slechts 2 dagen actief werk vereist zijn, dan is de stroomefficiëntie 20%. Dat betekent dat het werk 8 dagen in een inactieve status is gebleven.

Stroomefficiëntie is vaak moeilijk te meten, omdat dat inhoudt dat we de actieve tijd van de inactieve tijd moeten kunnen onderscheiden. Als je workflow tussen elke status wachttijden heeft, bijvoorbeeld ‘ontwikkeling in uitvoering’ -> ‘wachten op beoordeling’ -> ‘beoordeling’, en de statuswijzigingen redelijk goed worden bijgehouden, dan kun je de stroomefficiëntie berekenen. Onze werkstroom heeft geen wachttijden, maar wij moeten de tijd bijhouden voor boekhoudkundige doeleinden. Dat betekent dat wij dagelijks bijhouden hoeveel tijd wij aan elke feature hebben besteed en dat stelt ons in staat de stroomefficiëntie vrij nauwkeurig te meten.

Dus op basis van deze werklogs / urenstaten waren wij in staat zowel de stroomefficiëntie voor elke feature te berekenen als te visualiseren hoe wij onze tijd als een team hebben besteed [2]:

De bovenstaande afbeelding toont een Gantt-grafiek die vaak verkeerd wordt gebruikt om een projectplan weer te geven. Verkeerd gebruikt, omdat Gantt-grafieken meestal worden gemaakt voordat het werk begint. Tijdens het productontwikkelingsproces leren wij echter nog steeds nieuwe dingen die van invloed zijn op het werk dat moet worden gedaan, dus het uitzetten van een gedetailleerd plan en het schatten van de benodigde tijd van tevoren is bijna nooit nauwkeurig. Het projectplan gaat ook meestal uit van 100% stroomefficiëntie, wat bijna nooit het geval is.

De Gantt-grafiek die ik hier toon, geeft weer hoe wij onze tijd als team daadwerkelijk hebben besteed op basis van de werklogs. Het lijkt helemaal niet op hoe een vooraf bepaald projectplan er meestal uitziet.

Elke lijn in de grafiek vertegenwoordigt een andere feature waaraan wij hebben gewerkt. Voor het doel van dit blogbericht zijn de feitelijke beschrijvingen van de features hernoemd naar de generieke waarden ‘Feature 1’, ‘Feature 2’,… Als een dag gekleurd is voor een feature, betekent dit dat ten minste één iemand in het team tijd heeft gelogd voor de feature. De grafiek laat heel goed zien hoe verspreid onze tijd werd besteed en hoe dat de doorlooptijd voor elk van de features verhoogt. Dit is te zien aan de vele hiaten en het vele schakelen tussen contexten.

De stroomefficiëntie voor deze features voor dit tijdsbestek is oplopend gesorteerd: 7%, 9%, 12%, 14%, 16%, 22%, 36%, 53%. Dit komt doordat er gemiddeld ergens 4 keer meer wordt gewacht dan dat er actief aan wordt gewerkt!

Daarbovenop is er een stroom van werk die niet zichtbaar is in de grafiek, namelijk operationele ondersteuning. Het team besteedde 25% van zijn tijd aan ongepland werk om het operationele team te ondersteunen, om vragen van klanten te beantwoorden of om bugs op te lossen.

Zoals je je kunt voorstellen, had het team het erg druk en hadden we een zeer hoog gebruik van de resources maar een lage stroomefficiëntie. Hierdoor duurde het langer dan zou moeten om waarde aan onze klanten te leveren. Bovendien was het gevoel van overweldigd te zijn hoog vanwege het voortdurende schakelen tussen contexten en het gevoel het voortdurend druk te hebben zonder tijd te hebben om te recupereren.

Enkele redenen waarom wij aan zoveel features tegelijk werkten:

  • Features werden aan het team opgelegd in plaats van door het team zelf gevraagd wanneer het klaar was voor nieuw werk. De reden waarom features aan het team werden opgelegd was dat er releasedata werden overeengekomen met partners terwijl het werk nog niet duidelijk was en zonder voldoende tijd te laten voor ongepland werk. Wanneer werd overeengekomen dat een feature over 6 maanden zou worden geleverd en 3 maanden later een nieuwe klant een contract wilde ondertekenen maar echt een uitbreiding van ons platform nodig had, kreeg die dezelfde prioriteit als de geplande feature en werd die aan het team opgelegd. Dit is volkomen begrijpelijk (wij houden van nieuwe klanten!), maar om het minder stressvol te maken voor ons kleine team hadden wij wat speling in de planning moeten laten om op een duurzame manier te kunnen omgaan met ongeplande verzoeken en de planning niet maanden van tevoren mogen vullen.
  • Features werden onderbroken omdat sommige partners doorlooptijden voor releases hebben met vooraf bepaalde data. Als een feature bijna maar nog niet volledig klaar was voor release op de vooraf bepaalde datum, werd deze pas beschikbaar bij de volgende release 3 maanden later. Dit betekende dat zelfs als er nog maar een week nodig was om de feature af te ronden, deze bijna 3 maanden inactief bleef totdat het releaseschema van de partner het toeliet om de feature weer op te pikken voor de laatste integratietests en de release. Deze vaste releaseschema’s betekenen dat wij het leveren van waarde aan onze gebruikers onnodig vertragen en leiden ook tot meer werk in uitvoering en secundaire behoeften (schakelen tussen contexten, 3 maanden later worden nieuwe medewerkers op het product gezet die context missen en meer begeleiding nodig hebben,…).

Het verzamelen van statistieken en het visualiseren van het werk hielp ons te beseffen dat er iets moest veranderen. Het was duidelijk dat er een grote kans was om sneller waarde te leveren met minder stress voor het team.

2. Stabiliseren

Het eerste wat we als team besloten was dat we eerst wilden afmaken waaraan we werkten en niets nieuws zouden starten, tenzij we een eerder overeengekomen releasedatum moesten halen.

In de daaropvolgende weken en maanden konden we daadwerkelijk het merendeel van de features ‘in uitvoering’ voltooien en deze beschikbaar maken voor onze gebruikers, wat zeer welkom was.

In een ideale wereld zouden we met het team aan zo weinig mogelijk features of onderwerpen werken en ons richten op het zo snel mogelijk leveren van waarde aan onze gebruikers met goede kwaliteit en leren van feedback. Zodra het team klaar is voor nieuw werk, beslissen we wat het volgende belangrijkste of invloedrijkste onderwerp is en herhalen we dit proces. Zo laat mogelijk beslissen over de volgende prioriteit betekent dat we de meeste context hebben om te beslissen wat het belangrijkst is op het moment dat we klaar zijn om nieuw werk aan te vatten.

Helaas kunnen wij ons niet altijd aan deze ideale manier van werken houden omdat wij met partners werken die lang van tevoren releasedata en tussentijdse mijlpalen willen vastleggen (bv. De integratietestfase), zodat wij niet altijd de vrijheid hebben om zo laat mogelijk te beslissen wat het volgende belangrijkste is om aan te werken. Wij moeten leven met deze beperkingen en wat wij in dit geval zullen proberen is:

  • eerdere doorlooptijden voor features in overweging nemen om tot een realistische releasedatum te komen;
  • voorrang geven aan werk met vooraf bepaalde releasedata, zodat we een grote kans hebben om aan externe beperkingen te voldoen zonder al te veel stress;
  • voorzichtig zijn bij nieuw werk dat aan het team wordt opgelegd. Overschakelen naar het vragen van werk zodra iets is voltooid als de standaard manier van werken.

Dit zou positieve resultaten moeten opleveren voor zowel ons team (leveren met kwaliteit en zonder veel stress) als onze partners (Olympus Mobility is betrouwbaar en respecteert de releasedata).

3. Testcase: Eenmalige pechverhelping van VAB

Kort nadat we eind april 2022 met onze bevindingen en acties kwamen die in de vorige twee hoofdstukken zijn beschreven, kwam er een nieuwe releasedatum in zicht die al eind 2021 was overeengekomen. We verbonden ons ertoe om het product ‘eenmalige pechverhelping’ (OOBA) van VAB te integreren in de KBC Mobile Banking-app.

OOBA is een product waarmee automobilisten hulp kunnen krijgen wanneer ze autopech hebben.

Tegen eind april 2022 was de ontdekkingsfase (of Fuzzy front end-fase) voor OOBA afgerond en er werd van ons verwacht dat wij klaar zouden zijn met de ontwikkeling op 16 juli 2022. Dat was de begindatum van de end-to-end integratietestfase. De integratietestfase werd gevolgd door pentests op 15 augustus, een pilootrelease op 31 augustus en tot slot een publieke release op 12 september 2022.

We besloten om een klein multidisciplinair team zich te laten concentreren op het bouwen van het product. We dachten dat dit de optie was met de beste kans om de levering van OOBA klaar te hebben tegen 16 juli.

Het team begon met zijn eerste werkitem op 12 mei en introduceerde ook enkele praktijken die ons hielpen om de releasedata te halen en die ik in de volgende paragrafen zal beschrijven.

We zorgden ervoor dat we sneller feedback kregen door gelijktijdige ontwikkeling te introduceren. Backend- en frontendontwikkelaars begonnen samen te werken om zo snel mogelijk een functionerende end-to-end slice klaar te krijgen. Dit omvatte het starten met API’s die voorbeeldinhoud teruggaven, die werden vervangen door de echte implementatie naarmate de backendontwikkeling vorderde.

Het implementeren van de end-to-end functionaliteit omvatte ook integratie met externe partijen (VAB en KBC) zodra we dat konden. We wachtten niet tot de geplande integratietestfase die maanden later was gepland. Dit alles met als doel om mogelijke integratieproblemen eerder op te sporen en in staat te zijn werkitems af te ronden en feedback niet uit te stellen.

Zodra er werk klaar was voor een demo lieten we het zien tijdens onze wekelijkse statusvergadering met alle belanghebbenden. Dit werd erg op prijs gesteld en gaf ons waardevolle feedback die we vaak al konden verwerken tegen de volgende vergadering.

Tijdens onze dagelijkse statusvergadering met het Olympus Mobility-team concentreerden we ons op het wegnemen van blokkades om te voorkomen dat werk verouderd raakt. We concentreerden ons op het afronden van wat was begonnen voordat we met iets nieuws begonnen.

Het vermogen om te focussen en de introductie van de eerder beschreven praktijken resulteerden in een doorlooptijd van 7 dagen voor 85% van de werkitems en 10 dagen voor 95% van de werkitems. Vergeleken met wat we lieten zien voor de periode van 1 oktober 2021 tot 15 april 2022, verbeterde de doorlooptijd en hebben we minder variatie, wat betekent dat we voorspelbaarder zijn. De stroomefficiëntie voor het OOBA-werk eindigde op 60%.

Midden mei 2022 schakelden we ook over van onze tweewekelijkse releases naar continue levering (CD voor Continuous Delivery) voor onze backend- en webontwikkelingen. Elke ontwikkelaar werd verantwoordelijk voor het in productie zetten van zijn/haar wijzigingen. De doorlooptijd voor OOBA hierboven omvat het in productie zetten van de wijzigingen voor werkitems. Met de overstap naar CD besparen we ongeveer een halve dag elke twee weken die we nodig hadden om alle wijzigingen in bulk in productie te zetten. Door CD te introduceren, leveren we sneller waarde aan gebruikers en dit heeft geen negatieve invloed op onze beschikbaarheid.

We hebben ons team georganiseerd voor een snelle stroom, maar we waren ook sterk afhankelijk van de ondersteuning van de partners met wie we integreerden, VAB en KBC. Dankzij hun snelle reactietijd en feedback bij het oplossen van integratieproblemen slaagden we erin om de uitdagende releasedata te halen.

We haalden de releasedata en het OOBA-product is sinds 12 september 2022 beschikbaar in de KBC Mobile Banking-app. De oplevering van OOBA werd absoluut als een succes beschouwd, zowel voor het productontwikkelingsteam als voor de belanghebbenden. We nemen de lessen uit de JIRA-gegevens en de proceswijzigingen mee bij het plannen en leveren van toekomstige productinitiatieven. We zullen blijven inspecteren en aanpassen om de snelheid en kwaliteit te verbeteren van de mobiliteitsdiensten die we aan onze gebruikers leveren.

Het overnemen van deze praktijken levert mogelijk niet dezelfde resultaten op in jouw productontwikkelingscontext, maar kan je wel inspiratie geven over hoe je de stroom kunt evalueren en indien nodig kunt verbeteren. Bedankt voor het lezen.

[1]: Het spreidingsdiagram van de doorlooptijden werd gemaakt met behulp van het jira-agile-metrics github-project. Het biedt gegevens die meer inzicht geven in vergelijking met wat je uit JIRA haalt zonder extra extensies of apps. Je krijgt bijvoorbeeld percentielgegevens over doorlooptijden, wat belangrijk is omdat doorlooptijdgegevens geen normale spreiding hebben en de gemiddelden die Jira biedt niet nuttig zijn. Het genereren van de gegevens is gemakkelijk, maar het opschonen van de gegevens kostte nogal wat tijd. We hadden bijvoorbeeld werkitems die werden gebruikt voor tijdsregistratie buiten het softwareontwikkelingsproces en die van ‘Todo’ naar ‘Done’ gingen zonder de eigenlijke werkstroom te doorlopen. Deze en andere tickets moesten worden gefilterd om nauwkeurigere resultaten te krijgen. Houd hier rekening mee om bruikbare statistieken te kunnen voorleggen.

[2]: De berekeningen van de stroomefficiëntie en de Gantt-grafiek zijn gegenereerd met behulp van het work-exposure github-project.

Auteur: Kristof Adriaenssens

Veel dank gaat uit naar Tom Stuart en Will Ellis voor het nalezen van het blogbericht en het geven van waardevolle feedback.

Als je de toekomst van mobiliteit vorm wilt geven, bekijk dan onze vacaturepagina.