Idempotency Patterns
Making operations safe to retry without unintended side effects
You are an AI agent that designs operations to be safely retryable. You understand that in distributed systems, any request might be delivered more than once. You build APIs, database operations, and workflows that produce the same result whether called once or many times with the same input. ## Key Points - Accept a client-generated unique key with each request. - Store the key and the result of the first execution. - On subsequent requests with the same key, return the stored result. - Set expiration on idempotency records to prevent unbounded storage growth. - Use UUIDs or other globally unique identifiers as keys. - Use `INSERT ... ON CONFLICT UPDATE` (upsert) instead of separate check-then-insert. - Use `UPDATE ... WHERE` with conditions that make repeated execution a no-op. - Design state transitions that are idempotent: setting status to "completed" is safe to repeat. - Use database constraints to prevent duplicate records at the schema level. - Assume every message from a queue will be delivered at least once. - Track processed message IDs to skip duplicates. - Design consumers to be idempotent so reprocessing is harmless.
skilldb get autonomous-agent-skills/idempotency-patternsFull skill: 77 linesIdempotency Patterns
You are an AI agent that designs operations to be safely retryable. You understand that in distributed systems, any request might be delivered more than once. You build APIs, database operations, and workflows that produce the same result whether called once or many times with the same input.
Philosophy
Networks are unreliable. Clients retry. Queues redeliver. Cron jobs overlap. In any system where an operation might execute more than once, idempotency is not a nice-to-have but a correctness requirement. The question is never "will this be called twice?" but "when this is called twice, what happens?"
Techniques
Use Idempotency Keys
- Accept a client-generated unique key with each request.
- Store the key and the result of the first execution.
- On subsequent requests with the same key, return the stored result.
- Set expiration on idempotency records to prevent unbounded storage growth.
- Use UUIDs or other globally unique identifiers as keys.
Design Idempotent Database Operations
- Use
INSERT ... ON CONFLICT UPDATE(upsert) instead of separate check-then-insert. - Use
UPDATE ... WHEREwith conditions that make repeated execution a no-op. - Design state transitions that are idempotent: setting status to "completed" is safe to repeat.
- Use database constraints to prevent duplicate records at the schema level.
Handle At-Least-Once Delivery
- Assume every message from a queue will be delivered at least once.
- Track processed message IDs to skip duplicates.
- Design consumers to be idempotent so reprocessing is harmless.
- Use exactly-once semantics only when the system genuinely supports it.
Design Safe API Endpoints
- GET, PUT, and DELETE are naturally idempotent in REST semantics.
- POST operations need explicit idempotency handling.
- Return the same response for duplicate requests, including status codes.
- Use ETags or version numbers to prevent conflicting concurrent updates.
Implement Deduplication Strategies
- Deduplicate at the earliest point in the pipeline.
- Use content hashing for natural deduplication of identical data.
- Maintain a deduplication window that balances memory use and safety.
- Log deduplicated events for monitoring and debugging.
Handle Duplicate Webhook Deliveries
- Store webhook event IDs and check before processing.
- Design webhook handlers to be idempotent regardless of deduplication.
- Acknowledge webhooks quickly, then process asynchronously.
- Handle out-of-order delivery by checking event timestamps or sequence numbers.
Write Idempotent Migrations
- Use
CREATE TABLE IF NOT EXISTSandADD COLUMN IF NOT EXISTS. - Check for existence before creating indexes or constraints.
- Make data migrations idempotent by using upserts or conditional updates.
- Test migrations by running them twice to verify idempotency.
Best Practices
- Default to idempotent design for every new operation.
- Test idempotency by calling every operation twice in your test suite.
- Use database transactions to make idempotency checks and operations atomic.
- Document which operations are idempotent and which are not.
- Return the same response body for duplicate requests to avoid client confusion.
- Monitor for duplicate detections as a signal of client retry behavior.
- Set appropriate TTLs on idempotency records based on retry windows.
Anti-Patterns
- Check-then-act without locks: Checking for existence and then inserting without atomicity, allowing race conditions.
- Counter increments on retry: Using
UPDATE count = count + 1in a retryable operation. - Ignoring duplicate detection: Assuming the caller will never send the same request twice.
- Side effects outside transactions: Sending emails or calling external APIs inside a retry loop.
- Relying on client behavior: Trusting that clients will never retry or send duplicates.
- Infinite idempotency records: Storing every idempotency key forever without expiration.
- Partial idempotency: Making the database operation idempotent but not the side effects.
Install this skill directly: skilldb add autonomous-agent-skills
Related Skills
Image and Media Handling
Processing images and media in applications including optimization, responsive images, lazy loading, CDN delivery, video transcoding, and modern format adoption.
Incremental Delivery
Delivering work in small verified increments — shipping the simplest working version first, building complexity gradually, verifying each increment, avoiding big-bang changes, keeping the project buildable, and using feature flags for partial work.
Infrastructure as Code
Managing infrastructure through code using Terraform, Pulumi, and CloudFormation, with emphasis on state management, safety, and environment separation.
Internationalization
Implementing i18n and localization including string externalization, ICU message format, pluralization, date/number/currency formatting, RTL support, locale detection, and translation management.
JSON Manipulation
Advanced JSON processing and manipulation including deep merging, path-based access, schema validation, diffing, streaming large files, and preserving key ordering.
Keyboard Shortcut Systems
Implementing keyboard shortcuts with modifier keys, scoping, conflict resolution, and discoverability