Skills Development Framer API Rate Limiting and Retry Logic

Framer API Rate Limiting and Retry Logic

v20260423
framer-rate-limits
Provides robust patterns for handling API rate limits, throttling, and connection errors when integrating with the Framer API. It covers implementing exponential backoff, retry mechanisms, batching large CMS writes, and debouncing plugin operations to ensure reliable and high-throughput API calls.
Get Skill
261 downloads
Overview

Framer Rate Limits

Overview

Handle Framer API rate limits for Server API and plugin operations. The Server API uses WebSocket, so rate limits apply per-connection. CMS operations are limited by collection size and concurrent writes.

Rate Limit Reference

Operation Limit Notes
Server API connections 1 per site WebSocket, persistent
CMS setItems ~100 items/call Batch larger sets
CMS getItems No hard limit Returns all items
Plugin API calls Debounced Framer throttles internally
Publish ~1/minute Site publishing
Image upload Concurrent limit Via CMS image fields

Instructions

Step 1: Batch CMS Writes

async function batchSetItems(collection: any, items: any[], batchSize = 100) {
  for (let i = 0; i < items.length; i += batchSize) {
    const batch = items.slice(i, i + batchSize);
    await collection.setItems(batch);
    console.log(`Synced ${Math.min(i + batchSize, items.length)}/${items.length}`);
    if (i + batchSize < items.length) {
      await new Promise(r => setTimeout(r, 1000)); // 1s between batches
    }
  }
}

Step 2: Debounced Plugin Operations

// Debounce rapid plugin UI interactions
function debounce<T extends (...args: any[]) => any>(fn: T, ms = 300) {
  let timer: NodeJS.Timeout;
  return (...args: Parameters<T>) => {
    clearTimeout(timer);
    timer = setTimeout(() => fn(...args), ms);
  };
}

const debouncedSync = debounce(async () => {
  await syncCollection();
}, 500);

Step 3: Retry for Server API

async function withRetry<T>(fn: () => Promise<T>, maxRetries = 3): Promise<T> {
  for (let i = 0; i <= maxRetries; i++) {
    try {
      return await fn();
    } catch (err: any) {
      if (i === maxRetries) throw err;
      const delay = 1000 * Math.pow(2, i);
      console.log(`Retry ${i + 1} in ${delay}ms`);
      await new Promise(r => setTimeout(r, delay));
    }
  }
  throw new Error('Unreachable');
}

Error Handling

Error Cause Solution
WebSocket disconnected Connection timeout Reconnect with backoff
setItems slow Large batch Split into chunks of 100
Publish rate limited Too frequent Wait 60s between publishes

Resources

Next Steps

For security, see framer-security-basics.

Info
Category Development
Name framer-rate-limits
Version v20260423
Size 2.98KB
Updated At 2026-04-26
Language