toilahuongg/shopify-agents-kit

resilience-engineering

Strategies for handling Shopify API Rate Limits (429), retry policies, and circuit breakers. Essential for high-traffic apps.

First seen Mar 3, 2026

Installation

$ npx skills add toilahuongg/shopify-agents-kit --skill resilience-engineering

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from toilahuongg/shopify-agents-kit · top by installs.

npx skills add toilahuongg/shopify-agents-kit

Browse all from toilahuongg/shopify-agents-kit

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 10
License LICENSE
Default branch master
Open issues 0
Status Active

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 2,667 B
  • docs SUMMARY.md 155 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 7 installs

SKILL.md

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.