Every retention program eventually argues about where a customer attribute should live. A VIP flag, a subscription tier, a preferred category, a loyalty balance: each one can sit as a Shopify customer tag, a Shopify metafield, a Klaviyo profile property, or a column in your warehouse. Pick the wrong home and you either can't segment on it, you overwrite it in a sync loop, or you rebuild the same logic in three places. This is a store-of-record decision, and it costs real revenue when it's wrong.
Key takeaways
- Customer tags are cheap and human-readable but carry no type, no history, and no structured value, so they break down as segmentation logic grows.
- Shopify allows up to 256 metafield definitions per resource type for the merchant, with a 64KB value ceiling on most types, which makes metafields the right home for durable, storefront-facing attributes.
- Klaviyo profile properties cap at 100KB per property and editing a property name creates a brand new property rather than renaming the old one, so schema drift is permanent.
- The Klaviyo to Shopify metafield sync silently refuses to update when the data type does not match the existing definition, which is the most common cause of a stuck attribute.
- When the same attribute is computed from data neither platform owns, the warehouse has to be the source of truth and reverse ETL pushes it out to both.
What actually counts as segmentation data?
Segmentation data is any attribute you filter or branch on that is not the raw event itself. It splits into three kinds, and the kind decides the home.
The first kind is descriptive and slow-moving: a birthday, a region, a wholesale flag, a preferred store. The second is computed from behavior: predicted lifetime value, average days between orders, a churn-risk band. The third is transactional state that changes with each order: last product bought, current subscription tier, points balance.
Descriptive attributes want a durable home that both the storefront and the ESP can read. Computed attributes want to live wherever the computation runs. Transactional state wants to live wherever it is authoritatively written, which is almost never the ESP.
Where does each store keep it, and what are the hard limits?
Each option carries a different ceiling, a different type system, and a different blast radius when it breaks. The table below is the version I keep in front of me when a client asks where a new attribute should go.
| Store | Type system | Hard limit | Best for | Main failure mode |
|---|---|---|---|---|
| Shopify customer tag | None, plain string | Query returns up to 250 tags at a time | Coarse manual flags a human reads | No value, no type, collides on free text |
| Shopify metafield | Typed, 30+ data types | 256 definitions per resource, 64KB value | Durable storefront-facing attributes | Not real-time from Klaviyo, type mismatch on write |
| Klaviyo profile property | Loosely typed JSON | 100KB per property | ESP-only personalization and segments | Rename creates a new property, name collides with events |
| Warehouse column | Strong SQL types | Practically unbounded | Attributes computed from joined sources | Sync latency, no native storefront read |
When do customer tags stop scaling?
Tags stop scaling the moment an attribute needs a value rather than a yes or no. A tag is a bare string with no type, no numeric comparison, and no history. You can tag someone vip, but you cannot tag them a loyalty balance you later filter as greater than 500 without inventing brittle string conventions like points_500_999.
Tags also spread through free text. Two integrations writing VIP and vip produce two logical cohorts that no one reconciles. Shopify's own customer segmentation documentation treats tags as one filter among many precisely because they carry no structure to reason about.
Use tags for coarse, human-authored flags a support agent reads at a glance. The moment a value, a threshold, or a machine writes the attribute, move it to a metafield.
When is a Shopify metafield the right home?
A metafield is right when the attribute is durable, typed, and needs to be read by the storefront as well as the ESP. Metafields have a real type system covering more than thirty metafield data types, from number_integer to date to json, so a loyalty tier or a next-refill date keeps its type through every read.
The ceilings are generous but real. Shopify's metafield limits allow each app to create up to 256 metafield definitions per resource type and the merchant another 256, with a 64KB value size on most types and 128KB on JSON. That is far more than any sane customer schema needs, so the constraint is rarely the count. The constraint is discipline: an undefined metafield does not appear as a segment filter, so every attribute you want to segment on has to have a metafield definition, not just a raw value.
Metafields also earn their place because Shopify Flow, checkout, and theme code can all read them. If the same VIP tier drives a shipping rule and an email, a metafield is the one home that serves both.
When should the value live only in Klaviyo?
Keep an attribute in Klaviyo alone when it exists purely for messaging and nothing on the storefront needs it. A last-email-clicked category, an engagement band, or a per-profile send-time preference has no reason to round-trip to Shopify.
Klaviyo profile properties are loosely typed and forgiving, but two behaviors bite operators. First, the profile properties reference notes that editing a property after creation generates an entirely new property rather than renaming the original, so a typo in a property name is permanent schema debt you clean up by hand. Second, a profile property that shares a name with an event property makes the event undetectable in segment and flow dropdowns, which quietly disables filters you thought were live.
This is also where computed native properties live well. Klaviyo's predictive analytics write values like predicted lifetime value straight onto the profile, and those belong in Klaviyo because Klaviyo computes them. When those predictions look wrong, the fix is upstream of segmentation, which I cover in when Klaviyo predicted CLV is wrong about your store.
When does the warehouse have to be the source of truth?
The warehouse wins when the attribute is computed from data that neither Shopify nor Klaviyo fully owns. A true customer lifetime value that blends Shopify orders, refunds, wholesale invoices, and support cost cannot be trusted if any single tool computes it from its partial view.
In that case you model the attribute once in SQL and push it out. Reverse ETL tools read the warehouse and write the result to both platforms; Census, for example, offers a native Klaviyo reverse ETL integration that syncs warehouse-defined audiences and attributes onto profiles. The warehouse stays authoritative and every downstream tool receives the same number.
The trap here is letting the ESP quietly become the source of truth because the warehouse model is not trusted. If the segment logic in Klaviyo disagrees with the warehouse, fix the model, do not fork the definition into the tool that happens to send the email.
How do you keep a two-way sync from corrupting values?
Two-way sync corrupts data when both sides can write the same field and neither owns it. The single most common stuck-attribute case is a type mismatch. Klaviyo's guide to syncing data back to Shopify states plainly that if you push a custom property whose data type differs from the existing Shopify metafield definition, for example a string against an array, the metafield will not update at all. No error surfaces in the flow; the value just stays stale.
The same document notes the sync is not instant. Custom properties reflect in Shopify within 30 minutes of a change in Klaviyo, usually within a minute, which means any storefront logic that assumes real-time parity will read an old value during the window.
The rule that prevents this: give every synced attribute exactly one writer. Decide whether Shopify or the warehouse owns the value, let that system write, and let every other tool read a mirror. A field with two writers and no owner is the field that ends up wrong in production.
What are the trade-offs worth watching?
The honest tension is between reach and control. The warehouse gives you the cleanest definition and the worst latency. Klaviyo gives you instant use in a flow and the weakest schema guarantees. Metafields sit in the middle and pay for it with a sync delay from the ESP.
Three things I watch on every account. Watch for attributes with two writers, because that is where silent corruption starts. Watch for property-name collisions between profile and event data in Klaviyo, because they disable filters without warning. And watch the direction of truth for anything computed: if the number is assembled from more than one system, the assembling system owns it, and everything else reads a copy.
One more practical note on where behavioral data originates. Segmentation on real-time actions depends on events arriving intact, and the gaps there are their own problem, which I unpack in Shopify webhooks versus Klaviyo event tracking blind spots.