https://github.com/minhqdao/zimit
Hey there ![]()
I’ve been wanting to build something in Zig for a while and now I finished my rate limiter. ![]()
It implements the GCRA (Generic Cell Rate Algorithm) with a token-bucket-like API (which is more intuitive/user-friendly) and it is compatible with Zig 0.16.0. It supports per-key rate limiting (e.g. per IP address or user ID) and global limiting (e.g. if you want to protect your resource).
You can use it like this:
const std = @import("std");
const zimit = @import("zimit");
pub fn main(init: std.process.Init) !void {
const io = init.io;
var sys = zimit.SystemClock.init(io);
var limiter = try zimit.GlobalLimiter.init(.{
.rate = 100,
.per = .second,
.burst = 20,
.clock = sys.clock(),
});
switch (limiter.allow()) {
.allowed => std.debug.print("allowed\n", .{}),
.denied => |d| {
std.debug.print("denied, time until allowed: {d}ms\n", .{d.retry_after_ms_ceil()});
},
}
}
GlobalLimiter is thread-safe, RateLimiter is not because it uses a hash map. So make sure to wrap it with a std.Io.Mutex when using it in a multi-threading environment.
Feel free to try it out, let me know if there is anything I can improve and I’m happy to work on it. ![]()