2026-05-13
Van 4–6 weken naar ongeveer één werkdag
Bij een bekend modebedrijf ontwikkelden analisten van team C dashboardlogica in notebooks, waarna DE haar in PySpark herschreef voor Airflow. Na het herontwerp kostten de meeste nieuwe dashboards ongeveer één werkdag en stond dagelijkse data klaar vóór de business begon.
Probleem: nieuwe levering was traag en bestaande dashboards verversten laat
Pijnpunt 1: iedere wijziging werd twee keer gebouwd, maar geen team kon een incident alleen sluiten
Het ticket leek routinewerk:
“Sommige dashboards laten verkeerde cijfers zien. Kun je dat oplossen?”
De zichtbare fout zat in de rapportage. Verder stroomopwaarts lag een cross-department ontwikkelproces dat op dubbele implementatie draaide.
Bij dit modebedrijf maakte DA geen deel uit van het DE-team. Analisten werkten binnen specifieke business-teams, zoals team C. Wanneer team C een requirement indiende, ontwikkelde zijn DA de bedrijfslogica in een notebook. Die fase nam in de planning meestal één sprint in beslag, hoewel pure nieuwbouwtijd niet apart werd gemeten van notebook-operations en onderhoud. Daarna ging de notebook naar DE. Engineering bouwde de logica opnieuw in PySpark, voegde haar toe aan de door Airflow beheerste ETL en gebruikte daar nog één of twee sprints voor.
Business-requirement van team C
→ DA-notebook van team C: ontwikkel- en onderhoudsfase, gepland ~1 sprint
→ handmatige overdracht tussen afdelingen
→ DE PySpark-engineeringbestand: runtimeversie, 1–2 sprints
→ door Airflow beheerste ETL
→ dashboardDezelfde bedrijfsregel bestond zo als ontwikkelversie en runtimeversie. Een nieuw dashboard ging door de backlogs van twee teams en had daardoor meestal een totale doorlooptijd van vier tot zes weken.
De volledige overdracht gold voor iedere wijziging. Een nieuw dashboard ging erdoorheen, net als debugging, een kleine filterwijziging of een bugfix. DA paste de notebook aan, lichtte de wijziging toe aan DE en wachtte tot DE het PySpark-engineeringbestand aanpaste. Bij afwijkende cijfers vergeleken de teams de notebook, de PySpark-versie, de brondata en de dashboardquery. Overleg werd een vast onderdeel van debugging.
Bij productie-incidenten werd ook het eigenaarschap onduidelijk. DA begreep de bedrijfslogica, maar kon de door DE herschreven PySpark-runtimecode niet lezen en de productieversie niet rechtstreeks herstellen. DE kon de PySpark-code aanpassen, maar had DA nodig om de bedrijfsregels uit te leggen, het verwachte resultaat te bevestigen en opnieuw een overdracht te doen. Beide standpunten waren logisch: DE beheerde de runtimecode en DA de zakelijke betekenis ervan. Het systeem had de kennis en toegang voor één probleem over twee teams verdeeld, waardoor geen van beide diagnose, wijziging en validatie zelfstandig van begin tot eind kon uitvoeren.
Het proces werd te langzaam voor de business. De analisten van team C gingen hun notebooks uiteindelijk met cron plannen en stuurden de resultaten rechtstreeks naar BI. Deze shadow pipeline verkortte de wachttijd en plaatste productie buiten de ETL die DE met Airflow bestuurde. Tests, lineage, alerts, monitoring en gedeelde operations bleven op het formele platform, terwijl de business data uit een andere route gebruikte.
Pijnpunt 2: business-users begonnen de dag zonder actuele data
Voordat ik betrokken raakte, verversten de dagelijkse dashboards ook laat. Het team kon niet betrouwbaar garanderen dat business-users bij aanvang van hun dag de nieuwste data zagen. Vooral maandagochtenden waren kwetsbaar: de eerste analyse na het weekend kon al beginnen terwijl dashboards nog wachtten op upstream-data of een notebookrun.
Oorzaak: ontwikkel- en runtimeversies lagen aan weerszijden van een afdelingsmuur
Twee structurele lagen versterkten elkaar. De notebook was de ontwikkelversie van team C; het PySpark-engineeringbestand was de runtimeversie van DE. Er bestond geen uitvoerbare interface die ze synchroniseerde. Tickets, meetings en menselijke uitleg droegen wijzigingen over de afdelingsgrens.
1. Ontwikkel- en runtimeversies evolueerden afzonderlijk
DA implementeerde de requirement in een notebook. DE onderhield de PySpark- versie op basis van die notebook en de overdrachtsnotities. Een wijziging in filters, joins, tijdvensters of randgevallen werkte de andere kant niet automatisch bij. Twee codebases vertegenwoordigden één business-intentie onder verschillende owners, backlogs en releasecadansen.
2. Iedere wijziging ging door de afdelingsmuur
Na ontwikkeling droeg DA inputs, outputs, bedrijfsregels en verwachte resultaten over aan DE. Engineering reconstrueerde de requirement, plande het werk, ontwikkelde en valideerde het. Een kleine bug volgde dezelfde route. De codewijziging kon klein zijn, terwijl de organisatorische wachttijd één of meer sprints besloeg.
3. De kosten van het formele pad creëerden een shadow pipeline
De Airflow-ETL bood gedeelde planning, tests, lineage, alerts en operations, maar iedere requirement wachtte op een herschrijving door DE. Met cron geplande notebooks lieten team C die wachtrij omzeilen en sneller over data beschikken. Daardoor werden ze geleidelijk de productieroute waarop de business werkelijk vertrouwde. Het governed pad en het echte leveringspad liepen uiteen.
4. De shadow pipeline kon input-readiness niet betrouwbaar vaststellen
Cron-notebooks konden niet automatisch verifiëren of upstream-tabellen waren ververst. DA plande ze daarom later om het risico op ontbrekende of verouderde input te beperken. De notebookserver had bovendien minder rekenkracht dan het DE-cluster. Toen cronjobs verspreid door het business-team draaiden, kon DE de volledige DAG niet zien en bottlenecks op het end-to-end kritieke pad niet optimaliseren.
Daarnaast speelde ownership een rol. Team C bezat de dashboards en zijn analisten bezaten de notebooks. Tijdens mijn eerste engagement bij deze klant had ik de rework-loop al benoemd, maar engineering had nog niet het mandaat en vertrouwen om de werkwijze van een ander team te veranderen.
In de eerste maanden van mijn tweede engagement loste ik daarom de bestaande problemen op: rapportagefouten, Spark-performance-incidenten en IAM-issues. Die leveringen bouwden voldoende vertrouwen op om bij een volgend reporting-ticket een nieuwe werkwijze te testen.
Oplossing: SQL van analisten opnemen in het governed leveringspad
In één week bouwde ik naast de bestaande productieflow een parallel pad voor één dashboard. Beide flows gebruikten dezelfde input en leverden dezelfde output, zodat de teams de werkwijzen met echte resultaten konden vergelijken.
DE definieerde acht beperkingen voor dit leveringspad. Analisten behielden de snelheid bij het schrijven van bedrijfslogica; engineering hield controle over datagrenzen, runtimegedrag en de uiteindelijke publicatie.
1. Notebooks bevatten alleen SQL
Python was niet toegestaan in DA-notebooks. SQL dekte de benodigde transformaties en was eenvoudiger te lezen. Parsers en linters konden bovendien inputtabellen, outputtabellen en statementtypes vóór uitvoering inspecteren. Nadat de nieuwe werkwijze stabiel was, voltooide DA de meeste nieuwe bedrijfslogica binnen een paar uur tot één dag.
2. Inputs kwamen alleen uit Silver en Gold
DA kon uitsluitend door DE beheerde Silver- en Gold-tabellen lezen. Airflow beheerde ownership, schedules en refreshstatus van die tabellen. Een notebook kon geen onbeheerde tijdelijke bron het leveringspad in trekken.
3. Outputs gingen alleen naar een aparte experiments layer
DA had geen rechten om notebookoutput terug te schrijven naar de Silver- of Gold-domeinen van DE. Alle tussenresultaten landden in een aparte experiments data layer. De input- en outputregels vormden samen een eenrichtingsstroom en voorkwamen dat experimentele resultaten terugliepen naar hun eigen governed inputs.
4. SQL moest idempotent zijn
Herhaalde uitvoering over dezelfde input moest hetzelfde resultaat opleveren. Het schrijfbeleid stond overwrite toe en wees append af. Airflow-retries, handmatige reruns en historische reruns stapelden daardoor geen dubbele data op.
5. YAML was het leveringscontract voor iedere notebook
DE volgde alle notebooks in één YAML-bestand, inclusief inputs, outputs en schedule. CI/CD valideerde het volledige bestand statisch. Dezelfde configuratie genereerde lineage, bepaalde upstream- en downstreamrelaties en volgde planningsafhankelijkheden.
6. Goedgekeurde notebooks werden gecompileerd en via DQ gepromoveerd
Na automatische controles en review haalde tooling de SQL in cell-volgorde uit
de notebook en genereerde een geordende reeks .sql-bestanden. Die draaiden
eerst in de experiments layer. DE bezat het schema en de schrijfrechten van de
uiteindelijke Gold-tabel, zodat schemawijzigingen van DA alleen de experiments
layer raakten. Resultaten bereikten de door DE beheerde Gold-tabel pas nadat de
laatste DQ-controles waren geslaagd.
7. Een DAG factory beheerde planning en dependencies
Airflow genereerde notebook-DAG’s vanuit YAML via een DAG factory. Code leidde DAG-dependencies af uit de gedeclareerde input- en outputrelaties en gebruikte de refresh van upstream-tabellen als runtime-gate. Een notebook-DAG kon pas starten wanneer zijn inputtabellen gereed waren. DAG’s konden daardoor eerder worden ingepland en direct starten zodra de echte input gereed was, zonder een vaste conservatieve vertraging.
8. DE onderhield de gedeelde componenten
DE implementeerde en onderhield DQ-controles, Gold-promotion en publicatie naar het uiteindelijke BI-systeem. Workloads draaiden op het krachtigere DE-cluster. Toen Airflow de volledige DAG-grafiek liet zien, kon engineering ook bottlenecks over meerdere taken herkennen en het kritieke pad optimaliseren. Analisten richtten zich op business-SQL; het platform leverde veiligheidsgrenzen, betrouwbare planning en productie-integraties.
De dagelijkse ontwikkelworkflow na het herontwerp
DA bleef ontwikkelen, wijzigen en debuggen in de vertrouwde notebook en liet de logica eerst doorlopen tot een gecontroleerde output in de experiments layer. Versioning gebeurde op de achtergrond: notebooks synchroniseerden automatisch naar een door DE beheerde repository. Iedere wijziging kreeg historie, zonder dat DA Git hoefde te gebruiken of de bedrijfslogica in een andere taal moest herschrijven.
Zodra het resultaat gereed was, hoefde DA alleen aan DE te melden dat het kon worden uitgerold. DE pushte de gesynchroniseerde notebook naar een branch en opende een PR, meestal 10–20 minuten werk. CI/CD controleerde vervolgens SQL- statementtypes, input- en outputgrenzen, idempotentie, het YAML-contract en de dependencies. Een geslaagde pipeline liet zien dat de wijziging binnen de door DE gedefinieerde guardrails bleef. De pipeline extraheerde automatisch de SQL, bouwde de DAG en voltooide de productie-uitrol in ongeveer tien minuten. DE reviewde dezelfde notebook die DA al succesvol had uitgevoerd; engineering bouwde de bedrijfslogica niet opnieuw.
Het PR-werk en de pipeline-uitvoering zelf kostten samen ongeveer 20–30 minuten. Inclusief melding, wachttijd voor review en bevestiging van de deployment duurde productie-onboarding nadat de SQL gereed was meestal één tot twee uur.
DA ontwikkelt of debugt in een versioned notebook
→ experiments-output gevalideerd
→ DA meldt aan DE dat deployment kan starten
→ DE pusht de gesynchroniseerde versie en opent een PR (10–20 minuten)
→ CI/CD controleert de DE-guardrails
→ SQL en DAG automatisch gebouwd; productie uitgerold (~10 minuten)Ook incidenten kregen een expliciete route. Na een Airflow-alert controleerde DE eerst de governed grenzen: ontbreekt upstream-input en wijkt het schema van de uiteindelijke outputtabel af van het contract? Problemen met input, output of de platformruntime loste DE op. Als die grenzen gezond waren, lag het onderzoek weer bij de bedrijfslogica. DA debugde dezelfde notebook in de experiments layer en stuurde de fix door het geautomatiseerde pad hierboven. De teams hoefden geen twee implementaties meer over te dragen en te vertalen; observeerbare resultaten bepaalden aan welke kant het probleem thuishoorde.
DA SQL-notebook
→ CI/CD: alleen SQL, idempotent, governed inputs, outputs alleen naar experiments
→ automatisch geëxtraheerde geordende SQL-bestanden
→ YAML + DAG factory + upstream-refresh-gates
→ experiments data layer
→ DQ-validatie
→ door DE beheerde Gold-tabel
→ BI-publicatieDe parallelle pilot maakte het voorstel tastbaar. Stakeholders zagen dezelfde input, dezelfde output en een veel kortere leveringsroute. Een werkend voorbeeld leverde de onderbouwing voor goedkeuring.
Resultaten: winst voor business, DA en DE
Het resultaat laat zich samenvatten in drie voordelen:
- Business: de dagelijkse dashboarddata stond tussen 5 en 7 uur klaar, voordat gebruikers om 9 uur begonnen.
- DA: analisten kregen de tijd terug die eerder naar onderhoud van oude notebooks, runtimefouten en refreshcontroles ging, en richtten zich weer op nieuwe requirements.
- DE: engineering schrapte de dubbele PySpark-implementatie en de tijd voor uitleg, overdracht en afstemming, en gebruikte die capaciteit voor datakwaliteit, performance en platformmogelijkheden.
| Metric | Voor | Na |
|---|---|---|
| Nieuwe bedrijfslogica door DA | Geen stabiele baseline | Meestal uren–1 dag |
| Productie-onboarding na SQL | 1–2 engineering-sprints | 1–2 uur |
| End-to-end dashboard-TTM | 4–6 weken | Ongeveer 1 werkdag |
| DA-teamcapaciteit teruggewonnen | — | ~6–8 mandagen / week |
| DE-tijd teruggewonnen | — | ~5 mandagen / sprint |
| Dashboarddata beschikbaar | 10–11 AM | 5–7 AM |
Het herontwerp verkortte de denk- en ontwikkeltijd voor nieuwe bedrijfslogica niet rechtstreeks. Voor de wijziging bestond daarvoor geen stabiele baseline; nadat de werkwijze was gestabiliseerd, kostte de meeste nieuwe logica een paar uur tot één dag. De grotere winst zat in teamcapaciteit. DA besteedde veel minder tijd aan het draaiend houden van cron-notebooks, runtimefouten en handmatige refreshcontroles. Daardoor kwam meer tijd beschikbaar voor nieuwe requirements. Zodra de SQL gereed was, kostte productie-onboarding nog 1–2 uur en kwam de gebruikelijke end-to-end doorlooptijd uit op ongeveer één werkdag.
Uitgaande van een werkdag van acht uur besteedden de vier DA’s iedere maandag samen vier uur aan het oplossen van problemen: 16 uur voor het team. Daarnaast besteedde iedere DA wekelijks nog 1–1,5 dag aan storingen in de eigen notebooks, oftewel nog eens 32–48 uur. Als die twee blokken niet overlappen, kostte het in de lucht houden van de bestaande notebooks 48–64 teamuren per week, ongeveer 6–8 mandagen. Het herontwerp nam het grootste deel van die onderhoudslast weg, waardoor het merendeel van deze capaciteit beschikbaar kwam voor nieuwe requirements.
Door de tweede implementatie en haar wachtrij te verwijderen, won engineering ongeveer vijf mandagen per sprint terug. Die tijd ging naar bronkwaliteit, performance-bottlenecks, lineage-tooling en compute- en storage-efficiëntie.
Dashboarddata die meestal tussen 10 en 11 uur ‘s ochtends klaarstond, werd nu tussen 5 en 7 uur beschikbaar. Drie veranderingen zorgden daarvoor:
- Airflow controleerde of inputtabellen gereed waren, zodat DAG’s vroeg konden worden ingepland en direct na upstream-refreshes startten.
- SQL draaide op het DE-cluster, dat sneller was dan de eerdere notebookserver.
- DE zag de volledige DAG-grafiek, vond bottlenecks over meerdere taken en optimaliseerde het kritieke pad.
Business-users begonnen de ochtend daardoor met actuele data, ook tijdens de kwetsbaardere maandagcyclus. Het governed pad werd sneller en voorspelbaarder, waardoor DA de cron shadow pipeline niet meer hoefde te onderhouden.
Gedachten hierover? Discussieer met mijn agent, of stuur me een bericht.