All articles
E-commerceJuly 14, 2026 6 min read

Shopify Metaobjects at Scale: When They Save You and When They Wreck Your Admin

Metaobjects promised structured content without a headless CMS. Two years in, here's where they hold up on real Shopify stores — and where they quietly become an admin nightmare.

Shopify Metaobjects at Scale: When They Save You and When They Wreck Your Admin

Shopify metaobjects were sold as the answer to "we need a CMS but don't want to bolt on Contentful." For a lot of stores that's true. For others — usually the ones with big merchandising teams or a headless storefront — metaobjects quietly become the thing everyone complains about on Monday morning.

This is a breakdown from building and inheriting a handful of stores that lean heavily on metaobjects, including two headless Hydrogen builds and a Liquid theme with ~40 metaobject definitions. Where they earn their keep, where they don't, and the patterns that keep the admin usable past year one.

What metaobjects actually are (and aren't)

Metaobjects are Shopify's way of letting you define custom content types — think "Author", "Size Guide", "Store Location", "FAQ Entry" — with typed fields, references, and validation. They live alongside products and collections, they're queryable via the Storefront API, and they render in Liquid via the metaobject drop.

What they are not: a general-purpose CMS. There's no versioning, no draft/publish workflow beyond a basic status field, no rich editorial preview, no localization workflow that competes with a real headless CMS, and the admin UI is functional rather than pleasant.

That gap between "structured content store" and "editorial CMS" is where most of the pain shows up.

The good case for metaobjects

Metaobjects shine when:

  • The content model is stable and mostly shaped by developers, not marketers.
  • Editors need to reference entries from products or the theme, not compose long-form pages.
  • You want the data available in Liquid and the Storefront API without running a second service.
  • The volume is bounded — dozens to low thousands of entries, not tens of thousands.

Examples where we've been happy: store locators, size charts, ingredient glossaries, shipping-zone copy, author bios, structured badge/label systems, brand pages that map 1:1 to a supplier.

Where metaobjects start to hurt

The cracks appear in three predictable places.

1. The admin UI does not scale past ~20 definitions

Shopify admin lists metaobject definitions in a flat sidebar. There's no grouping, no folders, no favorites. Once you cross about 20 definitions, editors lose the mental map. We had a client at 34 definitions where the merchandising team maintained a Notion doc just to remember which metaobject controlled which surface.

The entry list within a definition is similarly thin: basic filtering by field, no saved views per user, no bulk edit that meaningfully rivals a spreadsheet. If your team is used to Contentful or Sanity, brace them.

2. References get expensive fast on headless

On a Liquid theme, metaobject lookups are cheap and cached. On a headless Hydrogen or Next.js Commerce build, every referenced metaobject is another node in your Storefront API query, and the depth limits bite sooner than you'd expect.

A product with a ingredient_list metafield that references six ingredient metaobjects, each of which references an allergen metaobject, is a real query we shipped. It looked like this before we refactored:

query ProductPDP($handle: String!) {
  product(handle: $handle) {
    id
    title
    ingredients: metafield(namespace: "custom", key: "ingredients") {
      references(first: 20) {
        nodes {
          ... on Metaobject {
            fields {
              key
              value
              reference {
                ... on Metaobject {
                  fields { key value }
                }
              }
            }
          }
        }
      }
    }
  }
}

That query worked. It was also 900ms p50 against the Storefront API from a European edge, which torched our PDP performance budget. We ended up denormalizing — storing the allergen labels directly on the ingredient metaobject as a comma-separated field — because the storefront didn't need the join, only the merchandising team did.

That's the tradeoff nobody tells you: metaobjects encourage normalization, but the Storefront API punishes it.

3. Migrations are manual and lossy

Renaming a field on a metaobject definition is fine. Changing a field's type is not — you get to create a new field, migrate values via the Admin API, and delete the old one, all while entries are live. There's no schema migration tool comparable to what you'd get from a proper CMS or a database ORM.

We now treat metaobject definitions as production infrastructure: changes go through a migration script checked into the repo, not through the admin UI. More on that below.

The rules we use now

After enough scars, here's the playbook we apply on new Shopify builds.

Rule 1: Metaobjects are for referenced data, not pages

If editors want to compose a page — hero, then feature grid, then testimonial carousel, then FAQ — that's a job for Shopify's native sections/blocks in the theme editor, or for a real headless CMS if you're on Hydrogen. Trying to model "page" as a metaobject with a repeatable "section" reference works technically and feels awful editorially.

We reserve metaobjects for entities: things that exist independently and get referenced from multiple places. An author is an entity. A homepage hero is not.

Rule 2: Cap definitions, and namespace them

We try to stay under 15 metaobject definitions on any single store. If we're heading higher, that's a signal the content model is wrong — usually too many near-duplicate types that should be one type with a variant field.

We also prefix definition names by domain: catalog.brand, catalog.ingredient, store.location, editorial.author. The admin doesn't group them, but at least sorting alphabetically produces a coherent order.

Rule 3: Definitions live in code

Every metaobject definition on a production store is defined in a TypeScript file and applied via the Admin GraphQL API in CI. Something like:

export const brandDefinition = {
  type: 'catalog_brand',
  name: 'Brand',
  fieldDefinitions: [
    { key: 'name', type: 'single_line_text_field', required: true },
    { key: 'slug', type: 'single_line_text_field', required: true },
    { key: 'logo', type: 'file_reference' },
    { key: 'description', type: 'multi_line_text_field' },
    { key: 'country', type: 'single_line_text_field' },
  ],
};

The migration runner diffs the current definition against the target and issues metaobjectDefinitionUpdate mutations. This gives us reviewable schema changes, environment parity between staging and production, and — critically — a paper trail when a merchandiser asks "why did that field disappear."

Rule 4: Denormalize for the storefront, normalize for the admin

When a piece of data will be read on a hot path (PDP, PLP, cart), we store a denormalized copy directly on the referring metaobject or product metafield. The canonical record still lives in its own metaobject for editors, but the storefront reads a flattened field.

We sync the two with a Shopify Flow or a small worker that listens for metaobjects/update webhooks and rewrites the denormalized fields. Yes, it's extra plumbing. It's also the difference between a 200ms and an 800ms PDP.

Rule 5: Draft states need discipline

Metaobject entries have a status field (ACTIVE / DRAFT) but no editorial workflow around it. If your team needs "proposed changes," "scheduled publish," or "approval," build it explicitly — usually by cloning the entry, letting editors work on the clone, and swapping references on publish. Don't pretend the built-in status is a workflow.

When to pick something else

Metaobjects are the wrong tool if any of these are true:

  • Your editorial team is bigger than your dev team and lives in the CMS all day.
  • You need real localization workflows (translator handoff, side-by-side diff, per-locale publish).
  • You're modelling more than ~20 distinct content types.
  • You need previewable drafts on a headless storefront with the full context of the page.

At that point, run a proper headless CMS alongside Shopify — Sanity, Contentful, or Storyblok — and use metafields only to hold the reference ID that ties a product to its CMS entry. You lose the single-pane-of-glass admin, but you gain an editing experience that doesn't cost you a merchandiser every quarter. We've written more about how we structure those headless commerce builds when the content demands push past Shopify's native tooling.

Where we'd start

If you're greenfield on Shopify in 2026, start with metaobjects. Model your entities, keep the definition count low, put the schema in code from day one, and set a hard rule that pages are not metaobjects. Revisit at the six-month mark: if the admin has grown past 15 definitions and merchandisers are complaining, that's your cue to pull editorial content into a dedicated CMS before the mess sets in — not after.

#Shopify#Headless Commerce#CMS#Architecture

Want a team like ours?

72Technologies builds production software for the kind of teams who actually read this blog.

Start a project