The 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 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 type | Weight |
|---|---|
Order | 10 |
Product | 4 |
| 2 |
Collection | 1 |
Customer (including ) | 1 |
Shop | 1 |
| All other owner types | 0 |
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 accepts at most 25 metafields per mutation, the highest possible cost for a single invocation is 260 points (25 distinct resources of type Order, plus the ten-point base cost).
Cost is calculated per invocation, not per request. If you use GraphQL aliases to send multiple 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).
Cost is calculated per invocation, not per request. If you use GraphQL aliases to send multiple 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).
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/apps/build/graphql/basics/advanced#make-multiple-queries-in-one-request">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:
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 count once) and one distinct 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 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 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:
- 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.
- 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.
- Check the cost you were charged: Read the
extensions.costfield in the response. Send theheader for a per-field breakdown. - Handle throttling: Back off and retry when
THROTTLEDis returned.