Optimize Shopify app costs through plan selection, API usage monitoring, and Shopify Plus upgrade analysis. Use when analyzing API spend, choosing between Shopify plans, or reducing billable API calls. Trigger with phrases like "shopify cost", "shopify billing", "shopify pricing", "shopify Plus worth it", "shopify API usage", "reduce shopify costs".
Optimize Shopify app and API costs through plan analysis, API usage monitoring, and strategies to minimize billable API calls. Covers Shopify store plans, Partner app billing, and API efficiency.
API rate limits are determined by the merchant's plan, not your app:
| Merchant Plan | REST Bucket | REST Leak Rate | GraphQL Points | GraphQL Restore |
|---|---|---|---|---|
| Basic Shopify | 40 requests | 2/second | 1,000 points | 50/second |
| Shopify |
| 40 requests |
| 2/second |
| 1,000 points |
| 50/second |
| Advanced | 40 requests | 2/second | 1,000 points | 50/second |
| Shopify Plus | 80 requests | 4/second | 2,000 points | 100/second |
Key insight: Upgrading from Basic to Advanced doesn't help rate limits. Only Plus doubles them.
If your app charges merchants, use the GraphQL appSubscriptionCreate mutation to create recurring charges. Set test: true in development to avoid real billing.
See App Billing API for the complete mutation and variable setup.
Track GraphQL query costs and REST call counts over time to identify optimization opportunities. Log extensions.cost.actualQueryCost from every GraphQL response.
See Usage Tracker Class for a complete tracking implementation with reporting.
Four key strategies: replace REST with GraphQL for targeted field selection, use bulk operations for exports, cache responses and invalidate via webhooks, and use Storefront API for public data.
See Cost Reduction Strategies for code examples of each approach.
| Issue | Cause | Solution |
|---|---|---|
| Frequent throttling | High query cost | Reduce fields, use bulk ops |
| High hosting costs | Too many API calls | Cache responses, use webhooks |
| App billing rejection | Test mode not set | Use test: true in development |
| Merchant cancels | Unexpected charges | Clear billing in app onboarding |
// After every GraphQL call, log the cost
const response = await client.request(query);
const cost = response.extensions?.cost;
if (cost) {
console.log(
`Query cost: ${cost.actualQueryCost}/${cost.throttleStatus.maximumAvailable} ` +
`(${cost.throttleStatus.currentlyAvailable} available)`
);
}