Claude-code-plugins serpapi-performance-tuning
install
source · Clone the upstream repo
git clone https://github.com/jeremylongshore/claude-code-plugins-plus-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/jeremylongshore/claude-code-plugins-plus-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/saas-packs/serpapi-pack/skills/serpapi-performance-tuning" ~/.claude/skills/jeremylongshore-claude-code-plugins-serpapi-performance-tuning && rm -rf "$T"
manifest:
plugins/saas-packs/serpapi-pack/skills/serpapi-performance-tuning/SKILL.mdsource content
SerpApi Performance Tuning
Overview
SerpApi typical latency: 2-5 seconds per search (real-time scraping). Main optimization: aggressive caching since search results change slowly. Secondary: use Google Light API for faster responses, reduce
num parameter, and parallelize independent searches.
Instructions
Step 1: Multi-Layer Caching
import { LRUCache } from 'lru-cache'; import { Redis } from 'ioredis'; import { getJson } from 'serpapi'; // L1: In-memory (fastest, per-instance) const l1 = new LRUCache<string, any>({ max: 1000, ttl: 600_000 }); // 10 min // L2: Redis (shared across instances) const redis = new Redis(process.env.REDIS_URL!); async function cachedSearch(params: Record<string, any>): Promise<any> { const key = `serpapi:${JSON.stringify(params)}`; // L1 check const l1Hit = l1.get(key); if (l1Hit) return l1Hit; // L2 check const l2Hit = await redis.get(key); if (l2Hit) { const parsed = JSON.parse(l2Hit); l1.set(key, parsed); return parsed; } // Cache miss: real API call const result = await getJson({ ...params, api_key: process.env.SERPAPI_API_KEY }); l1.set(key, result); await redis.setex(key, 3600, JSON.stringify(result)); // 1 hour in Redis return result; }
Step 2: Google Light API (Faster)
# Google Light API: ~1s instead of 2-5s, limited result fields result = client.search(engine="google_light", q="fast query", num=5) # Returns: organic_results with title, link, snippet only # No knowledge_graph, answer_box, or rich snippets
Step 3: Reduce Response Size
# Only get the fields you need result = client.search( engine="google", q="query", num=5, # Fewer results = faster no_cache=False, # Use SerpApi's server-side cache (default) ) # Strip metadata to reduce memory/storage clean = { "organic_results": result.get("organic_results", []), "answer_box": result.get("answer_box"), "search_id": result["search_metadata"]["id"], }
Step 4: Parallel Search
import PQueue from 'p-queue'; const queue = new PQueue({ concurrency: 5, interval: 1000, intervalCap: 5 }); async function batchSearch(queries: string[]): Promise<any[]> { return Promise.all( queries.map(q => queue.add(() => cachedSearch({ engine: 'google', q, num: 5 })) ) ); } // 10 queries, 5 parallel, rate limited: ~4 seconds total const results = await batchSearch(['query1', 'query2', /* ... */]);
Latency Benchmarks
| Method | Typical Latency | Credits |
|---|---|---|
| Google Search (uncached) | 2-5s | 1 |
| Google Light | 1-2s | 1 |
| L1 cache hit | < 1ms | 0 |
| Redis cache hit | 1-5ms | 0 |
| Archive retrieval | 500ms | 0 |
Error Handling
| Issue | Cause | Solution |
|---|---|---|
| Cache stampede | TTL expiry under load | Stale-while-revalidate |
| High latency | Complex queries | Use Google Light API |
| Memory pressure | Large cache | Limit LRU max entries |
Resources
Next Steps
For cost optimization, see
serpapi-cost-tuning.