Content model drift: why eleven brands end up with eleven different schemas

Tony Spiro
September 8, 2026
Nobody decides to run eleven different content models. It happens one launch at a time, and every individual decision along the way is reasonable.
Brand four needs to launch in three weeks. Copying brand two's content model means understanding brand two's content model, including the three fields nobody can explain and the one that is definitely unused but might not be. Starting fresh takes an afternoon. So somebody starts fresh.
Repeat that six more times. Two years later, nothing shares a field name, no query spans properties, and reporting across brands is a person with a spreadsheet.
This is content model drift. It is the most common structural problem in multi-brand content operations and the least discussed, because it never announces itself. There is no outage. There is just a slow rise in how long everything takes.
The four mechanics of drift
Drift is not one problem. It is four, and they compound in that order.
1. Naming drift
The same concept, different keys. This is the visible layer and the easiest to fix.
published_dateon three properties,publish_dateon two,dateon one,go_liveon the newesthero_imageversusfeatured_imageversusimageversusmain_imageauthoras a plain text field on the older properties and a relationship on the newer ones
Every cross-property function grows a mapping layer. The mapping layer becomes the only place the real schema is documented, and it lives in application code that nobody maintains deliberately.
2. Structural drift
The same concept, different shape. Harder to fix, because migration means transforming data rather than renaming a key.
One property stores SEO as two flat fields, seo_title and seo_description. Another nests them under a parent group. A third put the meta description inside a general-purpose JSON blob. A fourth has no SEO fields at all and derives everything from the title, which was fine until somebody asked why one brand never shows a proper description in search results.
3. Validation drift
The same field, different rules. Required on one property, optional on four. Max length 60 on the property whose developer read the SEO guidance, unlimited everywhere else.
This one is sneaky because it produces quality differences that look like people problems. One brand's editors always write good meta descriptions and another brand's never do. The usual explanation is discipline. The actual explanation is that one form required it and the other did not.
4. Semantic drift
The same name, different meaning. This is the expensive one, and it is the reason a cross-brand rollup can be wrong rather than merely incomplete.
A status field means editorial state on the media properties, draft or review or published, and product availability on the commerce property, in stock or discontinued. A featured boolean means homepage placement on one brand and newsletter inclusion on another. category is a free-text field on the oldest property and a relationship to a controlled taxonomy on the rest.
A query that filters on status across all properties returns a number. The number is meaningless, and nothing in the response tells you that.
Auditing your own drift in about an hour
You cannot fix drift you have not measured, and the measurement is genuinely quick. Pull the schema for every property and compare.
import { createBucketClient } from '@cosmicjs/sdk'; const properties = [ { name: 'Brand A', bucketSlug: 'brand-a', readKey: process.env.BRAND_A_READ_KEY! }, { name: 'Brand B', bucketSlug: 'brand-b', readKey: process.env.BRAND_B_READ_KEY! }, { name: 'Brand C', bucketSlug: 'brand-c', readKey: process.env.BRAND_C_READ_KEY! }, ]; for (const property of properties) { const cosmic = createBucketClient({ bucketSlug: property.bucketSlug, readKey: property.readKey, }); const { object_types } = await cosmic.objectTypes.find(); for (const type of object_types) { const fields = (type.metafields ?? []).map((field) => `${field.key}:${field.type}`); console.log(property.name, type.slug, fields.sort().join(', ')); } }
Dump that into a spreadsheet with one row per property and one column per field key. The drift becomes visually obvious in about five minutes: the gaps in the grid are your missing fields, and the near-duplicate column headers are your naming drift.
Then answer four questions:
- How many distinct names does your "publish date" concept have?
- Which fields exist on some properties and not others, and was that deliberate?
- Are there any fields with the same name and a different type across properties? Those are your semantic drift candidates.
- Which property has the model you would choose if you were starting today?
That last answer is your canonical model. You almost never need to design one from scratch.
The fix: a canonical core with local extensions
The instinct is to force every property onto one identical model. That fails, because brands genuinely differ. The commerce property really does need fields the editorial property does not.
What works is a two-layer model.
The canonical core is a small set of types and fields that are identical everywhere, no exceptions. Ten to fifteen fields is usually enough: title, slug, body, publish date, updated date, author relationship, category relationship, hero image, SEO title, SEO description. Same keys, same types, same validation rules, on every property. This layer is what makes cross-property queries, shared components, and org-wide reporting possible.
Local extensions are everything a specific property needs on top. The commerce brand adds pricing and inventory fields. The franchise sites add location and hours. The media property adds a bylines repeater. These live in the same types and nobody outside that property needs to know about them.
The discipline is one rule: nothing goes into the core without going into all of them, and nothing in the core is ever renamed locally. A new property starts by cloning the core, then adds what it needs.
Fixing existing drift without a rebuild
You do not have to migrate everything at once, and you should not.
- Write the core down. One document, one table, field key and type and validation rule. This step alone prevents the next launch from adding an eleventh variant.
- Pick the pilot. The smallest property that is still representative. Migrate it to the core and keep notes on what surprised you.
- Migrate additively. Add the canonical field alongside the legacy one, backfill it, run both in parallel, then cut reads over. No property goes dark.
- Do naming drift first. It is the cheapest fix and it unblocks cross-property queries immediately.
- Do semantic drift next, even though it is harder. Wrong numbers cost more than missing numbers.
- Leave local extensions alone. They are not the problem, and touching them turns a two-week project into a quarter.
Keeping it from coming back
Drift is a process failure, so the prevention is a process:
- A new property is created by cloning the canonical model, never by starting empty
- A field added to the core is added to every property in the same change
- Validation rules live in the schema, not in a style guide that editors are asked to remember
- Somebody owns the core. One person, named. Shared ownership of a schema means no ownership of a schema
- Re-run the audit script once a quarter and diff it against last quarter
The quarterly diff is the highest-value item on that list. Drift is slow, which is exactly why an annual review misses it and a quarterly diff catches it while it is still a rename.
The structural fix underneath
A canonical model is much easier to maintain when your properties live in one place administratively while staying isolated content-wise. That is the shape Cosmic Workspaces are built for: one Workspace, one Project per property, each with its own content, models, keys, and permissions, under one bill and one team.
Large Workspace covers 10 Projects, 30 Buckets, and 30 team members at $2,999/month. Small Workspace covers 5 Projects, 10 Buckets, and 10 team members at $999/month. Both include a 30-day free trial, which is enough time to build your canonical model once and clone it across properties before you pay anything.
- See the structure: cosmicjs.com/workspaces
- Start a free 30-day trial: app.cosmicjs.com/signup
- Bring your current field list and we will look at it with you: book 30 minutes with our CEO
For the wider architecture question of what to centralize and what to keep local, read the multi-property content stack.






