Designing Production-Grade Distributed Rate Limiting with Redis Lua in a Linkedin Style Social Media Platform's Backend
How I designed and implemented a production-grade distributed token bucket rate limiter using Redis Lua to protect authentication, messaging, and feed endpoints in my LinkedUp social platform.
introduction
When building LinkedUp, a LinkedIn-style social platform, I quickly realized that traditional middleware-based rate limiting was insufficient. A social system exposes high-frequency endpoints such as login, messaging, feed fetching, and media streaming. Without proper protection, these endpoints become trivial targets for brute-force attacks, spam, and scraping. This post explains how I designed a distributed, production-grade rate limiting system using Redis and Lua scripting.
problem statement
Basic rate limiting solutions (like in-memory counters or fixed-window Express middleware) fail in distributed systems. LinkedUp runs across multiple instances, meaning memory-based counters are inconsistent. Additionally, fixed-window rate limiting allows burst attacks at window boundaries. I needed a solution that was atomic, distributed, burst-tolerant, and performant under high concurrency.
threat model
{
"authentication_abuse": "Attackers attempting brute-force login by rotating passwords or usernames.",
"message_spam": "Users sending large volumes of messages in short timeframes.",
"feed_scraping": "Bots repeatedly requesting feed endpoints to scrape data.",
"api_flooding": "High-frequency calls designed to exhaust CPU or event loop capacity."
}naive implementation and its failure
Initially, I considered Express middleware like express-rate-limit. However, it relies on in-memory storage or simple Redis counters. Fixed window counters allow burst traffic at window edges and lack fine-grained refill control. In a horizontally scaled environment, this approach becomes inconsistent and vulnerable.
design decision
{
"algorithm_choice": "Token Bucket",
"reasoning": "Token bucket allows controlled bursts while maintaining a steady refill rate. It is more flexible than fixed window and simpler than sliding window log implementations.",
"storage_layer": "Redis",
"atomicity_strategy": "Lua scripting to ensure atomic read-modify-write operations."
}architecture overview
Each protected endpoint uses a Redis-backed token bucket keyed by user ID (or IP fallback if unauthenticated). The bucket stores the current token count and last refill timestamp. Every request executes a Lua script that calculates token refill, checks availability, deducts tokens, and returns allow/deny — all atomically.
lua script core logic
The Lua script calculates elapsed time since last refill, adds tokens proportionally based on refill rate, caps at maximum capacity, checks if at least one token exists, decrements if allowed, and stores updated state. This entire process runs inside Redis to prevent race conditions.
implementation example
{
"node_wrapper": "Each endpoint calls the Redis script using EVALSHA. If the script returns 0, the request is blocked with HTTP 429. If 1, the request proceeds.",
"example_use_cases": [
"loginLimiter (IP + username composite key)",
"messageTokenLimiter (capacity 10, refillRate 0.2/sec)",
"feedFetchLimiter",
"conversationFetchLimiter"
]
}why lua was critical
- Ensures atomic updates under concurrency
- Prevents race conditions
- Reduces network round-trips
- Maintains consistent state across distributed instances
security improvements over time
- IPv6-safe IP extraction
- User ID–based keys for authenticated requests
- Separate limiters for login, signup, logout
- Differentiated capacities for messaging vs feed fetching
tradeoffs
{
"pros": [
"Distributed and horizontally scalable",
"Burst-friendly",
"Atomic operations",
"Low latency"
],
"cons": [
"Requires Redis availability",
"Adds operational complexity",
"Needs careful capacity tuning"
]
}lessons learned
- Rate limiting must be designed per endpoint behavior.
- Authentication endpoints require stricter policies than feed reads.
- Atomicity is non-negotiable in distributed systems.
- Security mechanisms must evolve as the system grows.
future improvements
- Adaptive rate limits based on user trust score
- Dynamic throttling under high system load
- Integration with CDN-level rate limiting for media endpoints
conclusion
Rate limiting is not just middleware — it is a core architectural component in any real-world social platform. By implementing Redis Lua token buckets, I built a scalable, abuse-resistant protection layer for LinkedUp. This system now safeguards authentication, messaging, and feed endpoints while maintaining performance under distributed load.