resilience-engineering
Original:🇺🇸 English
Translated
Strategies for handling Shopify API Rate Limits (429), retry policies, and circuit breakers. Essential for high-traffic apps.
2installs
Added on
NPX Install
npx skill4agent add toilahuongg/shopify-agents-kit resilience-engineeringTags
Translated version includes tags in frontmatterSKILL.md Content
View Translation Comparison →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 header (seconds to wait).
Retry-AfterImplementation (using or custom delay):
bottlenecktypescript
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 client handles retries automatically if configured.
@shopify/shopify-api2. Queues & Throttling
For bulk operations (e.g., syncing 10,000 products), you cannot just loop and await.
Using bottleneck
bottleneckbash
npm install bottlenecktypescript
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 skill - to be added if needed, but conceptually here).
redis-bullmq3. 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
cockatielbash
npm install cockatieltypescript
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 webhook twice.
Fix: Store in Redis/DB with a short TTL (e.g., 24h). If it exists, ignore the request.
orders/createX-Shopify-Webhook-Id