Idempotent Actions
An idempotent action produces the same result whether it is executed once or many times. Designing agent actions to be idempotent makes retries safe and prevents duplicate side effects.
6 min•By Priygop Team•Updated 2026
Making Actions Idempotent
- Use idempotency keys: include a unique request ID in every API call so the server deduplicates retries
- Check before write: before creating a record, check if it already exists with the same ID
- Use upsert operations: 'create if not exists, update if exists' avoids duplicate records
- Store action results: after completing an action, record it in state so it is not repeated on retry
- Use conditional writes: only write if the current version matches the expected version
Idempotency Key Example
Idempotency Key Example
import uuid
# Idempotent refund using an idempotency key
def issue_refund_idempotent(
order_id: str,
amount: float,
idempotency_key: str = None
) -> dict:
"""
Issue a refund idempotently.
If the same idempotency_key is sent twice, the second call
returns the result of the first call without charging again.
"""
# Generate a deterministic key from the order + amount if not provided
if not idempotency_key:
idempotency_key = f"refund-{order_id}-{int(amount*100)}"
# Check if we already processed this refund
completed_refunds = {} # In production: database lookup
if idempotency_key in completed_refunds:
print(f" Idempotent: returning cached result for key {idempotency_key}")
return completed_refunds[idempotency_key]
# Process the refund (simulated)
result = {
"status": "success",
"refund_id": f"REF-{str(uuid.uuid4())[:8]}",
"order_id": order_id,
"amount": amount,
"idempotency_key": idempotency_key
}
# Store the result so retries return the same refund_id
completed_refunds[idempotency_key] = result
print(f" Refund processed: {result['refund_id']} (key: {idempotency_key})")
return result
# First call — processes the refund
r1 = issue_refund_idempotent("ORD-123", 49.99)
# Retry (e.g., after a timeout) — returns same result, no duplicate
r2 = issue_refund_idempotent("ORD-123", 49.99)
print(f"Same refund ID? {r1['refund_id'] == r2['refund_id']}")Key Takeaways
- An idempotent action produces the same result whether it is executed once or many times.
- Use idempotency keys: include a unique request ID in every API call so the server deduplicates retries
- Check before write: before creating a record, check if it already exists with the same ID
- Use upsert operations: 'create if not exists, update if exists' avoids duplicate records