Rate Limiting in C++: Libraries and Tools for Request Control

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Rate Limiting in C++: A Complete Guide to Request Limiting



Rate limiting is a critically important mechanism for protecting servers, APIs, and distributed systems from overloads, DDoS attacks, and random traffic spikes. In C++, implementing rate limiting requires efficient algorithms and the right choice of libraries. In this article, we will break down the main approaches, popular libraries, and provide ready-made code examples.



What is rate limiting and why is it needed?

Rate limiting sets the maximum number of requests a client or system can perform within a specific time period. The main goals are:

  • Protection from abuse and server overload
  • Ensuring fair distribution of resources among users
  • Preventing DDoS attacks and brute-force attacks
  • Controlling API quota consumption


Basic rate limiting algorithms

In C++, three classic algorithms are most commonly used:



1. Token Bucket

The most popular algorithm. It represents a "bucket" of tokens that are replenished at a constant rate. Each request takes one token. If there are no tokens, the request is rejected.

#include <chrono>#include <mutex>

class TokenBucket {private: double tokens; double maxTokens; double refillRate; // tokens per second std::chrono::steady_clock::time_point lastRefill; std::mutex mtx;

public: TokenBucket(double maxTokens, double refillRate) : tokens(maxTokens), maxTokens(maxTokens), refillRate(refillRate) { lastRefill = std::chrono::steady_clock::now(); }

bool tryConsume() { std::lock_guard<std::mutex> lock(mtx); refill(); if (tokens >= 1.0) { tokens -= 1.0; return true; } return false; }

private: void refill() { auto now = std::chrono::steady_clock::now(); auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - lastRefill).count() / 1000.0; tokens = std::min(maxTokens, tokens + elapsed * refillRate); lastRefill = now; }};


2. Leaky Bucket

Requests enter a queue (bucket) which is processed at a fixed rate. If the bucket overflows, requests are discarded.

#include <queue>#include <chrono>

class LeakyBucket {private: std::queue<int> bucket; size_t capacity; double leakRate; // requests per second std::chrono::steady_clock::time_point lastLeak; std::mutex mtx;

public: LeakyBucket(size_t capacity, double leakRate) : capacity(capacity), leakRate(leakRate) { lastLeak = std::chrono::steady_clock::now(); }

bool addRequest(int request) { std::lock_guard<std::mutex> lock(mtx); leak(); if (bucket.size() < capacity) { bucket.push(request); return true; } return false; }

private: void leak() { auto now = std::chrono::steady_clock::now(); auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - lastLeak).count() / 1000.0; size_t toRemove = static_cast<size_t>(elapsed * leakRate); while (toRemove > 0 && !bucket.empty()) { bucket.pop(); toRemove--; } lastLeak = now; }};


3. Sliding Window Log

Stores timestamps of requests and discards those that fall outside the window. More accurate, but requires more memory.



Popular C++ libraries for rate limiting

Although the C++ standard library does not contain ready-made solutions, there are proven libraries:

Recommendations