AgentSkillsCN

clay-performance-tuning

通过缓存、批处理与连接池优化Clay API性能。 当遇到API响应缓慢、实施缓存策略、 或优化Clay集成的请求吞吐量时使用。 可通过“Clay性能”、“优化Clay”、 “Clay延迟”、“Clay缓存”、“Clay缓慢”、“Clay批处理”等短语触发。

SKILL.md
--- frontmatter
name: clay-performance-tuning
description: |
  Optimize Clay API performance with caching, batching, and connection pooling.
  Use when experiencing slow API responses, implementing caching strategies,
  or optimizing request throughput for Clay integrations.
  Trigger with phrases like "clay performance", "optimize clay",
  "clay latency", "clay caching", "clay slow", "clay batch".
allowed-tools: Read, Write, Edit
version: 1.0.0
license: MIT
author: Jeremy Longshore <jeremy@intentsolutions.io>

Clay Performance Tuning

Overview

Optimize Clay API performance with caching, batching, and connection pooling.

Prerequisites

  • Clay SDK installed
  • Understanding of async patterns
  • Redis or in-memory cache available (optional)
  • Performance monitoring in place

Latency Benchmarks

OperationP50P95P99
Read50ms150ms300ms
Write100ms250ms500ms
List75ms200ms400ms

Caching Strategy

Response Caching

typescript
import { LRUCache } from 'lru-cache';

const cache = new LRUCache<string, any>({
  max: 1000,
  ttl: 60000, // 1 minute
  updateAgeOnGet: true,
});

async function cachedClayRequest<T>(
  key: string,
  fetcher: () => Promise<T>,
  ttl?: number
): Promise<T> {
  const cached = cache.get(key);
  if (cached) return cached as T;

  const result = await fetcher();
  cache.set(key, result, { ttl });
  return result;
}

Redis Caching (Distributed)

typescript
import Redis from 'ioredis';

const redis = new Redis(process.env.REDIS_URL);

async function cachedWithRedis<T>(
  key: string,
  fetcher: () => Promise<T>,
  ttlSeconds = 60
): Promise<T> {
  const cached = await redis.get(key);
  if (cached) return JSON.parse(cached);

  const result = await fetcher();
  await redis.setex(key, ttlSeconds, JSON.stringify(result));
  return result;
}

Request Batching

typescript
import DataLoader from 'dataloader';

const clayLoader = new DataLoader<string, any>(
  async (ids) => {
    // Batch fetch from Clay
    const results = await clayClient.batchGet(ids);
    return ids.map(id => results.find(r => r.id === id) || null);
  },
  {
    maxBatchSize: 100,
    batchScheduleFn: callback => setTimeout(callback, 10),
  }
);

// Usage - automatically batched
const [item1, item2, item3] = await Promise.all([
  clayLoader.load('id-1'),
  clayLoader.load('id-2'),
  clayLoader.load('id-3'),
]);

Connection Optimization

typescript
import { Agent } from 'https';

// Keep-alive connection pooling
const agent = new Agent({
  keepAlive: true,
  maxSockets: 10,
  maxFreeSockets: 5,
  timeout: 30000,
});

const client = new ClayClient({
  apiKey: process.env.CLAY_API_KEY!,
  httpAgent: agent,
});

Pagination Optimization

typescript
async function* paginatedClayList<T>(
  fetcher: (cursor?: string) => Promise<{ data: T[]; nextCursor?: string }>
): AsyncGenerator<T> {
  let cursor: string | undefined;

  do {
    const { data, nextCursor } = await fetcher(cursor);
    for (const item of data) {
      yield item;
    }
    cursor = nextCursor;
  } while (cursor);
}

// Usage
for await (const item of paginatedClayList(cursor =>
  clayClient.list({ cursor, limit: 100 })
)) {
  await process(item);
}

Performance Monitoring

typescript
async function measuredClayCall<T>(
  operation: string,
  fn: () => Promise<T>
): Promise<T> {
  const start = performance.now();
  try {
    const result = await fn();
    const duration = performance.now() - start;
    console.log({ operation, duration, status: 'success' });
    return result;
  } catch (error) {
    const duration = performance.now() - start;
    console.error({ operation, duration, status: 'error', error });
    throw error;
  }
}

Instructions

Step 1: Establish Baseline

Measure current latency for critical Clay operations.

Step 2: Implement Caching

Add response caching for frequently accessed data.

Step 3: Enable Batching

Use DataLoader or similar for automatic request batching.

Step 4: Optimize Connections

Configure connection pooling with keep-alive.

Output

  • Reduced API latency
  • Caching layer implemented
  • Request batching enabled
  • Connection pooling configured

Error Handling

IssueCauseSolution
Cache miss stormTTL expiredUse stale-while-revalidate
Batch timeoutToo many itemsReduce batch size
Connection exhaustedNo poolingConfigure max sockets
Memory pressureCache too largeSet max cache entries

Examples

Quick Performance Wrapper

typescript
const withPerformance = <T>(name: string, fn: () => Promise<T>) =>
  measuredClayCall(name, () =>
    cachedClayRequest(`cache:${name}`, fn)
  );

Resources

Next Steps

For cost optimization, see clay-cost-tuning.