perplexity-performance-tuning
Strategies to reduce latency and manage costs in search-augmented generation APIs.
Install
mkdir -p .claude/skills/perplexity-performance-tuning && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/6338" && unzip -o skill.zip -d .claude/skills/perplexity-performance-tuning && rm skill.zipInstalls to .claude/skills/perplexity-performance-tuning
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Optimize Perplexity Sonar API performance with caching, streaming, modelKey capabilities
- →Route Perplexity API calls based on query complexity
- →Cache Perplexity API responses with query-type-aware TTLs
- →Stream Perplexity API responses for perceived performance
- →Execute parallel Perplexity API research with rate limiting
- →Optimize response size by limiting tokens based on detail level
How it works
The skill classifies query complexity to select an appropriate Perplexity model and token limit. It caches responses with varying Time-To-Live values based on query type and streams results to reduce perceived latency.
Inputs & outputs
When to use perplexity-performance-tuning
- →Optimizing API response latency
- →Caching search-augmented generation
- →Routing queries to appropriate models
- →Reducing API costs
About this skill
Perplexity Performance Tuning
Overview
Optimize Perplexity Sonar API for latency, throughput, and cost. Key insight: every Perplexity call performs a live web search, so response times are inherently variable. Typical latencies: sonar 1-3s, sonar-pro 3-8s, sonar-deep-research 10-60s.
Latency Benchmarks
| Model | Typical Latency | Max Tokens | Best For |
|---|---|---|---|
sonar | 1-3s | 4096 | Quick answers, simple facts |
sonar-pro | 3-8s | 8192 | Deep research, many citations |
sonar-reasoning-pro | 5-15s | 8192 | Multi-step analysis |
sonar-deep-research | 10-60s | 8192 | Comprehensive reports |
Prerequisites
- Perplexity API key configured
- Understanding of search-augmented generation latency patterns
- Cache infrastructure (Redis or in-memory LRU)
Instructions
Step 1: Smart Model Routing
import OpenAI from "openai";
const perplexity = new OpenAI({
apiKey: process.env.PERPLEXITY_API_KEY,
baseURL: "https://api.perplexity.ai",
});
type QueryComplexity = "simple" | "standard" | "deep";
function classifyQuery(query: string): QueryComplexity {
const words = query.split(/\s+/).length;
const simplePatterns = [/^what is/i, /^who is/i, /^when did/i, /^define/i, /^how many/i];
const deepPatterns = [/compare.*vs/i, /analysis of/i, /comprehensive/i, /pros and cons/i, /in-depth/i];
if (simplePatterns.some((p) => p.test(query)) && words < 15) return "simple";
if (deepPatterns.some((p) => p.test(query)) || words > 30) return "deep";
return "standard";
}
function selectModel(complexity: QueryComplexity): { model: string; maxTokens: number } {
switch (complexity) {
case "simple": return { model: "sonar", maxTokens: 256 };
case "standard": return { model: "sonar", maxTokens: 1024 };
case "deep": return { model: "sonar-pro", maxTokens: 4096 };
}
}
async function smartSearch(query: string) {
const complexity = classifyQuery(query);
const { model, maxTokens } = selectModel(complexity);
return perplexity.chat.completions.create({
model,
messages: [{ role: "user", content: query }],
max_tokens: maxTokens,
});
}
Step 2: Query Hash Caching
import { LRUCache } from "lru-cache";
import { createHash } from "crypto";
const CACHE_TTL = {
news: 30 * 60 * 1000, // 30 min for current events
research: 4 * 60 * 60 * 1000, // 4 hours for research
factual: 24 * 60 * 60 * 1000, // 24 hours for stable facts
};
const searchCache = new LRUCache<string, any>({
max: 1000,
ttl: CACHE_TTL.research, // default TTL
});
function cacheKey(query: string, model: string): string {
return createHash("sha256")
.update(`${model}:${query.toLowerCase().trim()}`)
.digest("hex");
}
function detectTTL(query: string): number {
if (/\b(latest|today|breaking|current price|this week)\b/i.test(query))
return CACHE_TTL.news;
if (/\b(what is|define|how does|who is)\b/i.test(query))
return CACHE_TTL.factual;
return CACHE_TTL.research;
}
async function cachedSearch(query: string, model = "sonar") {
const key = cacheKey(query, model);
const cached = searchCache.get(key);
if (cached) return { ...cached, cached: true };
const result = await perplexity.chat.completions.create({
model,
messages: [{ role: "user", content: query }],
});
searchCache.set(key, result, { ttl: detectTTL(query) });
return { ...result, cached: false };
}
Step 3: Streaming for Perceived Performance
async function streamSearch(
query: string,
onChunk: (text: string) => void,
onCitations: (urls: string[]) => void
) {
const stream = await perplexity.chat.completions.create({
model: "sonar-pro",
messages: [{ role: "user", content: query }],
stream: true,
max_tokens: 4096,
});
let fullText = "";
for await (const chunk of stream) {
const text = chunk.choices[0]?.delta?.content || "";
fullText += text;
onChunk(text);
if ((chunk as any).citations) {
onCitations((chunk as any).citations);
}
}
return fullText;
}
Step 4: Parallel Research with Rate Limiting
import PQueue from "p-queue";
const queue = new PQueue({ concurrency: 3, interval: 1500, intervalCap: 1 });
async function parallelResearch(queries: string[]): Promise<Map<string, any>> {
const results = new Map<string, any>();
await Promise.all(
queries.map((q) =>
queue.add(async () => {
const result = await cachedSearch(q, "sonar");
results.set(q, result);
})
)
);
return results;
}
Step 5: Response Size Optimization
// Limit tokens to what you actually need
async function optimizedSearch(query: string, detail: "brief" | "full" = "brief") {
return perplexity.chat.completions.create({
model: "sonar",
messages: [
{
role: "system",
content: detail === "brief"
? "Answer in 2-3 sentences maximum."
: "Provide a thorough answer with examples.",
},
{ role: "user", content: query },
],
max_tokens: detail === "brief" ? 150 : 2048,
});
}
Error Handling
| Issue | Cause | Solution |
|---|---|---|
| Latency >10s on sonar | Complex query triggering deep search | Add max_tokens: 512 to limit response |
| Cache hit rate <20% | Queries too unique | Normalize queries (lowercase, trim) |
| Burst 429 errors | Parallel requests too aggressive | Use PQueue with intervalCap |
| Stale cached results | TTL too long for news | Use query-type-aware TTL |
Output
- Smart model routing by query complexity
- Query-aware caching with appropriate TTLs
- Streaming for reduced perceived latency
- Rate-limited parallel research
Resources
Next Steps
For cost optimization, see perplexity-cost-tuning.
Prerequisites
Limitations
- →Latency can exceed 10 seconds on 'sonar' for complex queries
- →Cache hit rate may be low if queries are too unique
- →Burst 429 errors can occur with aggressive parallel requests
How it compares
This skill dynamically adjusts API calls based on query characteristics and caching needs, unlike a static API integration.
Compared to similar skills
perplexity-performance-tuning side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| perplexity-performance-tuning (this skill) | 1 | 27d | Review | Intermediate |
| groq-performance-tuning | 1 | 27d | No flags | Intermediate |
| openrouter-streaming-setup | 1 | 27d | Review | Intermediate |
| ideogram-rate-limits | 2 | 27d | Review | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by jeremylongshore
View all by jeremylongshore →You might also like
groq-performance-tuning
jeremylongshore
Optimize Groq API performance with caching, batching, and connection pooling. Use when experiencing slow API responses, implementing caching strategies, or optimizing request throughput for Groq integrations. Trigger with phrases like "groq performance", "optimize groq", "groq latency", "groq caching", "groq slow", "groq batch".
openrouter-streaming-setup
jeremylongshore
Implement streaming responses with OpenRouter. Use when building real-time chat interfaces or reducing time-to-first-token. Trigger with phrases like 'openrouter streaming', 'openrouter sse', 'stream response', 'real-time openrouter'.
ideogram-rate-limits
jeremylongshore
Implement Ideogram rate limiting, backoff, and idempotency patterns. Use when handling rate limit errors, implementing retry logic, or optimizing API request throughput for Ideogram. Trigger with phrases like "ideogram rate limit", "ideogram throttling", "ideogram 429", "ideogram retry", "ideogram backoff".
firecrawl-reliability-patterns
jeremylongshore
Implement FireCrawl reliability patterns including circuit breakers, idempotency, and graceful degradation. Use when building fault-tolerant FireCrawl integrations, implementing retry strategies, or adding resilience to production FireCrawl services. Trigger with phrases like "firecrawl reliability", "firecrawl circuit breaker", "firecrawl idempotent", "firecrawl resilience", "firecrawl fallback", "firecrawl bulkhead".
linear-rate-limits
jeremylongshore
Handle Linear API rate limiting and quotas effectively. Use when dealing with rate limit errors, implementing throttling, or optimizing API usage patterns. Trigger with phrases like "linear rate limit", "linear throttling", "linear API quota", "linear 429 error", "linear request limits".
generating-grpc-services
jeremylongshore
Generate gRPC service definitions, stubs, and implementations from Protocol Buffers. Use when creating high-performance gRPC services. Trigger with phrases like "generate gRPC service", "create gRPC API", or "build gRPC server".