Skip to main content

Dynamic complexity cost for metafieldsSet mutation

The 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 api points, regardless of how many metafields or resources it touched.

Now the cost is calculated as follows:

Cost = base cost (10) + the sum of the costs for each distinct resource owner type in your mutation.

For each distinct resource owner type, the cost is (the number of distinct resources of that type * weight of that owner type)

Owner typeWeight
Order10
Product4
ProductVariant2
Collection1
Customer (including CustomerSegmentMember)1
Shop1
All other owner types0

Each owner is counted only 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 resources of type Order, plus the ten-point base cost).


Note

Cost is calculated per metafieldsSet invocation, not per request. If you use GraphQL aliases to send multiple metafieldsSet 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 3 × (10 + 25 × 10).


Example

This request writes to two products and one variant:

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.

RequestPrevious costNew cost
5 metafields on 1 product1014
1 metafield each on 2 products and 1 variant1020
25 metafields across 25 metaobjects1010
1 metafield each on 25 orders10260

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 varying background work. That work scales with the number of distinct 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 put excessive pressure on system infrastructure, slowing metafield writes and other API traffic for every app and store sharing that infrastructure.

Pricing by distinct resource reconciles an app's point spend with the work its requests actually cause.

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: Read the extensions.cost field in the response. Send the Shopify-GraphQL-Cost-Debug=1 header for a per-field breakdown.
  4. Handle throttling: Back off and retry when THROTTLED is returned.

Related docs

Was this page helpful?