replit-rate-limits
Implement rate limiting, backoff, and idempotency patterns to handle Replit resource constraints.
Install
mkdir -p .claude/skills/replit-rate-limits && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/5430" && unzip -o skill.zip -d .claude/skills/replit-rate-limits && rm skill.zipInstalls to .claude/skills/replit-rate-limits
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Handle Replit resource limits: KV database caps, deployment quotas,Key capabilities
- →Monitor Key-Value database storage usage
- →Implement app-level rate limiting middleware
- →Apply exponential backoff for external API calls
- →Manage request throughput with concurrency queues
- →Set Retry-After headers for throttled requests
How it works
The skill provides middleware to track request counts and implement backoff logic, ensuring applications stay within Replit's KV database and deployment resource limits.
Inputs & outputs
When to use replit-rate-limits
- →Implementing backoff logic for Replit KV database
- →Optimizing API request throughput
- →Handling 429 rate limit errors
- →Managing deployment resource budgets
About this skill
Replit Rate Limits
Overview
Understand and work within Replit's resource limits: Key-Value Database size caps, Object Storage quotas, deployment compute budgets, and egress allowances. Implement rate limiting in your own app for production safety.
Prerequisites
- Replit account with active Repls
- Understanding of your current resource usage
- For rate limiting: Express or Flask app
Replit Platform Limits
Key-Value Database
| Limit | Value |
|---|---|
| Total storage | 50 MiB (keys + values combined) |
| Maximum keys | 5,000 |
| Key size | 1,000 bytes |
| Value size | 5 MiB per value |
Object Storage (App Storage)
| Limit | Value |
|---|---|
| Object size | Configurable per bucket |
| Bucket count | Per Repl (auto-provisioned) |
| Rate | Throttled at high request volume |
PostgreSQL
| Limit | Value |
|---|---|
| Storage | Plan-dependent (1-10+ GB) |
| Connections | Pooled, plan-dependent |
| Dev + Prod | Separate databases auto-provisioned |
Deployments
| Resource | Autoscale | Reserved VM |
|---|---|---|
| Scale behavior | 0 to N based on traffic | Always-on, fixed size |
| Min cost | Pay per request | $0.20/day (~$6.20/month) |
| Max resources | Plan-dependent | Up to 4 vCPU, 16 GiB RAM |
| Egress | $0.10/GiB over allowance | $0.10/GiB over allowance |
Instructions
Step 1: Monitor KV Database Usage
// Check how close you are to KV limits
import Database from '@replit/database';
async function checkKVUsage() {
const db = new Database();
const keys = await db.list();
let totalSize = 0;
for (const key of keys) {
const value = await db.get(key);
const valueSize = JSON.stringify(value).length;
totalSize += key.length + valueSize;
}
const limitMiB = 50;
const usedMiB = totalSize / (1024 * 1024);
const percentUsed = (usedMiB / limitMiB * 100).toFixed(1);
console.log(`KV Usage: ${usedMiB.toFixed(2)} MiB / ${limitMiB} MiB (${percentUsed}%)`);
console.log(`Keys: ${keys.length} / 5,000`);
if (parseFloat(percentUsed) > 80) {
console.warn('WARNING: KV database above 80%. Consider migrating large values to Object Storage.');
}
}
Step 2: Implement App-Level Rate Limiting
// src/middleware/rate-limit.ts — protect your Replit-hosted API
import { Request, Response, NextFunction } from 'express';
interface RateLimitEntry {
count: number;
resetAt: number;
}
const store = new Map<string, RateLimitEntry>();
export function rateLimit(opts = { windowMs: 60000, max: 100 }) {
return (req: Request, res: Response, next: NextFunction) => {
const key = req.headers['x-replit-user-id'] as string || req.ip;
const now = Date.now();
const entry = store.get(key);
if (!entry || now > entry.resetAt) {
store.set(key, { count: 1, resetAt: now + opts.windowMs });
setRateLimitHeaders(res, opts.max, opts.max - 1, now + opts.windowMs);
return next();
}
entry.count++;
const remaining = Math.max(0, opts.max - entry.count);
setRateLimitHeaders(res, opts.max, remaining, entry.resetAt);
if (entry.count > opts.max) {
const retryAfter = Math.ceil((entry.resetAt - now) / 1000);
res.set('Retry-After', String(retryAfter));
return res.status(429).json({
error: 'Too many requests',
retryAfter,
});
}
next();
};
}
function setRateLimitHeaders(res: Response, limit: number, remaining: number, reset: number) {
res.set('X-RateLimit-Limit', String(limit));
res.set('X-RateLimit-Remaining', String(remaining));
res.set('X-RateLimit-Reset', String(Math.ceil(reset / 1000)));
}
// Clean up expired entries periodically
setInterval(() => {
const now = Date.now();
for (const [key, entry] of store) {
if (now > entry.resetAt) store.delete(key);
}
}, 60000);
Step 3: Apply Rate Limiting
import express from 'express';
import { rateLimit } from './middleware/rate-limit';
const app = express();
// Global: 100 requests per minute
app.use(rateLimit({ windowMs: 60000, max: 100 }));
// Strict: 10 per minute for write operations
app.post('/api/*', rateLimit({ windowMs: 60000, max: 10 }));
// Generous: 500 per minute for reads
app.get('/api/*', rateLimit({ windowMs: 60000, max: 500 }));
Step 4: Exponential Backoff for External APIs
// When your Replit app calls external APIs
export async function withBackoff<T>(
fn: () => Promise<T>,
opts = { maxRetries: 5, baseMs: 1000, maxMs: 30000 }
): Promise<T> {
for (let attempt = 0; attempt <= opts.maxRetries; attempt++) {
try {
return await fn();
} catch (err: any) {
if (attempt === opts.maxRetries) throw err;
const status = err.status || err.response?.status;
if (status && status !== 429 && status < 500) throw err;
const delay = Math.min(opts.baseMs * 2 ** attempt, opts.maxMs);
const jitter = Math.random() * delay * 0.1;
await new Promise(r => setTimeout(r, delay + jitter));
}
}
throw new Error('Unreachable');
}
Step 5: Request Queue for Burst Protection
import PQueue from 'p-queue';
// Limit concurrent requests to external services
const queue = new PQueue({
concurrency: 5, // max parallel requests
interval: 1000, // per this window
intervalCap: 10, // max requests in window
});
async function rateLimitedFetch(url: string, opts?: RequestInit) {
return queue.add(() => fetch(url, opts));
}
Error Handling
| Error | Cause | Solution |
|---|---|---|
KV Max storage exceeded | Over 50 MiB | Migrate large values to Object Storage |
KV Max keys exceeded | Over 5,000 keys | Archive old data, use prefix namespacing |
| 429 from your API | Client hitting your limits | Return Retry-After header |
| Object Storage throttled | Too many rapid requests | Add client-side request queue |
| High egress costs | Large responses | Compress, paginate, or cache at CDN |
Resources
Next Steps
For security configuration, see replit-security-basics.
When not to use it
- →Applications not using Express or Flask
- →Scenarios requiring non-volatile storage for large objects
Prerequisites
Limitations
- →KV database limited to 50 MiB total storage
- →KV database limited to 5,000 keys
- →Egress costs apply over allowance
How it compares
This approach automates the implementation of production-safe rate limiting and retry logic compared to manual, ad-hoc error handling.
Compared to similar skills
replit-rate-limits side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| replit-rate-limits (this skill) | 1 | 27d | Review | Intermediate |
| supabase-developer | 95 | 7mo | Review | Intermediate |
| agentdb-memory-patterns | 9 | 9mo | Review | Advanced |
| agentdb-advanced-features | 7 | 9mo | Review | Advanced |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by jeremylongshore
View all by jeremylongshore →You might also like
supabase-developer
daffy0208
Build full-stack applications with Supabase (PostgreSQL, Auth, Storage, Real-time, Edge Functions). Use when implementing authentication, database design with RLS, file storage, real-time features, or serverless functions.
agentdb-memory-patterns
ruvnet
Implement persistent memory patterns for AI agents using AgentDB. Includes session memory, long-term storage, pattern learning, and context management. Use when building stateful agents, chat systems, or intelligent assistants.
agentdb-advanced-features
ruvnet
Master advanced AgentDB features including QUIC synchronization, multi-database management, custom distance metrics, hybrid search, and distributed systems integration. Use when building distributed AI systems, multi-agent coordination, or advanced vector search applications.
agentdb-performance-optimization
ruvnet
Optimize AgentDB performance with quantization (4-32x memory reduction), HNSW indexing (150x faster search), caching, and batch operations. Use when optimizing memory usage, improving search speed, or scaling to millions of vectors.
senior-backend
davila7
Comprehensive backend development skill for building scalable backend systems using NodeJS, Express, Go, Python, Postgres, GraphQL, REST APIs. Includes API scaffolding, database optimization, security implementation, and performance tuning. Use when designing APIs, optimizing database queries, implementing business logic, handling authentication/authorization, or reviewing backend code.
redis-inspect
civitai
Inspect Redis cache keys, values, and TTLs for debugging. Supports both main cache and system cache. Use for debugging cache issues, checking cached values, and monitoring cache state. Read-only by default.