Bouwplan 03
Capaciteit: kun je het volume aan?
Instroom versus uitstroom per dag, netto-groei en een backlog-curve die elke dag harder wordt. Het rapport dat het gesprek over bezetting van onderbuikgevoel naar cijfers verplaatst.
Niveau: gevorderd · Bouwtijd: 3–5 uur · Nodig: Zendesk admin, Vercel, key-value store, Claude
Bouw eerst Bouwplan 02 (piekuren-heatmap) — daar staat de datalaag die dit rapport hergebruikt.
Wat je bouwt
- Instroom en uitstroom per dag, rolling 30 dagen, met filter op land/markt
- Netto per dag (instroom min uitstroom) rond de nullijn: groeit of krimpt je backlog?
- Backlog-curve met echte dagmetingen erin gemarkeerd
- KPI-tegels: instroom/dag · uitstroom/dag · netto/dag · dekking · auto close/solve per dag · backlog nu · wacht op klant · verandering backlog over de periode
- Schakelaar "Wie lost op": Team · Auto close/solve · Totaal
- Uitklapbaar definitieblok, tweetalig NL/EN
Waarom dit rapport
Bezetting bespreekbaar met cijfers
Dekking onder de 100% betekent dat je backlog oploopt, hoe hard iedereen ook werkt.
Vroegsignaal
De netto-grafiek draait weken eerder dan de klachten binnenkomen.
Eerlijke throughput
Tickets die een automation afhandelt tellen niet als teamwerk, dus je meet mensen niet af op werk dat de robot deed.
De meetbeslissing die alles bepaalt
In de standaard Zendesk Explore-tegels staat "Tickets solved" gegroepeerd op aanmaakdatum. Daardoor kan uitstroom per definitie nooit boven instroom uitkomen en lijken beide grafieken bijna identiek — je leest er niets over capaciteit uit af. Meet uitstroom op oplosdatum (solved_at). Dat is je echte throughput.
In 7 stappen
- 1
Leg je definities vast
- Zet deze letterlijk op de pagina, niet in een los document.
Begrip Definitie Instroom Tickets op aanmaakdatum. Spam en closed_by_merge tellen niet mee. Uitstroom Tickets op oplosdatum (solved_at). Wanneer het werk gedaan is. Netto Instroom min uitstroom. Positief betekent: backlog groeit die dag. Dekking Uitstroom gedeeld door instroom, maal 100%. Structureel onder de 100% en je backlog loopt op. Backlog Alles wat niet is opgelost: new, open, pending en on-hold. Momentopname, geen leeftijdsgrens, niet-toegewezen tickets tellen mee. Wacht op klant Het deel van de backlog met status pending of on-hold. Zit in de backlog, maar is geen werkvoorraad voor je team. Team vs. auto close/solve Tickets met de tag auto_solve of auto_close zijn door een trigger of automation afgehandeld en tellen niet als teamwerk. Rolling 30 dagen Laatste 30 kalenderdagen tot en met vandaag, Europe/Amsterdam. Vandaag is een deel-dag en ligt altijd laag. - 2
Haal instroom en uitstroom op
- Zelfde incremental export als bouwplan 01, maar bewaar per ticket ook het oplosmoment.
- Slank record: aanmaakmoment, oplosmoment, taal-tag, tags, brand.
- Query voor je backlog-anker.
- Zendesk-statussen zijn geordend (new < open < pending < hold < solved), dus "wacht op klant" is een tweede query.
type:ticket brand:<id> status<solved type:ticket brand:<id> status<solved status>open - 3
Anker je backlog op een echte meting
- Gebruik het search count-endpoint, niet een lijstquery: dat geeft een exact aantal en loopt niet tegen de 1000-resultatenlimiet aan.
- Meet totaal en per markt (tags:language__xx). Vijf calls per run is verwaarloosbaar.
- 4
Reken de historie terug
- Daarmee heb je meteen 30 dagen curve, zonder dat je een half jaar hebt zitten meten.
- Schrijf bij elke volle run de gemeten backlog weg per dag. Waar een dagmeting bestaat, overschrijft die de reconstructie — markeer die punten in de grafiek. Zo wordt je curve elke dag harder.
B(d-1) = B(d) − instroom(d) + uitstroom(d) - 5
Vang de late solves af
- Een ticket dat ouder is dan je bewaarvenster maar vandaag wordt opgelost, telt wel als uitstroom. Gooi je dat weg, dan drijft je hele curve weg.
- Oplossing: bewaar van die tickets een slank record (aanmaakmoment, oplosmoment, taal, markering "oud") zolang de oplosdatum in je venster valt, en sla ze over in je KPI-berekening.
- 6
Scheid teamwerk van automations
- Hang een tag aan elke trigger of automation die zelf tickets oplost of sluit. Wij gebruiken auto_solve en auto_close.
- Let op het verschil: "solved wordt na 28 dagen closed" is géén extra uitstroom (het ticket was al opgelost). Een automation die een onaangeraakt ticket sluit is dat wél.
- Houd de tag-lijst in een omgevingsvariabele, dan kun je uitbreiden zonder code te wijzigen.
- Zet je rapport standaard op scope "Team" en toon de auto-afhandeling als aparte tegel met percentage.
ZENDESK_AUTOSOLVE_TAGS=auto_solve,auto_close - 7
Visualiseer zonder trucs
- Instroom en uitstroom als twee losse grafieken onder elkaar (small multiples), niet als gegroepeerde balken naast elkaar. Losse dagpieken en het weekendritme lees je zo veel beter.
- Gedeelde y-schaal over beide grafieken, en vermeld dat onder de grafiek. Anders vergelijk je hoogtes die niet vergelijkbaar zijn.
- Netto in een eigen grafiek rond de nullijn.
- Backlog altijd in een eigen paneel. Nooit als tweede y-as over de balken heen.
- Kleuren die wij gebruiken (dataviz-gevalideerd, kleurenblind-veilig):
Instroom #1C64AC Uitstroom #63B3E8 Netto groei #D4562F Netto afname #1C64AC
Valkuilen
Uitstroom op aanmaakdatum: De standaard Explore-instelling. Je grafiek ziet er prima uit en zegt niets.
Vergeten backfill na een modelwijziging: Nieuw veld, lege historie, uitstroom blijft op nul staan. Eenmalig resetten en opnieuw opbouwen.
Te krappe functie-limieten: Zet je maxDuration hoog genoeg en houd marge voor de nawerking, anders loopt de run in een timeout.
Goed nieuws bij een timeout: Schrijf je state pas ná de verwerkingslus weg, dan verlies je alleen tijd en geen data — de volgende run pakt dezelfde pagina's opnieuw.
Heropende tickets: Die laten teruggerekende dagen een paar tickets afwijken. Lost zichzelf op zodra je dagmetingen zich opbouwen.
Deel-dag: Vandaag telt alleen de verstreken uren. Laat vandaag buiten je gemiddelden.
Markt is een taal-tag: Tickets zonder tag vallen onder Overig. Je landfilter is net zo compleet als je tag-dekking.
Pending uit de backlog knippen: Niet doen. Zet het apart als "wacht op klant" met percentage, dan blijft het totaalbeeld eerlijk.
Secret in de browser: Laat de refresh-knop server-side afvuren. En gebruik een secret zonder leestekens, anders breekt je shell.
Hoe je dit leest
- Loopt de dekking structureel onder de 100%? Dan is het een bezettingsvraag.
- Loopt vooral "wacht op klant" op? Dan is het een opvolg-probleem: te weinig reminders, te lange wachttijden aan klantzijde. Geen extra mensen nodig.
- Combineer met bouwplan 01: de heatmap zegt wanneer het volume komt, dit rapport of je het aankunt.
Doe het samen met Claude
Drie prompts. Kopieer, plak, bouw mee.
Prompt 1 — Definities scherp krijgen
Ik bouw een capaciteitsrapport op helpdeskdata: instroom versus uitstroom per dag, netto, dekking en een backlog-curve. Stel mij de vragen die nodig zijn om de definities waterdicht te krijgen: wat telt als instroom, wat als uitstroom, wat zit er in de backlog, hoe ga ik om met pending en on-hold, en met tickets die een automation oplost. Schrijf daarna een definitieblok dat ik letterlijk op de pagina kan zetten.
Prompt 2 — De worker schrijven
Schrijf een serverless functie die tickets ophaalt via de Zendesk Incremental Ticket Export en per dag instroom (aanmaakdatum) en uitstroom (oplosdatum) berekent over de laatste 30 dagen, per markt op basis van taal-tags. Haal de huidige open backlog op via het search count-endpoint (status<solved), reken de historie terug met B(d-1) = B(d) - instroom(d) + uitstroom(d), en schrijf elke run een harde dagmeting weg zodat die de reconstructie overschrijft. Tickets met de tags auto_solve of auto_close tel je apart als niet-teamwerk. Houd de functie herstartbaar met een cursor en schrijf de state pas weg na de verwerkingslus.
Prompt 3 — De pagina bouwen
Bouw een capaciteitspagina op dit JSON-endpoint: instroom en uitstroom als twee losse dagstaafgrafieken onder elkaar met een gedeelde y-schaal, een netto-grafiek rond de nullijn, en de backlog als aparte lijngrafiek waarin gemeten dagen als punt zijn gemarkeerd. Voeg KPI-tegels toe (instroom/dag, uitstroom/dag, netto/dag, dekking, auto close/solve per dag, backlog nu, wacht op klant, verandering backlog), een periodekeuze 7/14/30 dagen, een marktfilter, een schakelaar Team/Auto/Totaal en een uitklapbaar definitieblok. Geen dubbele y-as. Tweetalig NL/EN.
Checklist voor oplevering
- Uitstroom staat op oplosdatum, niet op aanmaakdatum
- Definities staan op de pagina zelf
- Backlog-anker komt uit een count-query, niet uit een lijstquery
- Dagmetingen worden opgeslagen en overschrijven de teruggerekende curve
- Auto close/solve staat apart en het rapport staat standaard op Team
- Instroom en uitstroom delen dezelfde y-schaal en dat staat er ook bij
- Backlog staat in een eigen paneel, geen tweede y-as
- Vandaag telt niet mee in de gemiddelden
- Je kunt in één zin uitleggen of je het volume aankunt
Twee routes
Laat CX Digital het bouwen
Wij zetten de koppeling, het rapport en de definities in jouw omgeving neer en kalibreren met je team.
Plan een gesprekVeelgestelde vragen
Wat is dekking precies?+
Uitstroom gedeeld door instroom, maal 100%. Bij 95% los je 95 tickets op voor elke 100 die binnenkomen: je backlog groeit elke dag met 5. Eén dag onder de 100% is ruis, drie weken onder de 100% is een capaciteitsprobleem.
Waarom meet je uitstroom op oplosdatum en niet op aanmaakdatum?+
Omdat uitstroom op aanmaakdatum per definitie nooit boven instroom kan uitkomen. Je ziet dan twee bijna identieke grafieken waar je niets uit kunt afleiden. Op oplosdatum meet je wat je team die dag echt heeft weggewerkt, inclusief oude tickets.
Waarom laten jullie pending en on-hold in de backlog zitten?+
Omdat dat het eerlijke totaalbeeld is: die tickets zijn niet opgelost. Voor de vraag of je genoeg mensen hebt is het misleidend, want bij pending ligt de bal bij de klant. Daarom staat het apart als 'wacht op klant' met percentage, in plaats van het uit de backlog te knippen.
Ik begin vandaag. Hoe kom ik aan historie?+
Meet je huidige open backlog en reken terug met instroom en uitstroom per dag: B(d-1) = B(d) - instroom(d) + uitstroom(d). Daarmee heb je direct 30 dagen curve. Vanaf dat moment schrijf je elke dag een echte meting weg, die de teruggerekende waarde overschrijft. Je curve wordt dus elke dag betrouwbaarder.
Tellen tickets die een automation oplost mee?+
Als instroom wel, als teamwerk niet. Zet een tag op elke trigger of automation die zelf oplost of sluit en filter daarop. Zonder die scheiding lijkt je team meer weg te werken dan het doet. Let op: het standaard 'solved wordt na 28 dagen closed' is geen extra uitstroom.
Kan ik hieruit afleiden hoeveel FTE ik nodig heb?+
Het is de helft van de rekensom. Vermenigvuldig je ticketvolume met je gemiddelde afhandeltijd en deel door de netto service-minuten per agent. Let op dat helpdesks de tijd meestal op het ticket registreren en niet per interactie: je AHT is dus de opgetelde tijd over alle interacties. Een lage first contact resolution verklaart dan een hoge AHT.
De hele methodiek
Wil je de hele methodiek? Start de gratis cursus.
De C1-C2 Masterclass leert je stap voor stap hoe je een waterdichte ticketcategorisatie opzet. Vijf modules, ongeveer twee uur.
Start de cursus