What Is an Idempotency Key?

Click "Submit" twice by accident? Without idempotency protection, you might create duplicate transactions. Here's how enterprise systems prevent this.

3 min read Foundations

You click "Post Payment" and nothing seems to happen. So you click again. And again.

Later, you discover three identical payments posted to the same account.

This is the duplicate transaction problem. Idempotency keys solve it.

The Problem

Network requests can fail or timeout without telling you whether they succeeded. Did the server:

  • Never receive your request?
  • Receive it but crash before responding?
  • Process it successfully but the response got lost?

Without knowing which happened, you're stuck. Retrying might create duplicates. Not retrying might lose the transaction.

What Is Idempotency?

An operation is idempotent if performing it multiple times has the same effect as performing it once.

Idempotent: Setting a thermostat to 72°. Do it once or ten times—the result is 72°.

Not idempotent: Adding $100 to an account. Do it twice, you've added $200.

Financial transactions are not naturally idempotent. We make them idempotent using keys.

How Idempotency Keys Work

  1. Client generates a unique key before the request (e.g., a UUID)
  2. Client sends the key with the request
  3. Server checks: Have I seen this key before?
  4. If no: Process the request, store the key
  5. If yes: Return the previous result without re-processing
  6. Client can safely retry with the same key
Request 1: POST /payment {amount: 500, idempotency_key: "abc-123"}
→ Server: New key, process payment, store key, return success

Request 2: POST /payment {amount: 500, idempotency_key: "abc-123"}
→ Server: Key exists, return previous success (no new payment)

The Journal Entry Application

For HOA accounting, idempotency matters when:

  • Posting assessment payments
  • Recording vendor payments
  • Creating journal entries
  • Processing recurring transactions

Each of these operations should have an idempotency key that prevents duplicates.

Example: Assessment Payment

A payment comes in from Stripe. The webhook might fire multiple times (Stripe retries on timeout). Without idempotency:

Webhook 1: Create journal entry for $500 payment
Webhook 2: Create another journal entry for $500 payment
Webhook 3: Create yet another journal entry for $500 payment

Homeowner paid once, but you recorded three payments. Chaos.

With idempotency:

Webhook 1: Key "stripe_pi_123" → Create entry, store key
Webhook 2: Key "stripe_pi_123" → Key exists, skip
Webhook 3: Key "stripe_pi_123" → Key exists, skip

One payment, one entry. Correct.

Implementation Requirements

True idempotency requires:

1. Unique Key Storage

The idempotency key must be stored in the database with a unique constraint. The database itself prevents duplicates.

2. Atomic Check-and-Set

Checking for the key and creating the record must happen atomically. Otherwise, race conditions can still create duplicates.

3. Appropriate Key Scope

Keys should be scoped appropriately: - Payment keys: Per payment intent - Journal entry keys: Per source transaction - Transfer keys: Per transfer request

4. Key Expiration (Optional)

Some systems expire keys after a period (e.g., 24 hours). This prevents key table bloat while still protecting against immediate retries.

What "No Idempotency" Looks Like

Without idempotency protection:

  • Double-clicking creates duplicates
  • Network retries create duplicates
  • Webhook retries create duplicates
  • Import processes create duplicates on re-run
  • Users must manually check for and delete duplicates

This is how most small-business accounting software works. It's why "duplicate payment" is a common support ticket.

The Enterprise Standard

Enterprise payment systems (Stripe, banks, ERPs) all use idempotency keys. It's not a nice-to-have—it's a requirement for reliable financial operations.

When evaluating accounting software, ask:

"If I accidentally submit a transaction twice, what prevents duplicate postings?"

If the answer is "be careful" or "we'll clean it up later," that's not enterprise-grade.


How CommunityPay Enforces This
  • Duplicate posting attempts rejected at database level
  • Idempotency key stored on every journal entry
  • Unique constraint prevents duplicate transactions
  • Safe retry behavior for all critical operations
Login