Skills Development Optimize SalesLoft API Performance

Optimize SalesLoft API Performance

v20260423
salesloft-performance-tuning
This guide provides advanced techniques to optimize interactions with the SalesLoft REST API v2. Key strategies include implementing LRU caching for frequently accessed data, utilizing incremental sync with `updated_at` filtering to avoid costly deep pagination, configuring connection pooling for stability, and running parallel reads safely. Use this when experiencing high latency, managing large datasets, or minimizing API usage costs for bulk operations.
Get Skill
476 downloads
Overview

SalesLoft Performance Tuning

Overview

Optimize SalesLoft REST API v2 performance. Key bottlenecks: deep pagination (cost multiplier), no batch endpoints, and per-minute rate limits. Solutions: caching, incremental sync, and pagination-aware request planning.

Latency Benchmarks

Operation Typical With Caching
GET /me.json 80ms N/A (auth)
GET /people.json (page 1) 120ms 1ms (cached)
POST /people.json 200ms N/A (write)
GET /activities/emails.json 150ms 1ms (cached)
Full sync (10k people) ~20min ~5min (incremental)

Instructions

Step 1: Response Caching

import { LRUCache } from 'lru-cache';

const cache = new LRUCache<string, any>({ max: 5000, ttl: 60_000 });

async function cachedGet<T>(endpoint: string, params?: Record<string, any>): Promise<T> {
  const key = `${endpoint}:${JSON.stringify(params || {})}`;
  const hit = cache.get(key);
  if (hit) return hit as T;

  const { data } = await api.get(endpoint, { params });
  cache.set(key, data);
  return data;
}

// Cache people lookups (frequent during cadence enrollment)
const person = await cachedGet('/people.json', { email_addresses: ['alex@co.com'] });

Step 2: Incremental Sync with updated_at

// Only fetch records changed since last sync
async function incrementalSync(lastSyncTime: string) {
  const updated: any[] = [];
  let page = 1;

  while (true) {
    const { data } = await api.get('/people.json', {
      params: {
        updated_at: { gt: lastSyncTime }, // ISO 8601
        per_page: 100,
        page,
        sort_by: 'updated_at',
        sort_direction: 'ASC',
      },
    });
    updated.push(...data.data);
    if (page >= data.metadata.paging.total_pages) break;
    page++;
  }

  return { updated, newSyncTime: new Date().toISOString() };
}

Step 3: Avoid Deep Pagination Cost

// Deep pages cost 3-30x. Instead of paginating all 25k records,
// use updated_at filter to get incremental changes
function shouldUseIncremental(totalCount: number): boolean {
  // If total records > 1000, incremental sync is more efficient
  // Full pagination of 250 pages = 910 cost points vs.
  // incremental of last 50 changes = 1 page = 1 point
  return totalCount > 1000;
}

Step 4: Connection Pooling

import { Agent } from 'https';

const agent = new Agent({
  keepAlive: true,
  maxSockets: 10,     // Max concurrent connections
  maxFreeSockets: 5,  // Keep idle connections alive
  timeout: 30_000,
});

const api = axios.create({
  baseURL: 'https://api.salesloft.com/v2',
  headers: { Authorization: `Bearer ${process.env.SALESLOFT_API_KEY}` },
  httpsAgent: agent,
});

Step 5: Parallel Safe Reads

// Parallelize independent reads (each costs 1 point)
const [people, cadences, activities] = await Promise.all([
  api.get('/people.json', { params: { per_page: 100 } }),
  api.get('/cadences.json', { params: { per_page: 50 } }),
  api.get('/activities/emails.json', { params: { per_page: 100 } }),
]);
// 3 points total, ~120ms parallel vs ~360ms sequential

Error Handling

Issue Cause Solution
Cache stampede TTL expiry under load Stale-while-revalidate pattern
Incremental misses Clock skew Use updated_at from last response, not local clock
Connection timeout Pool exhausted Increase maxSockets or reduce concurrency
Rate limit on bulk Too many parallel requests Use p-queue with intervalCap: 10

Resources

Next Steps

For cost optimization, see salesloft-cost-tuning.

Info
Category Development
Name salesloft-performance-tuning
Version v20260423
Size 4.28KB
Updated At 2026-04-28
Language