Skillshub alchemy-performance-tuning
install
source · Clone the upstream repo
git clone https://github.com/ComeOnOliver/skillshub
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/ComeOnOliver/skillshub "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/jeremylongshore/claude-code-plugins-plus-skills/alchemy-performance-tuning" ~/.claude/skills/comeonoliver-skillshub-alchemy-performance-tuning && rm -rf "$T"
manifest:
skills/jeremylongshore/claude-code-plugins-plus-skills/alchemy-performance-tuning/SKILL.mdsource content
Alchemy Performance Tuning
Performance Targets
| Operation | Target Latency | CU Cost |
|---|---|---|
| < 50ms | 10 |
| < 100ms | 19 |
| < 200ms | 50 |
| < 300ms | 50 |
| < 500ms | 150 |
| Multi-chain portfolio | < 2s | ~400 |
Instructions
Step 1: Response Caching with TTL
// src/performance/cache.ts import { Alchemy, Network } from 'alchemy-sdk'; class BlockchainCache { private store = new Map<string, { data: any; expiry: number }>(); // Different TTLs for different data freshness needs private TTL: Record<string, number> = { blockNumber: 12000, // 12s (~1 block) balance: 30000, // 30s tokenBalances: 60000, // 60s nftOwnership: 300000, // 5 min (NFTs transfer less frequently) contractMetadata: 3600000, // 1 hour (rarely changes) tokenMetadata: 86400000, // 24 hours (almost never changes) }; async cached<T>(category: string, key: string, fetcher: () => Promise<T>): Promise<T> { const cacheKey = `${category}:${key}`; const entry = this.store.get(cacheKey); if (entry && entry.expiry > Date.now()) return entry.data; const data = await fetcher(); this.store.set(cacheKey, { data, expiry: Date.now() + (this.TTL[category] || 30000) }); return data; } invalidate(category: string): void { for (const key of this.store.keys()) { if (key.startsWith(`${category}:`)) this.store.delete(key); } } } const cache = new BlockchainCache(); export { cache };
Step 2: Parallel Multi-Chain Fetching
// src/performance/parallel-fetch.ts import { Alchemy, Network } from 'alchemy-sdk'; import { cache } from './cache'; const CHAINS = [ { name: 'ethereum', network: Network.ETH_MAINNET }, { name: 'polygon', network: Network.MATIC_MAINNET }, { name: 'arbitrum', network: Network.ARB_MAINNET }, { name: 'base', network: Network.BASE_MAINNET }, ]; async function multiChainBalance(address: string) { const results = await Promise.allSettled( CHAINS.map(chain => cache.cached('balance', `${chain.name}:${address}`, async () => { const client = new Alchemy({ apiKey: process.env.ALCHEMY_API_KEY, network: chain.network }); const bal = await client.core.getBalance(address); return { chain: chain.name, balance: (parseInt(bal.toString()) / 1e18).toFixed(6) }; }) ) ); return results .filter((r): r is PromiseFulfilledResult<any> => r.status === 'fulfilled') .map(r => r.value); }
Step 3: Batch NFT Metadata (Reduce CU)
// src/performance/batch-nft.ts import { Alchemy, Network } from 'alchemy-sdk'; const alchemy = new Alchemy({ apiKey: process.env.ALCHEMY_API_KEY, network: Network.ETH_MAINNET }); // SLOW: Individual calls = 50 CU each // async function slowGetMetadata(tokens) { // return Promise.all(tokens.map(t => alchemy.nft.getNftMetadata(t.contract, t.tokenId))); // } // FAST: Batch call = 50 CU total for up to 100 tokens async function fastGetMetadata(tokens: Array<{ contractAddress: string; tokenId: string }>) { return alchemy.nft.getNftMetadataBatch(tokens); }
Step 4: WebSocket for Real-Time Data
// src/performance/realtime.ts import { Alchemy, AlchemySubscription, Network } from 'alchemy-sdk'; const alchemy = new Alchemy({ apiKey: process.env.ALCHEMY_API_KEY, network: Network.ETH_MAINNET }); // Use WebSocket subscriptions instead of polling function watchAddress(address: string, onActivity: (tx: any) => void) { alchemy.ws.on( { method: AlchemySubscription.PENDING_TRANSACTIONS, toAddress: address, }, (tx) => onActivity(tx) ); } // Auto-reconnect on disconnect alchemy.ws.on('close', () => { console.log('WebSocket disconnected — reconnecting in 5s'); setTimeout(() => alchemy.ws.connect(), 5000); });
Output
- TTL-based response cache matching data freshness requirements
- Parallel multi-chain fetching (4 chains in < 2s)
- Batch NFT metadata (100x CU reduction)
- WebSocket subscriptions replacing polling
Resources
Next Steps
For cost optimization, see
alchemy-cost-tuning.