Skip to content
← all posts

Why I wrote reliakit

2026-06-09·2 min read·0 views

Every time I build a service, it's the same problems: rate limiting, timeouts, retries, circuit breakers, input validation, keeping secrets out of logs. The "boring" stuff that, ironically, is what most often blows up in production.

I got tired of copy-pasting the same utilities from project to project, or pulling in a huge framework just for one small function. So I built reliakit.

The philosophy

reliakit is a set of reliability building blocks — small, composable, and no_std + zero-dependency wherever possible. Not a framework that forces its way on you; you take only what you need.

Each capability is its own crate:

  • ratelimit — a token-bucket rate limiter.
  • circuit — a circuit breaker: when a dependency is down, fail fast instead of piling up requests.
  • backoff — retries with backoff (exponential/linear/constant) + jitter.
  • timeout — clock-agnostic deadlines.
  • primitives — validated types: Email, HttpUrl, NonEmptyStr, Port, etc.
  • secret — wrap sensitive values so they never leak into logs or errors.

...plus a few more (bulkhead, health, validate, collections, json, codec, core, decide). 16 crates total, each usable on its own.

I use it on this site

Not just theory — the blog you're reading is guarded by reliakit:

  • The newsletter & contact forms are rate-limited with ratelimit to stop bot spam.
  • Email sending is guarded by a circuit breaker — if the provider is down, it won't hang.
  • The API key lives in a secret, so it can't leak into logs.
  • Emails are validated with primitives::Email.

You can even try the rate limiter right in your browser (it runs via WASM) in the playground on the Projects page.

Example

use reliakit::ratelimit::RateLimiter;

// 5 tokens, refill 1 every 2 seconds
let mut limiter = RateLimiter::new(5, 1, 2);

if limiter.try_acquire_one(now) {
    // go ahead
} else {
    // rate limited
}

That small. No background thread, it doesn't read the clock itself — you pass the time in, which makes it easy to test and deterministic.

Wrapping up

reliakit is still early (v0.1), but I already use it for real. If you're a Rust dev tired of re-copying the same reliability utilities, give it a try. Feedback and issues welcome on GitHub.