E-commerce
Shopify Flow limieten: veldgids voor Klaviyo-migraties
Je haalt abandoned cart weg bij Klaviyo. Dan moet de welkomstflow 35 dagen wachten, en Shopify Flow stopt bij 30. Hier is de veldgids voor de rest.

Het is dinsdagavond 21:00 en je marketinglead zit in de Shopify Admin om de welkomstserie opnieuw op te bouwen die ze vijf jaar lang op Klaviyo heeft gedraaid. De browser heeft twee tabs open. De Flow-editor, en het helpdocument waarin staat "Wait actions support delays from one minute to 30 days." Haar oude Klaviyo-sequentie had een re-engagement-stap van 35 dagen. Ze klapt haar laptop dicht en mailt jou.
Hier verandert de gemiddelde Klaviyo-naar-Shopify-Flow-migratie van een schone swap in een project. De Flow-editor lijkt op het eerste gezicht op Klaviyo. Dat is niet zo. De limieten zijn anders, ze duiken op andere plekken op, en ruwweg de helft is in de Admin te ontwerpen, terwijl de andere helft een Remix-app vraagt en een developer die weet wat een Shopify Function is.
We hebben de afgelopen achttien maanden Klaviyo-flowbibliotheken opnieuw opgebouwd op Shopify Flow plus Functions voor verschillende merchants. Dezelfde zestien limieten komen elke keer terug. Dit is de veldgids die we de merchant op dag één meegeven.
Waar de migratie meestal sneuvelt
De automation builder van Klaviyo is een lange, vertakte graph die draait op Klaviyo's servers en gebruikmaakt van Klaviyo's profile store. Je sleept een Wait. Je sleept een Conditional Split. Je sleept een Send Email. De graph leest van boven naar beneden en de bouwblokken zijn er in overvloed.
Shopify Flow is ook een graph, maar draait op Shopify's event bus, gebruikt Shopify's customer- en order-objecten, en heeft geen van Klaviyo's e-mailinfrastructuur. Het Send Email-blok in Flow weet alleen hoe het moet praten met Shopify Email, het interne customer service-team, of een HTTP endpoint dat jij aanlevert. Het vocabulaire is kleiner, de input is strikter, en de side effects zijn getypeerd.
Die wissel van substraat is waar de limieten leven. Flow ruilt Klaviyo's profielgerichte flexibiliteit in voor Shopify's objectmodel en event-throughput. De zestien limieten hieronder komen allemaal uit die ruil.
Acht limieten die een marketinglead in de Admin omzeilt
Dit zijn de limieten waarvoor je geen ticket bij een developer hoeft te openen. Open de Flow-editor, ontwerp eromheen, en ship.
1. De Wait van maximaal 30 dagen
De Wait-actie van Shopify Flow accepteert een vertraging van één minuut tot 30 dagen. De equivalent bij Klaviyo gaat tot een jaar, waar abonnementsmerken op leunen voor refill-nudges van 90 dagen. Had je oude sequentie een re-engagement-stap van 45 dagen? Ketting twee Waits aan elkaar. Flow-runs zijn duurzaam, dus een Wait van 30 dagen gevolgd door een van 15 dagen werkt. De prijs is dat de tweede Wait leest uit de customer state die bij de trigger is vastgelegd, niet de state op minuut 30. Check dus opnieuw wat in de tussentijd had kunnen veranderen.
2. Customer Created versus Customer Account Activated
Twee triggers, twee verschillende doelgroepen. Customer Created vuurt af zodra er een customer record verschijnt, inclusief de records die automatisch worden aangemaakt vanuit guest checkout. Customer Account Activated vuurt pas af zodra de klant een wachtwoord instelt. Ging je oude Klaviyo-welkomstserie ervan uit dat er een account was? Gebruik Account Activated. Anders mail je mensen die niet weten dat ze klant zijn.
3. Geen native percentage A/B-split
De Conditional Split van Klaviyo heeft een "random percentage"-modus. Flow niet. De workaround is de Random Number-conditie: gooi een getal tussen 1 en 100, en vertak op de vraag of het kleiner is dan je splitpunt. Documenteer het seed in een notitie op de flow, zodat het analytics-team het later terug kan lezen.
4. Latency, geen real-time
Flow-triggers draaien op een event queue, niet synchroon. Reken op één tot vijf minuten tussen het event en de eerste actie, langer tijdens piekuren zoals de maandagochtend van Black Friday. Ging je oude Klaviyo-flow uit van een instant cart-abandon mail op het 30-minutenpunt? Zet de Wait dan op 25 om dat te compenseren.
5. Send Email loopt via Shopify Email of HTTP
Send Internal Email in Flow is voor medewerkers. Klantmail gaat via de Shopify Email-actie, die een template vraagt die je instelt in het marketingtabblad. Hield je Klaviyo aan als verzender en verhuisde je alleen de automations? Dan heb je een HTTP Request-actie nodig die naar de events-API van Klaviyo post. Dat introduceert de volgende limiet.
6. Metafield-vergelijkingen zijn string-getypeerd
De Condition-actie ziet metafields als strings, ook als het onderliggende type integer of JSON is. Een lifetime-value-metafield vergelijken met 500 via "is greater than" werkt, omdat Flow casteert. Een JSON-metafield faalt stilletjes. Schrijf de waarde die je nodig hebt naar een platte string-metafield of een customer tag, en condition daarop.
7. Customer Segments worden één keer per run geëvalueerd
De Customer Segment-conditie leest het segment zoals het was op het moment dat de trigger afvuurde. Komt een klant midden in de flow in segment X terecht? De lopende instance merkt het niet. Ontwerp segmenten zo dat ze de trigger zijn, geen mid-flow-gate.
8. Geen flows tussen stores
Draai je meerdere Shopify-stores onder één merk? Flow deelt niet tussen die stores. Elke store heeft een eigen kopie nodig. Gebruik de import en export van Flow om ze gelijk te houden, versioneer de JSON in git, en zet er een CODEOWNERS-bestand bij, zodat het brandteam elke afwijking moet goedkeuren.
Ongeveer 70 procent van een typische Klaviyo-flowbibliotheek is door een marketinglead opnieuw op te bouwen in de Shopify Admin, zodra de acht bovenstaande beperkingen op een whiteboard staan.
Acht limieten waar je een Remix-developer voor nodig hebt
Dit zijn de limieten waarbij de merchant moet stoppen met blokken slepen en de developer moet bellen. Elke limiet is op te lossen, maar de oplossing leeft in een Shopify-app, vrijwel altijd gebouwd op Remix, met een Flow Connector-extension of een Function-extension.
9. De 10-seconden-timeout van de HTTP Request-actie
De HTTP Request-actie van Flow geeft het na tien seconden op en behandelt alles boven ongeveer 50KB response body als een failure. Die enrichment-API van jou die 12 seconden nodig heeft om een lead te scoren, breekt de run. Wikkel hem in een Cloudflare Worker of een Remix-route die proxy't, cachet en binnen budget antwoordt. Diezelfde proxy is de plek waar je de retry-logica neerzet die Flow je niet geeft.
10. Het 11ms CPU-budget van Functions
Shopify Functions draaien als WebAssembly en hebben een CPU-limiet van 11 milliseconden per invocation. Port je een Klaviyo-stap die een dynamische korting berekent? Dan kun je niet over 10.000 line items loopen om string math te doen. Profileer in de Functions log viewer, schakel hot paths over naar Rust zodra JavaScript out of budget loopt, en precompute zoveel mogelijk in metafields die je vanuit een webhook schrijft.
11. Functions kunnen geen HTTP-call doen
Een Function krijgt zijn input-JSON binnen, draait, retourneert een resultaat. Geen fetch, geen network, geen DNS. Hangt de korting af van een CRM-lookup? Dan moet die lookup eerder gebeuren (in Flow, in een order-webhook, ergens met netwerk) en moet het resultaat als metafield op de customer of cart de Function ingaan. Dit patroon verrast elke JS-developer bij zijn eerste Function.
12. De 256KB-inputlimiet op Cart Transform
De Cart Transform-function krijgt de volledige cart als input. Carts boven 256KB worden afgekapt. De meeste stores raken die grens nooit. B2B-stores met PO's van 500 regels raken hem op dag één. De fix: pre-filteren in de merchandising-laag, of bundle-uitklap splitsen over meerdere kleinere functions die op verschillende cart-condities geregistreerd zijn.
13. Discount stacking vraagt om een function
Standaard accepteert een Shopify-cart één automatic discount en één code discount, en die stapelen niet op elkaar. Klaviyo-flows die stapelende kortingen afvuurden via de order edit-API hebben geen Flow-equivalent. Een Discount function met de juiste combinesWith-metadata kan bijna elke stapelregel uitdrukken die je nodig hebt, maar je beheert nu zelf de rekensom.
14. Geen persistent state tussen function-runs
Functions zijn puur. Een function die twee keer op rij op dezelfde cart wordt aangeroepen, weet niets van de eerste run. Hangt je kortingslogica af van "de klant heeft deze aanbieding al twee keer gebruikt"? Dan moet die teller in een metafield staan dat een app na elke order bijwerkt. Plan eerst de write path, dan pas de read path.
15. Custom Flow-triggers en -actions vragen om een extension
Wil een marketeer een trigger als "subscription paused" of een actie als "stuur naar ons reviewplatform"? Dan leeft die in een Flow Connector-extension binnen een Remix-app. De extension declareert het trigger-schema, levert een webhook endpoint dat hem afvuurt, en registreert zich in de Flow-triggerpicker van de merchant.
16. Function-logs stoppen bij 10K events per shop per dag
Het Partners dashboard toont de laatste 10.000 Function-executions. Raak je dat plafond? Dan ben je de rest van de dag blind, wat op Black Friday neerkomt op de hele dag. Pijp dezelfde payload via de logging-API van de Function plus een webhook naar je eigen observability-stack. Wij gebruiken een kleine Remix-route die buffert en doorsluist naar een managed log service.
Limieten 11 en 14 stapelen. Heeft je kortingslogica zowel een live CRM-lookup als een gebruiksteller nodig? Dan schrijf je twee app-oppervlakken (een webhook-receiver en een metafield-writer) voordat de Function überhaupt iets doet.
De triage die we op dag één doen
Als een merchant belt met "we willen voor het einde van het kwartaal van de Klaviyo-automations af," is het eerste gesprek geen kickoff. Het is een audit van een uur. We openen de Klaviyo-flowbibliotheek, lijsten elke actieve flow op, en taggen er één van de zestien limieten hierboven aan. De verdeling komt meestal uit op 70/30: de meeste flows zijn in één sprint in de Admin op te bouwen, een handvol vraagt een Remix-app.
Dit is grofweg de vorm van het spreadsheet dat we teruggeven:
flow_name,blocked_by,owner,est_days
Welcome series,#1 wait 35d,marketing,0.5
Browse abandon,#4 latency,marketing,0.5
B2B reorder,#12 cart-transform,dev,4
Loyalty tier discount,#11 no http + #14 state,dev,6
Win-back 60d,#1 wait,marketing,0.5
Post-purchase upsell,#13 stacking,dev,3
De audit doodt de verrassingen die een migratie van vier weken in een van vier maanden veranderen. De Wait van 35 dagen ligt voor de hand. De Cart Transform die een B2B-bundel van 600 regels moet uitklappen in line items per warehouse, niet. Vind de tweede klasse vóór je gaat scopen.
Nog één ding over Functions
Het 11ms-budget is de limiet waar de meeste developers door overvallen worden. Heb je eerder serverless functions geschreven? Dan zegt je instinct: "Ik cache het zware werk en spreid het uit over runs." Functions hebben geen cache. Elke invocation begint vanaf nul. Het patroon dat werkt: zo min mogelijk in de hot path, alles wat kan in een Remix endpoint dat via een webhook metafields bijwerkt, en laat de Function die metafields goedkoop uitlezen.
Toen we vorig kwartaal de post-purchase en re-engagement automations voor een Nederlands beautymerk van Klaviyo afhaalden, was de muur waar we tegenaan liepen limiet elf. De dynamische-kortingsfunction had live loyaltytier-data nodig, en Functions kunnen niet fetchen. We hebben het opgelost door de tier vanuit een Remix-listener op de orders/paid-webhook naar een customer metafield te schrijven, waarna de Function hem bij checkout uit de buyerIdentity van de cart leest. Dit is het playbook dat we nu inzetten voor elke e-commerce-migratie op deze stack.
Sta je op het punt om je eigen migratie te beginnen? Het kleinste nuttige dat je vandaag kunt doen: open je Klaviyo-flowbibliotheek, tel de flows die een Wait langer dan 30 dagen gebruiken, en vraag bij elke Wait of die dragend is. Die ene telling voorspelt het grootste deel van de scope van het project.
Kern
De helft van elke Klaviyo-naar-Shopify-Flow-migratie is ontwerpwerk dat een marketeer in de Admin afmaakt. De andere helft vraagt een Remix-app met een Function-extension.
FAQ
Kan Shopify Flow Klaviyo volledig vervangen voor e-mail?
Voor de automation-logica grotendeels wel. Voor verzending heb je nog Shopify Email nodig, je eigen ESP via een HTTP Request-actie, of je houdt Klaviyo aan als verzendlaag terwijl Flow de triggers draait.
Hoe lang duurt een Klaviyo-naar-Shopify-Flow-migratie meestal?
Een mid-market store met acht tot vijftien actieve flows zit op drie tot zes weken. De verdeling is één sprint Admin-werk en één sprint Remix-app-werk voor alles waar een Function of Flow Connector bij nodig is.
Welke Shopify Function-limiet is het lastigst om omheen te ontwerpen?
De combinatie van geen externe HTTP en het 11ms CPU-budget. Je moet elke input vooraf als metafield klaarzetten, wat betekent dat je herschrijft hoe de rest van de stack data naar checkout voert.
Heb ik Shopify Plus nodig om Flow en Functions te gebruiken?
Flow zit tegenwoordig in de meeste Shopify-plannen. Functions zit standaard bij Plus en op lagere tiers via custom apps. Check je plan voordat je werk scoopt dat van een van beide afhangt.