# API Rate Limiting with Edge Functions on PandaStack
An unprotected API is an invitation for abuse: scrapers, brute-force attacks, and accidental infinite loops from buggy clients can take your service down or run up your database costs. Rate limiting is the first line of defense — and implementing it at the edge means requests are blocked before they ever reach your application servers.
PandaStack Edge Functions run on Apache OpenWhisk and support Node.js and Python runtimes. Here is how to implement a rate limiter using Edge Functions and a managed Redis instance.
1. Why Rate Limit at the Edge?
Rate limiting at the application level works but has a cost: every request — even ones you are going to reject — hits your application server, consumes a database connection, and runs your middleware stack. High-volume abuse attacks can overwhelm your servers before the rate limiter even has a chance to block them.
Edge functions run before traffic reaches your application. Blocked requests never touch your backend.
2. Architecture Overview
User Request
↓
PandaStack Edge Function (rate limiter)
↓ (if allowed)
Your Application Container
↓
Managed Database / ServicesThe edge function checks a Redis counter per IP address (or API key). If the counter exceeds the limit, it returns 429 immediately. If not, it increments the counter and forwards the request.
3. Create a Managed Redis Database
- 1Log in to [dashboard.pandastack.io](https://dashboard.pandastack.io)
- 2Go to Databases → New Database → Redis
- 3Copy the connection URL
Your Redis URL will be in the format: redis://username:password@host:6379
4. Write the Rate Limiter Edge Function (Node.js)
Create a new file rate-limiter.js:
const redis = require('redis')
let client
async function getRedisClient() {
if (!client) {
client = redis.createClient({ url: process.env.REDIS_URL })
await client.connect()
}
return client
}
const WINDOW_SECONDS = 60 // 1 minute window
const MAX_REQUESTS = 100 // 100 requests per minute
async function main(params) {
const ip = params.__ow_headers['x-forwarded-for'] || 'unknown'
const key = `rate:${ip}`
const redis = await getRedisClient()
// Increment counter with expiry
const count = await redis.incr(key)
if (count === 1) {
await redis.expire(key, WINDOW_SECONDS)
}
if (count > MAX_REQUESTS) {
return {
statusCode: 429,
headers: {
'Content-Type': 'application/json',
'Retry-After': String(WINDOW_SECONDS),
'X-RateLimit-Limit': String(MAX_REQUESTS),
'X-RateLimit-Remaining': '0',
},
body: JSON.stringify({
error: 'Too Many Requests',
message: `Rate limit exceeded. Try again in ${WINDOW_SECONDS} seconds.`,
}),
}
}
// Forward to your application (return a pass-through response)
return {
statusCode: 200,
headers: {
'X-RateLimit-Limit': String(MAX_REQUESTS),
'X-RateLimit-Remaining': String(Math.max(0, MAX_REQUESTS - count)),
},
body: JSON.stringify({ allowed: true }),
}
}
module.exports.main = main5. Deploy the Edge Function
- 1Dashboard → Edge Functions → New Function
- 2Connect your GitHub repository containing
rate-limiter.js - 3Select Node.js runtime
- 4Set environment variables:
- REDIS_URL: Your managed Redis connection URL
- 1Click Deploy
6. Set Different Limits by Client Tier
For APIs with tiered access (free vs. paid), use API keys to set per-tier limits:
const TIERS = {
free: 60, // 60 req/min
basic: 300, // 300 req/min
premium: 1000, // 1000 req/min
}
async function main(params) {
const apiKey = params.__ow_headers['x-api-key'] || 'anonymous'
const tier = await getTier(apiKey) // lookup from Redis or your DB
const limit = TIERS[tier] || TIERS.free
// ... rest of rate limiting logic using limit
}7. Monitor Edge Function Invocations
PandaStack's edge function dashboard shows:
- Total invocations per day
- Error rates
- Average execution time
- Rejected requests (useful for tracking abuse volume)
Go to Edge Functions → select your function → Analytics.
8. Adjust Limits Based on Observed Traffic
Start conservative (100 req/min per IP) and adjust based on your analytics:
- If legitimate users are being rate limited, increase the limit
- If you are seeing abuse patterns, decrease the limit or add IP blocking
- Add exemptions for known IP ranges (your own monitoring services, partner integrations)
Full docs: [docs.pandastack.io](https://docs.pandastack.io).