Alle artikels
Software

Event sourcing en grote bestanden: zo hou je je event store snel en betaalbaar

Cover voor blogpost over grote bestanden in event sourcing

"Kandidaat heeft een CV geüpload." Een perfect event: kort, duidelijk, een feit dat gebeurd is.

Maar dan komt de vraag: waar laat je dat CV zelf? De pdf van 8 MB?

De verleiding is groot om hem gewoon mee in het event te stoppen. Alles op één plek, lekker simpel. Maar wie dat doet, zet een tijdbom onder zijn event store. In deze post leggen we uit waarom grote bestanden en event sourcing slecht samengaan als je ze inline opslaat, en hoe wij het oplossen zonder de voordelen van event sourcing op te geven.

Waarom bestanden niet in je event store horen

Bij event sourcing is je event store het logboek van je bedrijf: elk feit dat ooit gebeurd is, netjes op een rij. Dat logboek wordt voortdurend gelezen. Elke businessregel die iets controleert, elk overzicht dat opgebouwd wordt, leest events. Die leessnelheid is de motor van het hele systeem, en zoals we in onze benchmark toonden, is het uiteindelijk de database zelf die de bovengrens bepaalt. Alles wat je die database extra laat slepen, betaal je dus rechtstreeks in snelheid.

Stop je daar grote bestanden tussen, dan gebeuren er drie dingen, en geen enkel goed:

Je logboek wordt log. Een event van een halve kilobyte lezen gaat razendsnel. Duizend events lezen waarvan er tien een pdf van 8 MB meeslepen, niet meer. Je database sleept megabytes mee voor een controle die alleen wilde weten óf er een CV geüpload was.

Alles wordt duurder. Events verwijder je nooit, dus elk bestand dat je inline opslaat, blijft voor altijd. Je database groeit, je back-ups groeien mee, en het opnieuw afspelen van je geschiedenis duurt langer met elke upload.

Databases zijn er niet voor gemaakt. Bestanden horen in bestandsopslag, die daarvoor gebouwd en geprijsd is. Een database rij van 8 MB is voor elke database een vervelende uitzondering.

Kortom: een event store is gemaakt voor feiten, niet voor bijlagen.

De oplossing: het feit in de log, het bestand ernaast

Het idee is simpel. Het event beschrijft wat er gebeurde, het bestand zelf gaat naar een aparte opslagplaats (een blob store, zoals objectopslag bij je cloudprovider). In het event blijft alleen een klein verwijzingsnummer achter.

Concreet:

  1. Er komt een event binnen met een groot veld erin, bijvoorbeeld de inhoud van een CV.
  2. Vóór het event in de log belandt, wordt dat veld eruit gelicht en apart opgeslagen.
  3. In het event blijft alleen het verwijzingsnummer over. Het event zelf is weer klein.
  4. Wordt het event later gelezen, dan wordt het bestand er automatisch weer bij gehaald. Voor de rest van de software lijkt het alsof het er altijd in zat.

Je logboek blijft slank en snel, en de bestanden staan waar ze thuishoren.

De slimme bijvangst: niet alles hoeft het bestand te lezen

Hier wordt het pas echt interessant. De meeste onderdelen van je software hebben het bestand helemaal niet nodig.

Neem een overzicht dat toont hoeveel CV's er deze maand binnenkwamen. Dat hoeft alleen te tellen, niet te lezen. Door het bestand pas op te halen wanneer iemand er echt om vraagt (als een recruiter de pdf opent, bijvoorbeeld), lezen al die andere onderdelen alleen de kleine events. Dat scheelt enorm in snelheid, zeker bij het opnieuw opbouwen van overzichten over jaren aan geschiedenis.

En de GDPR dan?

Grote bestanden zijn vaak precies de dingen met persoonsgegevens erin: CV's, contracten, foto's. In een vorige post legden we uit hoe we persoonsgegevens in events wisbaar maken met crypto shredding: de sleutel weggooien in plaats van de kluis.

Voor bestanden ligt het nog eenvoudiger. Ze staan niet ín de onveranderlijke log, maar ernaast. Dus bij een verwijderverzoek onder de GDPR kunnen ze gewoon echt verwijderd worden. Het event blijft staan als feit ("er werd een CV geüpload op 12 maart"), het bestand zelf is weg. Wordt zo'n event later nog gelezen, dan herkent het systeem dat de bijlage verwijderd is en gaat het daar netjes mee om, in plaats van te crashen op een bestand dat er niet meer is.

Zo werken de twee mechanismen samen: crypto shredding voor de persoonsgegevens in de events, echte verwijdering voor de bestanden ernaast. Eén verwijderverzoek, en beide zijn afgehandeld.

Hoe wij het aanpakken

In ons framework zit dit ingebouwd als een laag die automatisch meedraait, net zoals de encryptie. Bij het wegschrijven van een event geef je aan welke velden bijlagen zijn. De rest gebeurt vanzelf: opslaan in de blob store, verwijzing in het event, transparant terugladen bij het lezen.

De opslag zelf is inwisselbaar. Objectopslag bij een Europese cloudprovider, een schijf op je eigen server: het framework trekt het zich niet aan. Dat past bij hoe we sowieso bouwen: op Europese infrastructuur, zonder vendor lock-in, en met opslagkosten die kloppen met wat je opslaat.

Het resultaat: een event store die snel blijft, back-ups die betaalbaar blijven, en bestanden die je bij een verwijderverzoek ook echt kwijt kan.

Eén ding zeggen we er eerlijk bij: dit hoeft niet vanaf dag één. Heb je alleen kleine events, dan voegt deze laag niets toe. Maar zodra er bestanden in je processen zitten (documenten, foto's, scans), wil je dit vanaf het begin goed zetten. Achteraf bestanden uit een gegroeide event store peuteren is een vervelende verbouwing.

Zitten er documenten, foto's of scans in jouw processen en wil je weten of je opslag toekomstbestendig is? Praat met ons, we bekijken het graag samen.

Gepubliceerd op 27 jul 2026
Profile picture of cofounder Mathias
Engineering
Mathias Beke

Bouwt software die snel draait, weinig kost, en volledig op Europese servers staat.