Skip to main content

truschery/idem

Idempotency for HTTP requests, queued jobs, and arbitrary operations in Laravel.

Run once. Reply forever.

$

// quick start

// 1. HTTP Route — attach middleware
Route::post('/checkout', CheckoutController::class)
->middleware('idempotent');

// 2. Job — prevent duplicate execution
public function middleware(): array
{
return [new EnsureIdempotent];
}

// 3. Facade — once for any callback
Once::do('send-welcome', fn() =>
Mail::to($user)->send(new WelcomeMail)
);

// core features

01

HTTP Middleware

Idempotent

Attach to any route. Clients send an Idempotency-Key header — duplicate requests get the cached response instantly, without touching your handler.

view documentation
02

Job Middleware

EnsureIdempotent

Prevent queued jobs from executing more than once. Even if a job is dispatched multiple times, it runs exactly one time — safe under retry storms.

view documentation
03

Once Facade

Once::do()

Wrap any arbitrary closure in Once::do() to guarantee it executes exactly once, regardless of how many times it's invoked across requests or jobs.

view documentation

// roadmap

What's shipped
& what's next

truschery/idem ships with all the building blocks for robust idempotency in Laravel. More tests and refinements are on the way.

5 of 7 milestones complete
Idempotent
HTTP Middleware
Route-level idempotency via Idempotency-Key header
EnsureIdempotent
Job Middleware
Prevent queued jobs from executing more than once
Once::do()
Once::do() facade
Arbitrary callback idempotency for any operation
store
Cache & Database drivers
Two storage backends out of the box
idem:prune
Artisan idem:prune command
Remove expired records from the database
security-integrity
Safe unserialize for callback caching
Encrypt serialized data using Crypt before saving to store
tests
Extended tests for Job middleware & Once::do()
Comprehensive test coverage for all middleware