Performance Optimization
This guide covers performance optimization strategies for SolvaPay SDK, including caching, request deduplication, and best practices.
Table of Contents
Caching Strategies
Customer Reference Caching
SolvaPay SDK automatically caches customer lookups to reduce API calls:
import { createSolvaPay } from '@solvapay/server';
const solvaPay = createSolvaPay({ apiKey: process.env.SOLVAPAY_SECRET_KEY });
// Customer lookups are automatically cached for 60 seconds
// Multiple concurrent requests share the same promise
const payable = solvaPay.payable({ agent: 'agt_myapi', plan: 'pln_premium' });
Subscription Caching (Next.js)
Use subscription caching to reduce API calls:
import { checkSubscription, clearSubscriptionCache } from '@solvapay/next';
// Check subscription (cached automatically)
export async function GET(request: NextRequest) {
const result = await checkSubscription(request);
return NextResponse.json(result);
}
// Clear cache when subscription changes
export async function POST(request: NextRequest) {
const userId = getUserIdFromRequest(request);
await clearSubscriptionCache(userId);
// ... handle subscription update
}
Cache Statistics
Monitor cache performance:
import { getSubscriptionCacheStats } from '@solvapay/next';
const stats = await getSubscriptionCacheStats();
console.log('Cache hits:', stats.hits);
console.log('Cache misses:', stats.misses);
console.log('Cache size:', stats.size);
Request Deduplication
SolvaPay SDK automatically deduplicates concurrent requests:
// Multiple concurrent requests for the same customer
// share the same API call promise
const promises = [
payable.http(createTask)(req1, res1),
payable.http(createTask)(req2, res2),
payable.http(createTask)(req3, res3),
];
// Only one API call is made, all requests share the result
await Promise.all(promises);
How It Works
- Concurrent Requests: Multiple requests for the same customer reference share the same promise
- Cache TTL: Results are cached for 60 seconds to prevent duplicate sequential requests
- Automatic Cleanup: Expired cache entries are automatically removed
Subscription Caching
Next.js Subscription Caching
The @solvapay/next package includes built-in subscription caching:
// app/api/check-subscription/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { checkSubscription } from '@solvapay/next';
export async function GET(request: NextRequest) {
// Automatically cached per user ID
const result = await checkSubscription(request);
return NextResponse.json(result);
}
Cache Management
import {
clearSubscriptionCache,
clearAllSubscriptionCache,
getSubscriptionCacheStats,
} from '@solvapay/next';
// Clear cache for specific user
await clearSubscriptionCache(userId);
// Clear all caches
await clearAllSubscriptionCache();
// Get cache statistics
const stats = await getSubscriptionCacheStats();
Cache Invalidation
Invalidate cache when subscription changes:
// After successful payment
export async function POST(request: NextRequest) {
const userId = getUserIdFromRequest(request);
// Process payment...
// Clear cache to force refresh
await clearSubscriptionCache(userId);
return NextResponse.json({ success: true });
}
Best Practices
1. Reuse SolvaPay Instances
Create a single SolvaPay instance and reuse it:
// ✅ Good: Single instance
// lib/solvapay.ts
export const solvaPay = createSolvaPay({ apiKey: process.env.SOLVAPAY_SECRET_KEY });
// ❌ Bad: Creating new instances
const solvaPay = createSolvaPay({ apiKey: process.env.SOLVAPAY_SECRET_KEY }); // In each file
2. Use Subscription Caching
Enable subscription caching in Next.js:
// ✅ Good: Use cached subscription checks
import { checkSubscription } from '@solvapay/next';
export async function GET(request: NextRequest) {
const result = await checkSubscription(request); // Cached automatically
return NextResponse.json(result);
}
3. Batch Operations
Batch multiple operations when possible:
// ✅ Good: Batch operations
const [subscription, customer] = await Promise.all([
checkSubscription(request),
getCustomer(request),
]);
// ❌ Bad: Sequential operations
const subscription = await checkSubscription(request);
const customer = await getCustomer(request);
4. Minimize API Calls
Use caching and deduplication to minimize API calls:
// SolvaPay automatically:
// - Deduplicates concurrent requests
// - Caches customer lookups (60s TTL)
// - Caches subscription checks (Next.js)
5. Edge Runtime Compatibility
Use Edge-compatible patterns:
// ✅ Good: Edge-compatible
import { createSolvaPay } from '@solvapay/server';
export const runtime = 'edge';
export async function GET(request: Request) {
const solvaPay = createSolvaPay({ apiKey: process.env.SOLVAPAY_SECRET_KEY });
// Works in Edge runtime
}
Performance Monitoring
Measure API Call Latency
import { createSolvaPay } from '@solvapay/server';
const solvaPay = createSolvaPay({ apiKey: process.env.SOLVAPAY_SECRET_KEY });
async function measurePerformance() {
const start = Date.now();
await solvaPay.checkLimits({
customerRef: 'user_123',
agentRef: 'agt_myapi',
});
const latency = Date.now() - start;
console.log(`API call took ${latency}ms`);
}
Monitor Cache Hit Rates
import { getSubscriptionCacheStats } from '@solvapay/next';
async function monitorCache() {
const stats = await getSubscriptionCacheStats();
const hitRate = stats.hits / (stats.hits + stats.misses);
console.log(`Cache hit rate: ${(hitRate * 100).toFixed(2)}%`);
if (hitRate < 0.5) {
console.warn('Low cache hit rate - consider increasing cache TTL');
}
}
Track Request Deduplication
// SolvaPay automatically tracks and logs deduplication
// Enable debug mode to see deduplication in action:
const solvaPay = createSolvaPay({
apiKey: process.env.SOLVAPAY_SECRET_KEY,
debug: true, // Enable debug logging
});
Advanced Optimization
Custom Cache Implementation
For advanced use cases, implement custom caching:
import { createSolvaPay } from '@solvapay/server';
import { LRUCache } from 'lru-cache';
// Custom subscription cache
const subscriptionCache = new LRUCache<string, any>({
max: 1000,
ttl: 60000, // 60 seconds
});
async function getCachedSubscription(userId: string) {
const cached = subscriptionCache.get(userId);
if (cached) {
return cached;
}
// Fetch from API
const subscription = await checkSubscription(request);
subscriptionCache.set(userId, subscription);
return subscription;
}
Request Batching
Batch multiple customer lookups:
async function batchCustomerLookups(userIds: string[]) {
const solvaPay = createSolvaPay({ apiKey: process.env.SOLVAPAY_SECRET_KEY });
// Batch lookups (SolvaPay handles deduplication)
const promises = userIds.map(userId =>
solvaPay.ensureCustomer(userId, userId)
);
const results = await Promise.all(promises);
return results;
}
Performance Tips
-
Enable Debug Mode Sparingly: Debug logging adds overhead. Only enable in development.
-
Monitor Cache Performance: Track cache hit rates and adjust TTL values as needed.
-
Use Edge Runtime: Deploy to Edge runtime for lower latency.
-
Minimize Payload Size: Keep request/response payloads small.
-
Use Compression: Enable gzip compression for API responses.
-
Monitor API Limits: Track API usage to avoid rate limits.
Next Steps
- Testing with Stub Mode - Test performance
- Next.js Integration Guide - Next.js performance tips
- API Reference - Full API documentation