---
title: >-
  Dynamic complexity cost for metafieldsSet mutation - Shopify developer
  changelog
description: >-
  Shopify’s developer changelog documents all changes to Shopify’s platform.
  Find the latest news and learn about new platform opportunities.
source_url:
  html: >-
    https://shopify.dev/changelog/dynamic-complexity-cost-for-metafieldsset-mutation
  md: >-
    https://shopify.dev/changelog/dynamic-complexity-cost-for-metafieldsset-mutation.md
metadata:
  effectiveApiVersion: ''
  affectedApi:
    - displayName: Admin GraphQL API
      handle: admin-graphql
  primaryTag:
    displayName: API
    handle: api
  secondaryTag:
    displayName: Update
    handle: update
  indicatesActionRequired: false
  createdAt: '2026-09-14T14:28:16-04:00'
  postedAt: '2026-09-15T12:00:00-04:00'
  updatedAt: '2026-09-15T10:08:40-04:00'
  effectiveAt: '2026-09-15T12:00:00-04:00'
---

September 15, 2026

# Dynamic complexity cost for `metafieldsSet` mutation

DateSeptember 15, 2026

FlagsUpdate

SurfacesAPI

Affected APIs[Admin GraphQL API](https://shopify.dev/changelog?api_type=admin-graphql)

The [`metafieldsSet`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/metafieldsSet) mutation now uses dynamic complexity costing. Instead of a flat cost for every call, a request's cost reflects how many distinct resources metafields were changed. Most apps need no changes, as updating a single resource remains cheap. Apps setting many metafields across many different owners may hit their rate limit faster. Apps are encouraged to batch metafield writes by distinct resource.

## What changed

Previously, every `metafieldsSet` call cost a flat **10 points**, regardless of how many metafields or resources it touched.

Now the cost is:

```
cost = 10 + Σ (number of distinct owners of a type × that type's weight)
```

* **Base cost**: 10 points (unchanged)
* **Per distinct owner**: the weight of that owner's type

| Owner type | Weight |
| - | - |
| `Order` | 10 |
| `Product` | 4 |
| `ProductVariant` | 2 |
| `Collection` | 1 |
| `Customer` (including `CustomerSegmentMember`) | 1 |
| `Shop` | 1 |
| All other owner types | 0 |

Each owner is counted **once per mutation invocation**, however many metafields you set on it. Setting 10 metafields on one product costs the same as setting one.

Because `metafieldsSet` accepts at most 25 metafields per mutation, the highest possible cost for a single `metafieldsSet` invocation is **260 points** (25 distinct orders).

***

**Note:** Cost is calculated per \<code>\<span class="PreventFireFoxApplyingGapToWBR">metafields\<wbr/>Set\</span>\</code> invocation, not per request. If you use \<a href="https://shopify.dev/docs/api/usage/graphql-basics/queries#aliases">GraphQL aliases\</a> to send multiple \<code>\<span class="PreventFireFoxApplyingGapToWBR">metafields\<wbr/>Set\</span>\</code> mutations in a single request, the base cost of 10 is charged for each alias, and owners are not deduplicated across aliases. A request with three aliases updating the same 25 distinct orders costs 780 points \<code>3 × (10 + 25 × 10)\</code>.

***

#### Example

This request writes to two products and one variant:

```graphql
mutation {
  metafieldsSet(metafields: [
    { ownerId: "gid://shopify/Product/1", namespace: "custom", key: "a", type: "single_line_text_field", value: "a" },
    { ownerId: "gid://shopify/Product/1", namespace: "custom", key: "b", type: "single_line_text_field", value: "b" },
    { ownerId: "gid://shopify/Product/2", namespace: "custom", key: "a", type: "single_line_text_field", value: "c" },
    { ownerId: "gid://shopify/ProductVariant/9", namespace: "custom", key: "a", type: "single_line_text_field", value: "d" }
  ]) {
    metafields { key }
    userErrors { field message }
  }
}
```

It has two distinct `Product` owners (the two inputs for `Product/1` count once) and one distinct `ProductVariant` owner, so it costs `10 + (2 × 4) + (1 × 2)` = **20 points**.

| Request | Previous cost | New cost |
| - | - | - |
| 5 metafields on 1 product | 10 | 14 |
| 1 metafield each on 2 products and 1 variant | 10 | 20 |
| 25 metafields across 25 metaobjects | 10 | 10 |
| 1 metafield each on 25 orders | 10 | 260 |

## Who's affected

This change applies to any app that calls the `metafieldsSet` mutation in the Admin GraphQL API. Apps making high-volume, cross-owner requests (for example, updating 25 distinct orders in one request) will see an increase in query cost and may consume their API rate limit bucket faster. Apps updating single resources or using owner types with a weight of 0 will experience minimal changes to their API consumption.

## Why this matters

Setting a metafield isn't finished when the write returns. For every distinct resource whose metafields change, Shopify runs follow-up work in the background: webhooks, cache invalidation, search reindexing, and other per-owner processing. That work scales with the number of resources a request touches, not with the number of metafields it sets.

Under a flat cost, a request setting 25 metafields across 25 different products costs exactly the same as one setting a single metafield on a single product, even though it generated 25 times the downstream work. Bursts of high-fan-out `metafieldsSet` traffic have saturated the job queues and datastores behind metafields, slowing metafield writes and other API traffic for every app and store sharing that infrastructure.

Pricing by distinct resource lines an app's point spend up with the work its requests actually cause, and stops a single burst from degrading the platform for everyone.

## What to do

Most apps need no changes. A request that writes to a single resource, or to resources with a weight of 0, costs between 10 and 20 points.

If your app writes metafields at high volume, follow these optimization strategies:

1. **Group metafields by owner.** Additional metafields for the same resource are free, so setting all of one product's metafields in a single call is cheaper than one call per metafield.
2. **Don't split a high-fan-out call to reduce cost.** Every call pays the base 10 points, so splitting one request across 25 orders into 25 requests costs more in total, not less.
3. **Check the cost you were charged** from the `extensions.cost` field in the response. Send the `Shopify-GraphQL-Cost-Debug=1` header for a per-field breakdown.
4. **Handle throttling** by backing off and retrying when `THROTTLED` is returned.

## Related docs

* [GraphQL Admin API rate limits](https://shopify.dev/docs/api/usage/limits)
* [Manage metafields using the GraphQL Admin API](https://shopify.dev/docs/apps/build/metafields/manage-metafields)
* [Metafield limits](https://shopify.dev/docs/apps/build/metafields/metafield-limits)
