Agent skill

Customerio Reliability Patterns

by jeremylongshore in jeremylongshore/tons-of-skills-marketplace

Implement Customer.io reliability and fault-tolerance patterns.

MITAuto-check passedDevelopment

Install Customerio Reliability Patterns

skills CLI
$ npx skills add jeremylongshore/tons-of-skills-marketplace --skill customerio-reliability-patterns -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install jeremylongshore/tons-of-skills-marketplace customerio-reliability-patterns --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/jeremylongshore/tons-of-skills-marketplace.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/.curated/customerio-reliability-patterns .claude/skills/customerio-reliability-patterns && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
customerio-reliability-patterns
GitHub stars
2.8k
Token cost
~2.8k tokens
SKILL.md length
343 words
Files
3 (incl. references)
Skills in repo
3,342
Repo updated
First seen
Licence
MIT

At a glance

Implement Customer.io reliability and fault-tolerance patterns.

  • Building circuit breakers
  • SKILL.md covers Output, Error Handling, Examples and Overview, plus 6 more sections
  • Needs CUSTOMERIO_TRACK_API_KEY
  • Fallback queues

What it does

Customerio Reliability Patterns is an agent skill from jeremylongshore/tons-of-skills-marketplace. Implement Customer.io reliability and fault-tolerance patterns. Use when building circuit breakers, fallback queues, idempotency, or graceful degradation for Customer.io integrations. Trigger: "customer.io reliability", "customer.io resilience", "customer.io circuit breaker", "customer.io fault tolerance".

Its SKILL.md is about 2.8k tokens, which your agent loads only when the skill is triggered. The skill folder holds 3 other files, including reference files (for example `references/implementation-guide.md` and `references/implementation.md`). Compatibility notes: Designed for Claude Code

It sits in Development, covering Error handling. The repository describes itself as: Model-agnostic agent-skills platform with a harness-free canonical layer, verified adapters, and the ccpi package manager. Explore at tonsofskills.com. The licence is MIT.

When your agent uses it

  • Building circuit breakers
  • Fallback queues
  • Graceful degradation for Customer.io integrations

Example prompts

  • “customer.io reliability”
  • “customer.io resilience”
  • “customer.io circuit breaker”
  • “/customerio-reliability-patterns”

Requirements

  • A credential in CUSTOMERIO_TRACK_API_KEY
  • Compatibility (from SKILL.md): Designed for Claude Code
  • Pre-approved tools (allowed-tools): Read, Write, Edit, Bash(npm:*), Bash(npx:*), Glob, Grep

What it can do on your machine

Read from SKILL.md and the folder at commit 80f86df. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves these tools, so the agent can use them without asking each time:

    • Read
    • Write
    • Edit
    • Bash(npm:*)
    • Bash(npx:*)
    • Glob
    • Grep

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are typescript).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Links to these hosts (documentation or services it may open):

    • martinfowler.com
    • aws.amazon.com
    • bullmq.io

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • CUSTOMERIO_TRACK_API_KEY

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

  • Compatibility

    Designed for Claude Code

    From compatibility in the SKILL.md frontmatter.

Context cost

Customerio Reliability Patterns loads about 2.8k tokens when it runs, and up to ~5.8k if it reads all its reference files. Until then it costs about 85 tokens; SKILL.md has 343 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~85
When it runs · the whole SKILL.md, loaded when a task matches
~2.8k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~5.8k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from jeremylongshore/tons-of-skills-marketplace at commit 80f86df, republished under its MIT licence (© jeremylongshore). 343 words, ~2,756 tokens.

Download SKILL.mdSave it as .claude/skills/customerio-reliability-patterns/SKILL.md (or your agent's skills folder). This skill also uses 2 other files; get the full folder from GitHub.
name
customerio-reliability-patterns
description
Implement Customer.io reliability and fault-tolerance patterns. Use when building circuit breakers, fallback queues, idempotency, or graceful degradation for Customer.io integrations. Trigger: "customer.io reliability", "customer.io resilience", "customer.io circuit breaker", "customer.io fault tolerance".
allowed-tools
Read, Write, Edit, Bash(npm:*), Bash(npx:*), Glob, Grep
compatibility
Designed for Claude Code
version
1.14.0
license
MIT
author
Jeremy Longshore <jeremy@intentsolutions.io>
tags
saas, customer-io, reliability, circuit-breaker, resilience

Customer.io Reliability Patterns

Output

  • An idempotent, observable event-delivery design with owned retry, replay, and dead-letter decisions.
  • A recovery procedure that protects consent, ordering, and recipient experience during partial failures.

Error Handling

ConditionSafe response
Provider returns transient failureRetry with bounded exponential backoff and preserve the idempotency key.
Event may be duplicatedDeduplicate by the stable event/correlation key before triggering downstream action.
Replay could resend customer messagingRequire consent/segment review and replay only the scoped failed set.
Dead-letter queue growsAlert the owner, quarantine malformed payloads, and fix the contract before bulk replay.

Examples

Store an immutable event ID and delivery state, retry 429/5xx responses with bounded backoff, and send terminal failures to a protected dead-letter queue. After the schema fix, replay only those records whose consent and idempotency checks still pass.

Overview

Implement fault-tolerant Customer.io integrations: circuit breaker (stop cascading failures), retry with jitter (handle transient errors), fallback queue (survive outages), idempotency guard (prevent duplicates), and graceful degradation (never crash your app for analytics).

Prerequisites

  • Working Customer.io integration
  • Understanding of failure modes (429, 5xx, timeouts, DNS failures)
  • Redis (recommended for queue-based patterns)

Instructions

Pattern 1: Circuit Breaker
typescript
// lib/circuit-breaker.ts
type CircuitState = "CLOSED" | "OPEN" | "HALF_OPEN";

export class CircuitBreaker {
  private state: CircuitState = "CLOSED";
  private failureCount = 0;
  private successCount = 0;
  private lastFailureTime = 0;

  constructor(
    private readonly failureThreshold: number = 5,
    private readonly successThreshold: number = 3,
    private readonly resetTimeoutMs: number = 30000
  ) {}

  get currentState(): CircuitState {
    if (this.state === "OPEN") {
      // Check if enough time has passed to try again
      if (Date.now() - this.lastFailureTime > this.resetTimeoutMs) {
        this.state = "HALF_OPEN";
        this.successCount = 0;
      }
    }
    return this.state;
  }

  async execute<T>(fn: () => Promise<T>): Promise<T> {
    if (this.currentState === "OPEN") {
      throw new Error("Circuit breaker is OPEN — Customer.io calls blocked");
    }

    try {
      const result = await fn();
      this.onSuccess();
      return result;
    } catch (err) {
      this.onFailure();
      throw err;
    }
  }

  private onSuccess(): void {
    this.failureCount = 0;
    if (this.state === "HALF_OPEN") {
      this.successCount++;
      if (this.successCount >= this.successThreshold) {
        this.state = "CLOSED";
        console.log("Circuit breaker: CLOSED (recovered)");
      }
    }
  }

  private onFailure(): void {
    this.failureCount++;
    this.lastFailureTime = Date.now();
    if (this.failureCount >= this.failureThreshold) {
      this.state = "OPEN";
      console.warn(
        `Circuit breaker: OPEN (${this.failureCount} failures). ` +
        `Will retry in ${this.resetTimeoutMs / 1000}s`
      );
    }
  }

  getStatus(): { state: CircuitState; failures: number; lastFailure: Date | null } {
    return {
      state: this.currentState,
      failures: this.failureCount,
      lastFailure: this.lastFailureTime ? new Date(this.lastFailureTime) : null,
    };
  }
}
Pattern 2: Retry with Jitter
typescript
// lib/retry.ts
export async function retryWithJitter<T>(
  fn: () => Promise<T>,
  maxRetries = 3,
  baseDelayMs = 1000
): Promise<T> {
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    try {
      return await fn();
    } catch (err: any) {
      const status = err.statusCode ?? err.status;

      // Don't retry client errors (except 429)
      if (status >= 400 && status < 500 && status !== 429) throw err;

      if (attempt === maxRetries) throw err;

      // Exponential backoff: 1s, 2s, 4s + random jitter up to 30%
      const delay = baseDelayMs * Math.pow(2, attempt);
      const jitter = delay * 0.3 * Math.random();
      await new Promise((r) => setTimeout(r, delay + jitter));
    }
  }
  throw new Error("Unreachable");
}
Pattern 3: Fallback Queue
typescript
// lib/customerio-fallback.ts
import { Queue, Worker } from "bullmq";
import { TrackClient, RegionUS } from "customerio-node";

const REDIS_URL = process.env.REDIS_URL ?? "redis://localhost:6379";

// Queue for operations that fail when circuit breaker is open
const fallbackQueue = new Queue("cio:fallback", {
  connection: { url: REDIS_URL },
  defaultJobOptions: {
    attempts: 10,
    backoff: { type: "exponential", delay: 60000 }, // Start at 1 min
    removeOnComplete: 1000,
    removeOnFail: 5000,
  },
});

export async function enqueueFallback(
  operation: "identify" | "track" | "suppress",
  data: Record<string, any>
): Promise<void> {
  await fallbackQueue.add(operation, data);
  console.log(`CIO fallback: queued ${operation} (circuit open)`);
}

// Worker processes fallback queue when CIO is back up
export function startFallbackWorker(): void {
  const cio = new TrackClient(
    process.env.CUSTOMERIO_SITE_ID!,
    process.env.CUSTOMERIO_TRACK_API_KEY!,
    { region: RegionUS }
  );

  new Worker("cio:fallback", async (job) => {
    switch (job.name) {
      case "identify":
        await cio.identify(job.data.userId, job.data.attrs);
        break;
      case "track":
        await cio.track(job.data.userId, job.data.event);
        break;
      case "suppress":
        await cio.suppress(job.data.userId);
        break;
    }
  }, {
    connection: { url: REDIS_URL },
    concurrency: 5,
  });
}
Pattern 4: Resilient Client (All Patterns Combined)
typescript
// lib/customerio-resilient.ts
import { TrackClient, RegionUS } from "customerio-node";
import { CircuitBreaker } from "./circuit-breaker";
import { retryWithJitter } from "./retry";
import { enqueueFallback } from "./customerio-fallback";

export class ResilientCioClient {
  private client: TrackClient;
  private breaker: CircuitBreaker;

  constructor(siteId: string, apiKey: string) {
    this.client = new TrackClient(siteId, apiKey, { region: RegionUS });
    this.breaker = new CircuitBreaker(5, 3, 30000);
  }

  async identify(userId: string, attrs: Record<string, any>): Promise<void> {
    try {
      await this.breaker.execute(() =>
        retryWithJitter(() => this.client.identify(userId, attrs))
      );
    } catch (err: any) {
      if (err.message.includes("Circuit breaker is OPEN")) {
        await enqueueFallback("identify", { userId, attrs });
        return; // Queued for later — don't throw
      }
      // For non-circuit errors, log but don't crash the app
      console.error(`CIO identify failed for ${userId}: ${err.message}`);
    }
  }

  async track(
    userId: string,
    name: string,
    data?: Record<string, any>
  ): Promise<void> {
    try {
      await this.breaker.execute(() =>
        retryWithJitter(() =>
          this.client.track(userId, { name, data })
        )
      );
    } catch (err: any) {
      if (err.message.includes("Circuit breaker is OPEN")) {
        await enqueueFallback("track", { userId, event: { name, data } });
        return;
      }
      console.error(`CIO track failed for ${userId}/${name}: ${err.message}`);
    }
  }

  getHealthStatus() {
    return this.breaker.getStatus();
  }
}
Pattern 5: Idempotency Guard
typescript
// lib/idempotency.ts
import { createHash } from "crypto";

const processedOps = new Map<string, number>();
const MAX_ENTRIES = 100_000;
const TTL_MS = 5 * 60 * 1000;  // 5 minutes

export function isIdempotent(
  operation: string,
  userId: string,
  data: any
): boolean {
  const hash = createHash("sha256")
    .update(`${operation}:${userId}:${JSON.stringify(data)}`)
    .digest("hex")
    .substring(0, 16);

  const existing = processedOps.get(hash);
  if (existing && Date.now() - existing < TTL_MS) {
    return true; // Already processed within TTL
  }

  processedOps.set(hash, Date.now());

  // Prune old entries
  if (processedOps.size > MAX_ENTRIES) {
    const cutoff = Date.now() - TTL_MS;
    for (const [key, time] of processedOps) {
      if (time < cutoff) processedOps.delete(key);
    }
  }

  return false;
}
Pattern 6: Health Check Endpoint
typescript
// routes/health.ts — include circuit breaker status
import { ResilientCioClient } from "../lib/customerio-resilient";

const cio = new ResilientCioClient(
  process.env.CUSTOMERIO_SITE_ID!,
  process.env.CUSTOMERIO_TRACK_API_KEY!
);

app.get("/health/customerio", (_req, res) => {
  const status = cio.getHealthStatus();
  const healthy = status.state === "CLOSED";

  res.status(healthy ? 200 : 503).json({
    customerio: {
      circuit_state: status.state,
      failure_count: status.failures,
      last_failure: status.lastFailure?.toISOString() ?? null,
    },
  });
});

Pattern Selection Guide

ScenarioPatternPriority
Transient 5xx errorsRetry with jitterMust have
Extended Customer.io outageCircuit breaker + fallback queueMust have
Duplicate events from retriesIdempotency guardShould have
App must never crash for trackingGraceful degradation (catch all)Must have
Need visibility into reliabilityHealth check endpointShould have

Reliability Checklist

  • Circuit breaker implemented with reasonable thresholds
  • Retry with exponential backoff and jitter
  • Fallback queue for circuit-open operations
  • Idempotency guard for retried operations
  • All Customer.io calls wrapped in try/catch (never crash the app)
  • Health check exposes circuit breaker state
  • Graceful shutdown drains queues and flushes buffers
  • Timeout configured on HTTP calls

Resources

Next Steps

After reliability patterns, proceed to customerio-load-scale for load testing and scaling.

© jeremylongshore, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 2 other files (references) in skills/.curated/customerio-reliability-patterns of jeremylongshore/tons-of-skills-marketplace.

  • SKILL.md
  • references/implementation-guide.md
  • references/implementation.md

Open the folder on GitHubat commit 80f86df

Compare with similar skills

Customerio Reliability Patterns next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Customerio Reliability Patterns compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Customerio Reliability Patterns this skilljeremylongshore/tons-of-skills-marketplace2.8k—~2.8kAutomated safety check: PassMIT
Error HandlingCloudAI-X/claude-workflow-v21.4k—~3.4kAutomated safety check: PassMIT
Review Hog Perspective Performance ReliabilityPostHog/posthog40k—~1kAutomated safety check: PassCustom licence
Mole Bug Patternstw93/Mole70k—~2kAutomated safety check: PassGPL-3.0
Native Data FetchingCherryHQ/cherry-studio-app4k6 repos~2.9kAutomated safety check: NotesMIT
Rust Best Practicesfarm-fe/farm5.6k3 repos~1.1kAutomated safety check: PassMIT

Similar skills

  • Error Handling

    CloudAI-X/claude-workflow-v2

    Implements error handling patterns, structured logging, retry strategies, circuit breakers, and graceful degradation.

    1.4k GitHub stars~3.4k tokensUpdated 3 days ago
    DevelopmentAuto-check passed
  • A catalog of recurring bug shapes in the Mole Mac cleaner, used to review safety-sensitive diffs for deletion safety, unbounded commands, shell traps and weak tests.

    70k GitHub stars~2k tokensUpdated yesterday
    DevelopmentAuto-check passed
  • Native Data Fetching

    CherryHQ/cherry-studio-app

    A skill your agent uses when implementing or debugging ANY network request, API call, or data fetching.

    4k GitHub starsUsed in 6 repos~2.9k tokens
    DevelopmentAuto-check: notes
  • Guide for writing idiomatic Rust code based on Apollo GraphQL's best practices handbook.

    5.6k GitHub starsUsed in 3 repos~1.1k tokens
    DevelopmentAuto-check passed
  • Validates arguments of exported R functions with the standalone check_* type checkers from rlang, in tidyverse style with clear error messages.

    5.1k GitHub starsUsed in 1 repo~2.3k tokens
    DevelopmentAuto-check passed

More from jeremylongshore/tons-of-skills-marketplace

All 3,342 skills in this repo
  • Performing Security Code Review

    jeremylongshore/tons-of-skills-marketplace

    Execute this skill enables AI assistant to conduct a security-focused code review using the security-agent plugin.

    2.8k GitHub starsUsed in 2 repos~1.3k tokens
    Auto-check: notes
  • Adapting Transfer Learning Models

    jeremylongshore/tons-of-skills-marketplace

    Build this skill automates the adaptation of pre-trained machine learning models using transfer learning techniques.

    2.8k GitHub stars~1.1k tokensUpdated yesterday
    Auto-check passed
  • Agent Context Loader

    jeremylongshore/tons-of-skills-marketplace

    Execute proactive auto-loading: automatically detects and loads agents.md files.

    2.8k GitHub stars~1.1k tokensUpdated yesterday
    Auto-check passed
  • Aggregating Performance Metrics

    jeremylongshore/tons-of-skills-marketplace

    Aggregate and centralize performance metrics from applications, systems, databases, caches, and services.

    2.8k GitHub stars~1.2k tokensUpdated yesterday
    Auto-check passed
  • Analyzing Capacity Planning

    jeremylongshore/tons-of-skills-marketplace

    Execute this skill enables AI assistant to analyze capacity requirements and plan for future growth.

    2.8k GitHub stars~947 tokensUpdated yesterday
    Auto-check passed
  • Analyzing Database Indexes

    jeremylongshore/tons-of-skills-marketplace

    Process use when you need to work with database indexing. An agent skill from jeremylongshore/tons-of-skills-marketplace.

    2.8k GitHub stars~2k tokensUpdated yesterday
    Auto-check passed

Questions about Customerio Reliability Patterns

What does Customerio Reliability Patterns do?

Implement Customer.io reliability and fault-tolerance patterns. Customerio Reliability Patterns is an agent skill from jeremylongshore/tons-of-skills-marketplace.io reliability and fault-tolerance patterns.

When should I use Customerio Reliability Patterns?

Customerio Reliability Patterns fits situations like: building circuit breakers; fallback queues; graceful degradation for Customer.io integrations.

How do I install Customerio Reliability Patterns in Claude Code?

Run `npx skills add jeremylongshore/tons-of-skills-marketplace --skill customerio-reliability-patterns -a claude-code`. Or copy the skill folder (skills/.curated/customerio-reliability-patterns in jeremylongshore/tons-of-skills-marketplace) into .claude/skills/customerio-reliability-patterns in your project. Claude Code loads it when a task matches its description.

How do I install Customerio Reliability Patterns in Codex?

Run `npx skills add jeremylongshore/tons-of-skills-marketplace --skill customerio-reliability-patterns -a codex`. Or copy the skill folder (skills/.curated/customerio-reliability-patterns in jeremylongshore/tons-of-skills-marketplace) into .agents/skills/customerio-reliability-patterns in your project. Codex loads it when a task matches its description.

Can I use Customerio Reliability Patterns in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add jeremylongshore/tons-of-skills-marketplace --skill customerio-reliability-patterns -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/customerio-reliability-patterns, .gemini/skills/customerio-reliability-patterns, .github/skills/customerio-reliability-patterns and .opencode/skills/customerio-reliability-patterns in your project.

What does Customerio Reliability Patterns need to run?

Going by SKILL.md and its folder, Customerio Reliability Patterns needs credentials named CUSTOMERIO_TRACK_API_KEY. Our summary lists: A credential in CUSTOMERIO_TRACK_API_KEY. Its frontmatter pre-approves these tools: Read, Write, Edit, Bash(npm:*), Bash(npx:*), Glob, Grep. Compatibility (from SKILL.md): Designed for Claude Code.

Does Customerio Reliability Patterns access the network?

SKILL.md names 3 domains. As links in the text: martinfowler.com, aws.amazon.com and bullmq.io. This is read from the text; nothing was executed.

Is Customerio Reliability Patterns safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Customerio Reliability Patterns use?

Customerio Reliability Patterns is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Customerio Reliability Patterns use?

About 2.8k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 3k tokens, read only when the agent opens those files.

What are the alternatives to Customerio Reliability Patterns?

Skills that share tags, products or a category with Customerio Reliability Patterns: Error Handling (CloudAI-X/claude-workflow-v2, 1.4k stars), Review Hog Perspective Performance Reliability (PostHog/posthog, 40k stars), Mole Bug Patterns (tw93/Mole, 70k stars) and Native Data Fetching (CherryHQ/cherry-studio-app, 4k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Customerio Reliability Patterns?

jeremylongshore (a GitHub user) maintains it in jeremylongshore/tons-of-skills-marketplace, which has 2,825 GitHub stars. The repository holds 3,342 skills in this directory. The repository was last updated on October 9, 2026.

Source: jeremylongshore/tons-of-skills-marketplace on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.