framer-rate-limits

v2026.09.24

Implement Framer rate limiting, backoff, and idempotency patterns. Use when handling rate limit errors, implementing retry logic, or optimizing API request throughput for Framer. Trigger with phrases like "framer rate limit", "framer throttling", "framer 429", "framer retry", "framer backoff".

GitHub
Install command
npx skhub add jeremylongshore/framer-rate-limits
Markdown
SKILL.md

Framer Rate Limits

Prerequisites

Confirmed provider limits, bounded concurrency/retry policy, approved integration owner, and synthetic staging requests.

Output

Record policy version, aggregate throttles, retry/queue outcome, owner, and manual disposition without visitor data or credentials.

Examples

Simulate a throttled staging request, honor the retry bound under an opaque operation ID, and route repeated failures to review instead of replaying publish actions.

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

OperationLimitNotes
Server API connections1 per siteWebSocket, persistent
CMS setItems~100 items/callBatch larger sets
CMS getItemsNo hard limitReturns all items
Plugin API callsDebouncedFramer throttles internally
Publish~1/minuteSite publishing
Image uploadConcurrent limitVia 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

ErrorCauseSolution
WebSocket disconnectedConnection timeoutReconnect with backoff
setItems slowLarge batchSplit into chunks of 100
Publish rate limitedToo frequentWait 60s between publishes

Resources

Next Steps

For security, see framer-security-basics.

Discovery
Tags

No tags published for this skill.

Version
Latest version metadata

Version

v2026.09.24

Published

Sep 24, 2026

Category

Uncategorized

License

MIT

Source path

skills/.curated/framer-rate-limits

Default branch

main

Latest commit

e5a6c3b

Tree SHA

c2dc8e8