API Rate Limiter Development with Valkey
What will you learn in this guide?
This guide teaches you a rate limiter structure that protects your APIs against overuse and DDoS risks.
With Valkey's in-memory structure and atomic operations, you build a secure, fast and scalable solution.
🧠 Technical Summary
Subject: API rate limiting with Valkey (Redis compatible, in-memory database).
Problem: Excessive requests, DDoS and resource exhaustion.
Steps: Valkey installation → Express.js middleware → Atomic counter with Lua → Next.js integration.
What is a Speed Limiter?
A rate limiter restricts the number of requests a client can make in a given period of time.
The aim is to keep the system stable and fair.
Why Is It Necessary?
- Prevents abuse
- Reduces DDoS impact
- Reduces costs
- Maintains API performance
Valkey provides the advantage of low latency and atomic processing for this scenario.
Architecture and Flow
Components:
- Frontend (Next.js): User interaction
- Backend (Express.js): Traffic control
- Valkey: Counter and TTL management
Flow: Request → Backend → Valkey counter check → Permission/429 response.
Valkey Database Setup
- Select the Valkey engine from the cloud panel.
- Determine area and plan.
- Note down the Host, Port, Password information.
This step creates a managed and secure Valkey cluster.
Backend: Rate Limiter with Express.js
Environment Variables
VALKEY_HOST=db-adresi
VALKEY_PORT=25061
VALKEY_PASSWORD=parola
- These variables are used for secure connection.
Valkey Link
const Redis = require('ioredis');
const redis = new Redis({
host: process.env.VALKEY_HOST,
port: Number(process.env.VALKEY_PORT),
password: process.env.VALKEY_PASSWORD,
tls: {}
});
- This structure connects to Valkey via TLS.
Atomic Counter (Lua)
const rateLimiterLuaScript = `
local current
current = redis.call("INCR", KEYS[1])
if tonumber(current) == 1 then
redis.call("EXPIRE", KEYS[1], ARGV[1])
end
return current
`;
- This script performs counter increment and TTL setting in one step.
Middleware
const rateLimiter = async (req, res, next) => {
const ip = req.ip || 'global';
const limit = 5;
const windowInSeconds = 60;
const key = `rate:${ip}`;
const current = await redis.eval(rateLimiterLuaScript, 1, key, windowInSeconds);
if (current > limit) return res.status(429).send('Hız sınırı aşıldı');
next();
};
- This middleware limits 5 requests per minute.
Protected Endpoint
app.get('/api/saka', rateLimiter, (req, res) => {
res.send("Chuck Norris kod yazmaz, kod kendini yazar.");
});
- Bu endpoint, rate limiter ile korunur.
Frontend Integration (Next.js)
const response = await fetch('/api/saka');
if (response.status === 429) setError("Çok fazla istek");
- Frontend notifies user of 429 responses.
Why Valkey?
1. Multi-threading: Scales better under load
2. Memory efficiency: Low overhead
3. Compatibility: Seamless with Redis libraries
4. Observability: Counter and delay tracking
Frequently Asked Questions
1. Will there be user-based limits instead of IP? Yes. Create the key as rate:userId.
2. Why is Lua needed? Provides atomicity, avoids race conditions.
3. Is it suitable for a production environment? Yes. It is reliable in high traffic.
4. Why is TTL important? It ensures automatic resetting of counters.
Result
With this guide, you've set up a secure and scalable API rate limiter using Valkey. You can use this architecture in production to increase API stability.
You can try it now on the GenixNode platform for managed and high-performance infrastructures.

