resilience-engineering
Resilience Engineering for Shopify Apps
Shopify's API limit is a "Leaky Bucket". If you pour too much too fast, it overflows (429 Too Many Requests). Your app must handle this gracefully.
1. Handling Rate Limits (429)
The "Retry-After" Header
When Shopify returns a 429, they include a Retry-After header (seconds to wait).
Implementation (using bottleneck or custom delay):
async function fetchWithRetry(url, options, retries = 3) {
try {
const res = await fetch(url, options);
if (res.status === 429) {
const wait = parseFloat(res.headers.get("Retry-After") || "1.0");
if (retries > 0) {
await new Promise(r => setTimeout(r, wait * 1000));
return fetchWithRetry(url, options, retries - 1);
}
}
return res;
} catch (err) {
// network error handling
}
}
Note: The official @shopify/shopify-api client handles retries automatically if configured.
2. Queues & Throttling
For bulk operations (e.g., syncing 10,000 products), you cannot just loop and await.
Using bottleneck
npm install bottleneck
import Bottleneck from "bottleneck";
const limiter = new Bottleneck({
minTime: 500, // wait 500ms between requests (2 req/sec)
maxConcurrent: 5,
});
const products = await limiter.schedule(() => shopify.rest.Product.list({ ... }));
Background Jobs (BullMQ)
Move heavy lifting to a background worker. (See redis-bullmq skill - to be added if needed, but conceptually here).
3. Circuit Breaker
If an external service (e.g., your own backend API or a shipping carrier) goes down, stop calling it to prevent cascading failures.
Using cockatiel
npm install cockatiel
import { CircuitBreaker, handleAll, retry } from 'cockatiel';
// Create a Retry Policy
const retryPolicy = retry(handleAll, { maxAttempts: 3, backoff: new ExponentialBackoff() });
// Create a Circuit Breaker (open after 5 failures, reset after 10s)
const circuitBreaker = new CircuitBreaker(handleAll, {
halfOpenAfter: 10 * 1000,
breaker: new ConsecutiveBreaker(5),
});
// Execute
const result = await retryPolicy.execute(() =>
circuitBreaker.execute(() => fetchMyService())
);
4. Webhook Idempotency
Shopify guarantees "at least once" delivery. You might receive the same orders/create webhook twice.
Fix: Store X-Shopify-Webhook-Id in Redis/DB with a short TTL (e.g., 24h). If it exists, ignore the request.
More from toilahuongg/google-antigravity-kit
shopify-liquid
Guide for using the Liquid template language within Shopify Theme App Extensions and Themes. Use this skill when building App Embed Blocks, App Blocks, or modifying Shopify Themes.
50shopify-polaris-design
Design and implement Shopify Admin interfaces using the Polaris Design System. Use this skill when building Shopify Apps, Admin extensions, or any interface that needs to feel native to Shopify.
47docusaurus-generator
Generate end-user documentation site using Docusaurus 3.x from the current project. Use this skill when the user asks to create documentation, generate docs, build a docs site, or set up Docusaurus for their project. Supports analyzing project structure, generating markdown docs, configuring Docusaurus, and creating user guides.
31shopify-remix-template
Guide for developing Shopify apps using the official Shopify Remix Template. Covers structure, authentication, API usage, and deployment.
19remotion-best-practices
Best practices for Remotion - Video creation in React
18remixjs-best-practices
Best practices for Remix (2025-2026 Edition), focusing on React Router v7 migration, server-first data patterns, and error handling.
15