← Blog

Tooling

Sanity, Payload en Directus: een veldtest met 14 redacteuren

Een Haarlemse vakuitgeverij draait 14 redacteuren en één wekelijkse printdeadline. We legden drie headless CMS-stacks langs de meetlat die de rekening bepaalt.

Jacob Molkenboer· Oprichter · A Brand New Company· 16 jun 2026· 8 min
Drie gestapelde leren notitieboeken met messing labels, groen zijden lint, rode lakzegel op kaart, ivoren papier.

Het is 22:47 op woensdagavond. De hoofdredacteur van een Haarlemse vakuitgeverij ziet net dat de bulk import van een freelancer de categorievelden van 217 archiefartikelen heeft overschreven. De printeditie gaat om 09:00 naar de drukker. Niemand in het team van 29 heeft 'ops' in zijn functietitel.

Dat moment kiest je CMS voor je. Niet de prijs per zetel. Niet het GraphQL-schema. De restore om 23:00.

Het afgelopen kwartaal hebben we de redactie van precies deze uitgever opnieuw opgebouwd. De shortlist bleef hangen op drie: Sanity, Payload en een zelfgebouwde Directus + Postgres-stack. Op een feature-matrix lijken ze inwisselbaar. Dat zijn ze niet.

Rekenen per zetel

Het bedrag dat opvalt, is het bedrag dat elke oprichter als eerste uitrekent.

Sanity's Growth-plan rekent per redacteursaccount. Voor 14 redacteuren kom je uit op zo'n €200 per maand op het openbare tarief, afhankelijk van hoeveel zetels je via goedkopere viewer-rollen kunt routeren. Tel daar document-historie langer dan 30 dagen en een enterprise SSO add-on bij op en je zit dichter bij €350. Het actuele bedrag staat op de openbare Sanity-prijspagina.

Payload heeft een MIT-licentie en is gratis als je zelf host. Payload Cloud's Standard-tier zit rond de $35 per maand voor de hosted versie met hetzelfde aantal redacteuren. We hebben echte teams Payload zien draaien op één Hetzner CX22 van €18 per maand, met een managed Postgres ernaast. Totale vaste kosten voor 14 redacteuren: onder de €50 per maand.

Directus heeft een vergelijkbaar kostenplaatje. Het is gratis onder de Business Source License zolang de jaaromzet van je organisatie onder de $5M zit. Daarboven heb je een commerciële overeenkomst nodig. Een vakuitgever rond de €3M zit nu veilig, volgend jaar misschien minder zodra ze een concurrent overnemen. Een reminder waard in je agenda.

Stop je hier met lezen, dan winnen Payload en Directus met 6-1 op stickerprijs. Dat scheelde weinig. Toen stelden we de tweede vraag.

Preview-latency in de 4G-trein

Een ervaren redacteur bij deze uitgever reist drie dagen per week van Utrecht naar Zwolle. Ze schrijft het hoofdartikel onderweg. Ze wil op 'preview' drukken en het artikel tegen de echte voorpaginalayout op haar telefoon zien renderen voordat de trein Amersfoort binnenrijdt.

Sanity's Studio is een statische React-app. De Content Lake staat op hun globale CDN met een regionale gateway in de EU. Draft-previews komen snel binnen, zelfs tijdens 4G-handovers, omdat de API niet hoeft te round-trippen naar je origin server. Over een week gemeten zagen we een mediaan van 380 ms tussen publish en preview-update op dat traject.

Payload draait waar je hem host. Zet hem op een Hetzner-bak in Falkenstein en je krijgt een snelle response uit Berlijn en een minder snelle wanneer de trein door een 3G-eiland ten oosten van Amersfoort komt. Wij maten een mediaan van 700 ms, met uitlopers boven de vier seconden bij een opnieuw opgezette verbinding. Een Vercel edge function ervoor dicht een deel van het gat. Niet alles.

Directus heeft een vergelijkbaar profiel als Payload, maar levert standaard een WebSocket-live preview mee. Dat is een echte feature wanneer de rest van de redactie een draft live wil zien ontstaan. De tradeoff: de WebSocket-verbinding valt weg bij elke zendmast-handover. Redacteuren leren refreshen.

Dit soort dingen benchmark je niet in een Slack-kanaal. Wij zaten in de trein van 17:08 naar Zwolle met de redacteur. We zagen haar op preview drukken, verbinding verliezen, opnieuw drukken, vloeken. Het verschil tussen 400 ms en 'verbinding verloren, probeer opnieuw' is geen getal. Het is een gevoel.

De restore om 23:00

Nu het deel dat de winnaar kiest.

Sanity. Document History zit ingebouwd in Studio met 30 dagen op Growth, langer op Business. Voor één verprutst document kan een redacteur met de juiste rol in drie kliks terugdraaien. Voor 217 documenten tegelijk heb je de dataset export- en importflow nodig. Heb je geen recente sanity dataset export-snapshot, dan kun je een point-in-time restore aanvragen bij Sanity support. Binnen het uur reageren ze tijdens EU-kantooruren. Op woensdag om 23:00 begint dat uur pas als hun Amsterdamse team rond 08:30 inlogt. Tegen die tijd is de printdeadline weg.

Payload. De Postgres is van jou. Restore is pg_restore tegen je laatste back-up. Dat werkt alleen als je die back-ups ook daadwerkelijk hebt geconfigureerd. We zijn in te veel Payload-on-Hetzner-stacks terechtgekomen waar de back-up-cron drie maanden geleden uitgecommentarieerd is 'tijdens een testje'. Payload biedt ook versionering per document als je versions: true op de collectie zet. De meeste teams vergeten dat. Zet 't aan op dag één.

Zelfgebouwde Directus. Versies en een volledige activities log staan standaard aan. Elke wijziging wordt vastgelegd met de gebruiker, het tijdstip, de vorige waarde en de nieuwe waarde. De Directus-UI heeft een ingebouwde revert per item, scriptbaar over 217 items via de SDK. De Postgres is nog steeds van jou, en pg_restore blijft je vangnet.

Hier loopt de keuze uiteen. Sanity gaat ervan uit dat je supportcontract het disaster-recovery-plan is. Payload gaat ervan uit dat jij dat plan bent. Directus splitst het verschil: de tools zitten erin en de database blijft van jou.

Waarschuwing

Kiest je team voor Payload of een zelfgehoste Directus en draait er geen geplande pg_dump, dan is je disaster-recovery-plan fictie. Zet de cron op en test de restore op dag één, niet na het eerste incident.

Waar elk pakket echt past

Na drie maanden parallelle pilots op een representatieve redactionele workload was het antwoord niet 'een van deze is de beste'. Het was 'elk pakket is het beste voor een specifieke teamvorm'.

Sanity past als je budget hebt voor de regel per zetel en niet aan infra wilt denken. De schema's zijn getypeerd, de studio is opinionated en redacteuren die van een vast spoor houden, zullen 'm geweldig vinden. Preview-latency is best-in-class zonder moeite.

Payload past als je minstens één engineer hebt die het CMS als onderdeel van de applicatie behandelt. Je wilt een Next.js-frontend en een CMS-admin uit één Node-proces serveren. Je wilt elke byte in de hand houden en je hebt een back-upstrategie die je daadwerkelijk test.

Directus op Postgres past als je de operationele ergonomie van een echte database wilt zonder de redacteurs-UX van een opinionated admin op te geven. Je redacteuren gebruiken dagelijks bulkoperaties, imports en exports. Je wilt een echte activity log zonder die zelf te bouwen. Je zit onder de BSL-omzetdrempel, of je voelt je prima bij de commerciële licentie.

Voor deze Haarlemse uitgever leverden we Directus op Postgres. Het beslissende moment was een vraag op de gang van de printredacteur: 'als er iets misgaat, kan ik het dan ongedaan maken zonder iemand te bellen?'. Directus antwoordde standaard ja. Lees de rest van de afwegingen in de Directus-docs als je tussen dit en Payload zit.

De audit van vijf minuten

Zit je op Sanity, Payload, WordPress of iets anders en weet je niet hoe je restore om 23:00 eruitziet, dan is hier een test van vijf minuten. Open je CMS. Maak een kleine destructieve wijziging op één document. Verander de titel. Probeer hem nu terug te zetten zonder een engineer te vragen. Klok jezelf.

Lukt het niet binnen 60 seconden, dan staat je CMS op één foute import na klaar voor een lange nacht. De volgende stap is een snapshot vóór elke bulkoperatie. Op een Directus + Postgres-stack ziet het script er zo uit.

# 1. Snapshot before any bulk operation
pg_dump -Fc -h db.example.nl -U editor cms_prod \
  > /backups/cms_pre_import_$(date +%Y%m%d_%H%M).dump

# 2. If the import goes wrong, restore the touched tables only
pg_restore -h db.example.nl -U editor -d cms_prod \
  -t articles -t articles_translations --data-only \
  --clean /backups/cms_pre_import_20260615_2145.dump

# 3. Verify with a row count and a manual spot check
psql -h db.example.nl -U editor cms_prod \
  -c "SELECT count(*), max(updated_at) FROM articles;"

De hele flow past op een post-it. Je wilt 'm op een post-it.

Waarmee de vakuitgever uiteindelijk live ging

Toen we bij deze uitgever de redactie aan elkaar bouwden, zetten we procesautomatisering vóór elke bulk import: elke upload draait eerst een pg_dump en post het pad van de snapshot in een Slack-kanaal. De nacht dat de XLSX van de freelancer 217 categorieën overschreef, kopieerde de hoofdredacteur het pad uit Slack, draaide één restore-commando en ging naar bed.

Dat is de winst. Niet de CMS-keuze zelf, maar het feit dat de CMS-keuze ruimte liet voor een back-upscript van vijf regels. Open vanavond je eigen CMS, wijzig een titel, klok de undo.

Kern

Het CMS dat wint is niet het CMS met het mooiste schema. Het is het CMS waarmee een niet-engineer 217 documenten om 23:00 kan terugzetten.

FAQ

Kan een niet-engineer een verprutste bulk import in Sanity terugzetten?

Ja, voor één document via de history-view in Studio. Een restore van 200 documenten vraagt om de dataset export- en importflow of een supportticket. Plan dat voordat je het nodig hebt.

Is Directus gratis voor een team van 14 redacteuren?

Ja, onder de BSL-licentie zolang de jaaromzet van je organisatie onder de $5M zit. Daarboven geldt een commerciële overeenkomst. Check dat voordat je opschaalt of overneemt.

Welke headless CMS heeft de laagste draft-preview-latency op mobiel?

In onze 4G-tests tussen Utrecht en Zwolle had het gehoste Content Lake van Sanity de laagste mediaan. Bij self-hosted Payload of Directus hangt de latency af van waar je de origin host.

Moet ik Payload Cloud draaien of zelf hosten?

Self-host als je al een Postgres hebt staan en iemand de back-ups beheert. Payload Cloud is de kleine maandelijkse fee waard als je geen extra server wilt onderhouden.

toolingarchitectureoperationscase studystrategy

Iets bouwen?

Start een project