Skip to main content
AI/MLjeremylongshore

klaviyo-performance-tuning

'Optimize Klaviyo API performance with caching, batching, and pagination

Stars
2,267
Source
jeremylongshore/claude-code-plugins-plus-skills
Updated
2026-05-31
Slug
jeremylongshore--claude-code-plugins-plus-skills--klaviyo-performance-tuning
View on GitHubRaw SKILL.md

// install — copy + paste into any project

mkdir -p .claude/skills && curl -fsSL https://raw.githubusercontent.com/jeremylongshore/claude-code-plugins-plus-skills/HEAD/plugins/saas-packs/klaviyo-pack/skills/klaviyo-performance-tuning/SKILL.md -o .claude/skills/klaviyo-performance-tuning.md

Drops the SKILL.md into .claude/skills/klaviyo-performance-tuning.md. Works with Claude Code, Cursor, and any agent that loads SKILL.md files from .claude/skills/.

Klaviyo Performance Tuning

Overview

Optimize Klaviyo API performance with response caching, request batching, cursor-based pagination, sparse fieldsets, and connection pooling. This skill diagnoses where an integration is slow, then applies the right technique — payload reduction, memory caching, bounded pagination, request coalescing, or rate-limit-aware concurrency.

Read this file for the workflow and the decision guide. Full, copy-pasteable code for every step lives in references/implementation.md; combined real-world scenarios live in references/examples.md.

Prerequisites

  • klaviyo-api SDK installed
  • Understanding of Klaviyo's rate limits (75 req/s burst, 700 req/min)
  • Redis or in-memory cache (optional)
  • For batching/concurrency helpers: dataloader, p-queue, lru-cache

Klaviyo API Performance Characteristics

Operation Typical Latency Max Page Size
Get Profile by ID 50-150ms N/A
Get Profiles (list) 100-300ms 20 (default), 100 (some endpoints)
Create Profile 100-200ms N/A
Create Event 50-100ms N/A
Get Segment Profiles 200-500ms 20
Campaign Operations 200-500ms 20

Instructions

Apply the techniques in order — each is independent, so start with the one that matches your bottleneck. Every step below has a full implementation in references/implementation.md.

Step 1: Sparse Fieldsets (Reduce Payload Size)

Klaviyo supports JSON:API sparse fieldsets — request only the fields you need instead of the 20+ default attributes. This is the cheapest win and applies to every read.

// GOOD: Only fetch the fields you use (much smaller payload)
const profiles = await profilesApi.getProfiles({
  fieldsProfile: ['email', 'first_name', 'created'],  // snake_case = API names
});

Step 2: Response Caching

Wrap read calls in an LRUCache keyed by query, with per-resource TTLs (profiles 5 min, segments 15 min — they change less often). See the caching implementation in references/implementation.md.

Step 3: Efficient Pagination

Use a fetchAllPages helper that follows the links.next cursor with a maxPages ceiling so large exports terminate predictably. See the pagination implementation in references/implementation.md.

Step 4: Request Batching with DataLoader

Coalesce many getProfile(id) calls in a single tick into concurrency-controlled requests with DataLoader (maxBatchSize: 10, 50 ms window). See the batching implementation in references/implementation.md.

Step 5: Parallel API Calls with Concurrency Control

Drive bulk writes through a PQueue capped at 50 req/s — a safe margin under the 75 req/s burst limit — with progress logging. See the concurrency implementation in references/implementation.md.

Step 6: Performance Monitoring

Wrap calls in measuredCall and read a p95 summary via getPerfSummary to find the real bottleneck before optimizing. See the monitoring implementation in references/implementation.md.

Output

Applying this skill produces:

  • Sparse-fieldset read calls with 50-80% smaller payloads on list endpoints.
  • A cache module (src/klaviyo/cache.ts) that serves repeated reads from memory with per-resource TTLs.
  • A pagination helper (src/klaviyo/pagination.ts) that safely walks cursor-paginated endpoints to completion under a maxPages guard.
  • Batching + concurrency helpers that keep bulk operations under Klaviyo's 75 req/s burst and 700 req/min ceilings.
  • A perf-monitoring module (src/klaviyo/perf-monitor.ts) emitting per-operation avg, p95, and count so you can verify the gains.

Error Handling

Issue Cause Solution
Cache stampede Many requests on cache miss Use stale-while-revalidate pattern
Pagination timeout Very large datasets Set maxPages limit, process in chunks
Rate limit on bulk ops Too much concurrency Reduce PQueue concurrency/intervalCap
Slow filter queries Complex filter expressions Simplify filters, use segment IDs instead

Examples

Worked, end-to-end scenarios that combine the steps above are in references/examples.md:

  • Fast cached profile lookup — sparse fieldsets + LRU caching for a repeated lookup.
  • Export a large list — bounded cursor pagination for a multi-hundred-thousand-member list.
  • Bulk-update 10,000 profilesPQueue concurrency under the rate limit.
  • Measure where the time goesmeasuredCall + getPerfSummary to find the slow op first.

Minimal caching example (full versions in the reference):

import { cachedKlaviyoCall } from './cache';

const profile = await cachedKlaviyoCall(
  `profile:${email}`,
  () => profilesApi.getProfiles({ filter: `equals(email,"${email}")` }),
  5 * 60 * 1000  // 5 minute TTL
);

Resources

Next Steps

Once reads are cached and bulk writes are rate-limit-safe, profile the workload with getPerfSummary (Step 6) to confirm the p95 improvement, then tune TTLs and concurrency to your traffic. For cost optimization of the same integration, see the klaviyo-cost-tuning skill.