Rack Idempotency Kit
Stripe-style idempotency for Rack and Rails APIs.
About
Rack Idempotency Kit ensures that repeated requests with the same idempotency key replay the original response instead of executing the action twice. It protects against retries, network timeouts, and client-side duplications.
The middleware stores a fingerprint of the request and a completed response. If the same key is used with different request parameters, it returns a conflict.
Use Cases
- Payment, checkout, and webhook endpoints with retries
- API clients with timeouts and automatic replays
- Protecting side-effecting endpoints from duplicate writes
- Reducing p99 spikes caused by retry storms
Compatibility
- Ruby 3.0+
- Rack 2.2+
- Works with Rails middleware stack
Elysium Arc Reliability Toolkit
Also check out these related gems:
- Cache Coalescer: https://github.com/Elysium-Arc/cache-coalescer
- Cache SWR: https://github.com/Elysium-Arc/cache-swr
- Faraday Hedge: https://github.com/Elysium-Arc/faraday-hedge
- Env Contract: https://github.com/Elysium-Arc/env-contract
Installation
# Gemfile
gem "rack-idempotency-kit"Usage (Rails)
# config/application.rb
config.middleware.use Rack::Idempotency::Kit,
store: Rails.cache,
ttl: 86_400,
header: "Idempotency-Key"Usage (Rack)
use Rack::Idempotency::Kit,
store: MyStore.new,
ttl: 86_400,
header: "Idempotency-Key"Options
-
storestorage backend -
ttl(Integer) response retention in seconds -
header(String) idempotency header name -
methods(Array) HTTP methods to protect -
wait_timeout(Float) wait time for in-flight requests -
lock_ttl(Integer) in-flight lock TTL in seconds -
max_body_bytes(Integer) maximum body size to store
Store Backends
- ActiveSupport cache stores (
read/write) - Redis-style stores (
get/set)
Behavior
- Replays stored responses for repeated idempotency keys
- Returns
409if the same key is reused with a different request fingerprint - Returns
409if a request is still in flight afterwait_timeout
Release
bundle exec rake release