From flyio-pack
Manages Fly.io Machines API rate limits with exponential backoff retries, PQueue concurrency control, and batching for create/update/delete/start/stop operations. Useful for high-volume machine management.
npx claudepluginhub jeremylongshore/claude-code-plugins-plus-skills --plugin flyio-packThis skill is limited to using the following tools:
The Fly.io Machines API has rate limits per organization. Machine create/update/delete operations are more tightly limited than read operations. The API returns 429 with `Retry-After` header when limits are exceeded.
Implements TypeScript clients and patterns for Fly.io Machines API: typed REST calls, lifecycle management, state waiting, multi-region deployments with Docker images.
Provides quick reference for Fly.io PaaS deployments including fly.toml config, global distribution, scaling patterns, secrets management, health checks, and troubleshooting. Auto-loads on fly.toml detection.
Deploys and manages Fly.io apps using Docker containers, Fly Machines, fly.toml configs, databases, volumes, secrets. Supports fly launch/deploy, debugging, multi-region setups for Python/Node/Rails/Django apps.
Share bugs, ideas, or general feedback.
The Fly.io Machines API has rate limits per organization. Machine create/update/delete operations are more tightly limited than read operations. The API returns 429 with Retry-After header when limits are exceeded.
| Operation | Approximate Limit | Scope |
|---|---|---|
| Machine create/delete | ~10/minute | Per org |
| Machine start/stop | ~30/minute | Per org |
| List/get machines | ~60/minute | Per org |
| App operations | ~20/minute | Per org |
async function flyApiWithRetry<T>(
fn: () => Promise<Response>,
maxRetries = 4
): Promise<T> {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
const res = await fn();
if (res.ok) return res.json();
if (res.status === 429) {
const retryAfter = parseInt(res.headers.get('Retry-After') || '10');
const delay = retryAfter * 1000 + Math.random() * 2000;
console.log(`Rate limited. Retry in ${(delay / 1000).toFixed(0)}s`);
await new Promise(r => setTimeout(r, delay));
continue;
}
if (res.status >= 500 && attempt < maxRetries) {
await new Promise(r => setTimeout(r, Math.pow(2, attempt) * 1000));
continue;
}
throw new Error(`Fly API ${res.status}: ${await res.text()}`);
}
throw new Error('Max retries exceeded');
}
import PQueue from 'p-queue';
// Limit concurrent machine operations
const flyQueue = new PQueue({ concurrency: 3, interval: 10000, intervalCap: 10 });
async function batchCreateMachines(configs: Array<{ region: string; config: any }>) {
return Promise.all(
configs.map(c => flyQueue.add(() =>
flyApiWithRetry(() => fetch(`${FLY_API}/v1/apps/${app}/machines`, {
method: 'POST', headers,
body: JSON.stringify(c),
}))
))
);
}
For security, see flyio-security-basics.