Evidence ledger 28 sources Checked 01 Sep 2026

Evidence ledger

One row per claim in A timeout is not an answer: making retried requests safe: who published it, what grade it carries, when it was written, when the link was last checked, and the quote or figure it rests on. Nothing in the guide is cited from memory, so anything not in this table is not in the guide.

Topic: how production systems make a resent request harmless (idempotency keys, client tokens, dedupe stores), what the guarantee actually covers, and how the machinery itself fails.

Research date: 2026-09-01. All sources checked 2026-09-01.

Access note for this session: the research environment's egress proxy allowed direct fetches only of raw.githubusercontent.com. Rows marked fetched were retrieved in full and quotes are copied verbatim from the fetched bytes. Rows marked search-verified were confirmed to exist via live web-search results on the research date; the supporting quote or figure is copied from the search result content for that page, not from a full page fetch. No row is cited from memory.

# Org Title Tier Published Checked URL Claim I take from it Supporting quote or figure
1 Stripe (Brandur Leach) Implementing Stripe-like Idempotency Keys in Postgres blog 2017-10-27 2026-09-01 fetched (via mirror raw.githubusercontent.com/brandur/sorg) https://brandur.org/idempotency-keys The unit of design is the foreign state mutation; local work groups into atomic phases between them "To shore up our backend, it's key to identify where we're making foreign state mutations... once we make our first foreign state mutation, we're committed one way or another."
2 Stripe (Brandur Leach) Implementing Stripe-like Idempotency Keys in Postgres blog 2017-10-27 2026-09-01 fetched https://brandur.org/idempotency-keys Even internal Kafka produces count as foreign mutations "It's tempting to treat emitting records to Kafka as part of atomic operations because they have such a high success rate that they feel like they are. They're not, and should be treated like any other fallible foreign state mutation."
3 Stripe (Brandur Leach) Implementing Stripe-like Idempotency Keys in Postgres blog 2017-10-27 2026-09-01 fetched https://brandur.org/idempotency-keys Recovery points let a retry resume rather than restart; keys are recycled ~24-72h "A recovery point is a name of a check point that we get to after having successfully executed any atomic phase or foreign state mutation... Servers should recycle them out of the system beyond a horizon where they won't be of much use -- say 24 hours or so." Reaper suggestion: "a threshold of about 72 hours".
4 Stripe (Brandur Leach) Implementing Stripe-like Idempotency Keys in Postgres blog 2017-10-27 2026-09-01 fetched https://brandur.org/idempotency-keys Clients cannot be relied on to finish their own retries; a server-side completer is needed "there can be cases where a client starts working, never quite finishes, and drops forever. A stretch goal is to implement a completer. Its only job is to find requests that look like they never finished... and push through to completion."
5 Stripe (Brandur Leach) Implementing Stripe-like Idempotency Keys in Postgres blog 2017-10-27 2026-09-01 fetched https://brandur.org/idempotency-keys None of this works without local transactions "It's worth mentioning that none of this is possible on a non-ACID store... every operation against your database becomes equivalent to a foreign state mutation because the notion of an atomic phase is impossible."
6 Stripe Designing robust and predictable APIs with idempotency blog 2017-02 2026-09-01 search-verified https://stripe.com/blog/idempotency The client half of the contract: same key on retry, backoff with jitter Search-result content: "When performing a request, a client generates a unique ID to identify the operation and sends it to the server... If the client notices a failure, it retries with the same ID"; "The Stripe Ruby library retries on failure automatically with an idempotency key using increasing backoff times and jitter."
7 Stripe API reference: Idempotent requests vendor current docs 2026-09-01 search-verified https://docs.stripe.com/api/idempotent_requests The guarantee has a 24-hour horizon, after which the same key is a new request Search-result content: "You can remove keys from the system automatically after they're at least 24 hours old. We generate a new request if a key is reused after the original is pruned."
8 Stripe stripe-ruby lib/stripe/api_requestor.rb (master) source current (fetched from master) 2026-09-01 fetched https://github.com/stripe/stripe-ruby/blob/master/lib/stripe/api_requestor.rb The client library auto-generates a key the moment retries are enabled, because retrying POST without one is unsafe Code comment: "It is only safe to retry network failures on post and delete requests if we add an Idempotency-Key header"; code: headers["Idempotency-Key"] ||= SecureRandom.uuid.
9 Stripe stripe-ruby lib/stripe/api_requestor.rb (master) source current 2026-09-01 fetched https://github.com/stripe/stripe-ruby/blob/master/lib/stripe/api_requestor.rb Stripe's server replays stored 500 responses for a reused key rather than re-executing Code comment: "we expect the stripe-should-retry header to be false in most cases when a 500 is returned, since our idempotency framework would typically replay it anyway."
10 Airbnb (Jon Chew) Avoiding double payments in a distributed payments system blog 2019-04 2026-09-01 search-verified https://medium.com/airbnb-engineering/avoiding-double-payments-in-a-distributed-payments-system-2981f6b070bb Orpheus splits every request into Pre-RPC / RPC / Post-RPC and classifies errors as retryable or non-retryable; dedupe store is sharded by key Search-result content: "Orpheus is centered around the assumption that almost every standard API request can be separated into three distinct phases: Pre-RPC, RPC, and Post-RPC"; "error responses classified as 'retryable' or 'non-retryable'"; "Airbnb alleviated scaling issues by sharding the database by idempotency key"; clients use "write repair... repeatedly fire the same request without maintaining state besides retries."
11 Twilio Billing Incident Post-Mortem: Breakdown, Analysis and Root Cause postmortem 2013-07 2026-09-01 search-verified https://www.twilio.com/en-us/blog/company/communications/billing-incident-post-mortem-breakdown-analysis-and-root-cause-html A retry loop with a real charge inside and no dedupe on the external side charged cards repeatedly; the fix was an independent record and a fail-safe Search-result content: an incorrect configuration caused "redis-master to boot as a slave of itself, putting it in read-only mode"; the auto-recharge service "billed the customers before updating their balance internally" and "continued to retry the transaction again and again, resulting in multiple charges to customer's credit cards"; on-call engineers "shut down the billing system to prevent further charges" at 4:10 AM PDT; remediation: "if billing balances don't exist or cannot be written, the system will not suspend accounts or charge credit cards."
12 antirez (Salvatore Sanfilippo) Twilio incident and Redis blog 2013-07 2026-09-01 search-verified https://antirez.com/news/60 Independent analysis by the datastore's author: the billing state was held in an in-memory master-slave setup that resynchronized en masse Search-result content: the incident involved "a Redis server used to store in-flight account balances in a master-slaves setup"; network partition caused "all redis-slaves to reconnect and request full synchronization with the master at the same time."
13 CircleCI Post Incident Report: December 2, 2025 (workflows, duplicate events) postmortem 2025-12 2026-09-01 search-verified https://status.circleci.com/incidents/fjpg0vmh476k Duplicate completion events plus a non-idempotent consumer (auto-rerun) created duplicate workflows and cascade Search-result content: a deploy "introduced a race condition in how workflows are terminated. When workflows failed with concurrent jobs terminating, their system published duplicate workflow completion events. For customers with auto-rerun enabled, these duplicate events triggered duplicate workflows to be created, causing cascading issues"; duplicate workflows and duplicate emails Dec 2 16:20 - Dec 3 14:20; fully resolved Dec 3 22:50.
14 Zuora Incident: duplicate charges through legacy Vantiv gateway postmortem 2024-11 2026-09-01 search-verified https://trust.zuora.com/incidents/h3t74vcgl9nd An unmapped gateway response code was treated as a failure and retried, producing duplicate charges Search-result content: "an issue affecting payment processing through the legacy Vantiv gateway, which may have resulted in duplicate charges. Response code 136 was introduced by the Vantiv gateway on Nov-05, and the team worked on response code mapping to fix the issue."
15 Coinbase / Visa / Worldpay Joint Statement from Visa and Worldpay for Coinbase customers postmortem 2018-02 2026-09-01 search-verified https://blog.coinbase.com/joint-statement-from-visa-and-worldpay-for-coinbase-customers-9a6f2ff5f3b3 Reversal-and-repost inside the card network itself produced duplicates at the customer; the dedupe boundary was below everyone's application code Joint statement quote (via coverage): "This issue was not caused by Coinbase. Worldpay and Coinbase have been working with Visa and Visa issuing banks to ensure that the duplicate transactions have been reversed and appropriate credits have been posted to cardholder accounts." Trigger per Visa spokesperson: an incorrect merchant category code change; Visa "refunded and recharged transactions under a different merchant category" (TechCrunch, CNBC coverage, 2018-02-16/17).
16 TechCrunch Visa confirms Coinbase wasn't at fault for overcharging users casestudy 2018-02-16 2026-09-01 search-verified https://techcrunch.com/2018/02/16/visa-coinbase-not-at-fault/ Scale of the 2018 duplicate-charge event: some cards charged dozens of times, overdrafts caused Search-result content: "Some customers reported losing tens of thousands after being charged 17, even 50 times. The duplicate charges drained customers' bank accounts and generated costly overdraft fees."
17 IETF HTTPAPI WG (Jena, Dalal) The Idempotency-Key HTTP Header Field (draft-ietf-httpapi-idempotency-key-header) adr draft-07 2025-10-15; source fetched from main 2026-09-01 fetched (raw.githubusercontent.com/ietf-wg-httpapi/idempotency) https://datatracker.ietf.org/doc/draft-ietf-httpapi-idempotency-key-header/ The would-be standard: key MUST be unique and MUST NOT be reused with a different payload; retry after completion replays the result, concurrent retry gets a conflict Fetched draft text: "The idempotency key MUST be unique and MUST NOT be reused with another request with a different request payload"; enforcement: retry "SHOULD respond with the result of the previously completed operation"; concurrent request "SHOULD respond with a resource conflict error".
18 IETF HTTPAPI WG Idempotency-Key draft, Implementation Status section adr draft-07 2025-10-15 2026-09-01 fetched https://datatracker.ietf.org/doc/draft-ietf-httpapi-idempotency-key-header/ At least 20 named organisations run the pattern, under at least 9 different header/field names Fetched draft lists Stripe, Adyen, Dwolla, Interledger, WorldPay, Yandex, http4s, Finastra, Datatrans under Idempotency-Key, and Django, Chargebee, Twilio, PayPal (PayPal-Request-Id), RazorPay, OpenBanking (x-idempotency-key), Square (body idempotency_key), Google Standard Payments (requestId), BBVA (X-Unique-Transaction-ID), WebEngage (x-request-id) as implementing the concept differently.
19 IETF (Mark Nottingham) POST Once Exactly (POE), draft-nottingham-http-poe-00 adr 2005-03, expired 2005-09-17 2026-09-01 search-verified https://datatracker.ietf.org/doc/html/draft-nottingham-http-poe-00 The first attempt to standardise safe POST retry expired in 2005; the current draft credits it Search-result content: "A POE resource will respond to a POST request successfully exactly once... The Internet-Draft expired on September 17, 2005." Fetched current draft acknowledges it: "this draft is inspired by... Internet Draft on POST Once Exactly authored by Mark Nottingham."
20 IETF HTTPAPI WG Issue #36: What value does Idempotency Fingerprint add? source open issue 2026-09-01 search-verified https://github.com/ietf-wg-httpapi/idempotency/issues/36 The fingerprint (payload binding) is still an unsettled design argument in the standards process Search-result content: the issue questions "what value the idempotency fingerprint adds, and what would be the consequences of two requests with the same idempotency-key but different fingerprints"; related concern that sections 2.4 and 2.6 of the spec "seemed to conflict."
21 Pat Helland (Amazon/Salesforce) Idempotence Is Not a Medical Condition paper 2012-04 (ACM Queue 10(4), pp. 30-46) 2026-09-01 search-verified https://queue.acm.org/detail.cfm?id=2187821 Retries are a property of the substrate, so idempotence is mandatory, not optional Search-result content: "messages sent between systems do not have crisp guarantees for delivery and can get lost, so after a timeout they are retried"; "every message may be retried and, hence, must be idempotent." Published April 2012, 69,000+ downloads per ACM DL.
22 Stanford (Lee, Park, Ousterhout et al.) Implementing Linearizability at Large Scale and Low Latency (RIFL), SOSP 2015 paper 2015-10 2026-09-01 search-verified https://web.stanford.edu/~ouster/cgi-bin/papers/rifl.pdf Exactly-once RPC is a reusable layer with four sub-problems, and it is cheap: under 4% on a 13.5 µs write Search-result content: "RIFL provides a general-purpose mechanism for converting at-least-once RPC semantics to exactly-once semantics"; must solve "RPC identification, completion record durability, retry rendezvous, and garbage collection"; "adds less than 4% to the 13.5 μs base cost for writes, and simple distributed transactions execute in about 20 μs."
23 Xerox PARC (Birrell, Nelson) Implementing Remote Procedure Calls paper 1984 (ACM TOCS 2(1)) 2026-09-01 search-verified https://web.eecs.umich.edu/~mosharaf/Readings/RPC.pdf The client-generated unique request identifier for duplicate elimination is 40+ years old Search-result content: "The call identifier structure is and allows elimination of duplicate call packets"; the callee "must not execute the procedure a second time" when the acknowledgment is lost.
24 Apache Kafka KIP-98: Exactly Once Delivery and Transactional Messaging adr 2016-11 (implemented Kafka 0.11, 2017) 2026-09-01 search-verified https://cwiki.apache.org/confluence/display/KAFKA/KIP-98+-+Exactly+Once+Delivery+and+Transactional+Messaging Broker-side dedupe by (producer id, per-partition sequence number), the same mechanism as TCP Search-result content: "it works in a way similar to TCP: each batch of messages sent to Kafka will contain a sequence number that the broker will use to dedupe any duplicate send"; adding PID and epoch to the message format "potentially adds a considerable amount of overhead."
25 Apache Kafka KIP-679: Producer will enable the strongest delivery guarantee by default adr 2020-10 (shipped Kafka 3.0, 2021) 2026-09-01 search-verified https://cwiki.apache.org/confluence/display/KAFKA/KIP-679:+Producer+will+enable+the+strongest+delivery+guarantee+by+default It took 4 years to make idempotence the default, and the stated cost was negligible Search-result content: "the default value of acks will change to all and enable.idempotence will change to true"; analysis "indicates that changing acks from 1 to all won't increase the latency and decrease the throughput in a significant way."
26 Apache Kafka KAFKA-13598: idempotence producer is not enabled by default if not set explicitly source 2022-01, fixed 3.0.⅓.1.⅓.2.0 2026-09-01 search-verified https://issues.apache.org/jira/browse/KAFKA-13598 The idempotence-by-default change shipped broken: the flag read true but validation logic never applied it, in 3.0.0 and 3.1.0 Search-result content: "In 3.0.0 and 3.1.0, a bug prevented the idempotence default from being applied, which meant that idempotence remained disabled unless the user had explicitly set enable.idempotence to true. In v3.0, enable.idempotence was set to default to true, but the validator and the idempotence enabled check method were not adjusted."
27 Apache Kafka (d-t-w) PR #12260: add note on IDEMPOTENT_WRITE ACL to 3.2.0 notable changes source 2022-06 (merged) 2026-09-01 search-verified https://github.com/apache/kafka/pull/12260 Turning idempotence on by default broke producers against older brokers via a missing ACL; a community PR had to document it PR exists in apache/kafka adding the 3.2.0 upgrade note on IDEMPOTENT_WRITE ACL; independent analysis: Factor House, "Apache Kafka 3.2.0: Idempotent Producer Breaking Change" (https://factorhouse.io/articles/kafka-producer-breaking-change).
28 Confluent (Neha Narkhede) Exactly-once Semantics is Possible: Here's How Apache Kafka Does it vendor 2017-06 2026-09-01 search-verified https://www.confluent.io/blog/exactly-once-semantics-are-possible-heres-how-apache-kafka-does-it/ The vendor account of KIP-98's design, paired with the community's later bug record Search-result content: the idempotent producer dedupes with sequence numbers; enabling idempotence "adds some overhead to track sequence numbers and manage retries"; "as transaction commits become more frequent, the overhead of the transaction will be higher."
29 Confluent (Jason Gustafson) Exactly Once Semantics Revisited, Kafka Summit NYC 2019 talk 2019-04 2026-09-01 search-verified https://www.confluent.io/kafka-summit-ny19/exactly-once-semantics-revisted/ Two years into production, EOS needed a "revisited" talk on remaining gaps Talk page abstract (search-verified): "outlines transactional writes across multiple partitions and identifies remaining gaps, then discusses how they are being addressed." Slides: https://www.slideshare.net/slideshow/exactly-once-semantics-revisited-jason-gustafson-confluent-kafka-summit-nyc-2019/139735997
30 Confluent (Matthias J. Sax) Don't Repeat Yourself: Introducing Exactly-Once Semantics in Apache Kafka, Kafka Summit London 2018 talk 2018-04 2026-09-01 search-verified https://www.confluent.io/kafka-summit-london18/dont-repeat-yourself-introducing-exactly-once-semantics-in-apache-kafka/ The implementer's own framing: exactly-once is idempotence plus transactions plus fencing, not magic Talk page (search-verified): "presents the additions to Apache Kafka 1.0 to achieve exactly-once processing semantics"; video at https://videos.confluent.io/watch/uGa9KHWv1p3q9cyzcNYA7c
31 AWS (Malcolm Featonby) Making retries safe with idempotent APIs (Amazon Builders' Library) blog 2021-01 2026-09-01 search-verified https://aws.amazon.com/builders-library/making-retries-safe-with-idempotent-APIs/ Amazon's internal pattern: unique client request identifier, parameter-mismatch validation error Search-result content: Amazon uses "unique client request identifiers, often implemented as a ClientToken in AWS APIs"; "When the service receives a unique client request token that has been seen before but with different parameters, it returns a validation error." PDF: https://d1.awsstatic.com/builderslibrary/pdfs/making-retries-safe-with-idempotent-apis-malcolm-featonby.pdf
32 AWS Ensuring idempotency in Amazon EC2 API requests vendor current docs 2026-09-01 search-verified https://docs.aws.amazon.com/ec2/latest/devguide/ec2-api-idempotency.html EC2 launched client tokens in 2010; idempotency scope is regional or zonal depending on how the AZ is specified Search-result content: "The RunInstances API action uses both Regional and zonal idempotency. The type of idempotency that is used depends on how you specify the Availability Zone." Launch announcement (2010): https://aws.amazon.com/blogs/aws/new-amazon-ec2-feature-idempotent-instance-creation
33 AWS / boto3 users Issue #4406: Unexpected breaking change in RunInstances (not idempotent anymore. Even with client token) source 2025-01-26, confirmed bug 2026-09-01 search-verified https://github.com/boto/boto3/issues/4406 The provider changed replay behaviour after 14+ years and users' automation broke: replay of a terminated instance's token began throwing Search-result content: "calling RunInstances on a terminated instance with the same client token... used to succeed according to EC2 documentation, but the operation started failing with an IdempotentInstanceTerminated exception"; "this breaking change violates that idempotency promise."
34 AWS DynamoDB TransactWriteItems ClientRequestToken vendor current docs 2026-09-01 search-verified https://docs.aws.amazon.com/sdk-for-kotlin/api/latest/dynamodb/aws.sdk.kotlin.services.dynamodb.model/-transact-write-items-request/client-request-token.html The dedupe window can be as short as 10 minutes Search-result content: "A client request token is valid for 10 minutes after the first request that uses it is completed... After 10 minutes, any request with the same client token is treated as a new request."
35 Adyen API idempotency (docs) vendor current docs 2026-09-01 search-verified https://docs.adyen.com/development-resources/api-idempotency/ A second payment provider's window: minimum 7 days Search-result content: "Idempotency keys are valid for a minimum period of 7 days after first submission."
36 Square Idempotency (developer docs) vendor current docs 2026-09-01 search-verified https://developer.squareup.com/docs/build-basics/common-api-patterns/idempotency Same pattern, transported in the body; replay of the stored success, mismatch error on changed parameters Search-result content: "when you send a request with the same idempotency_key, it will send back the current successful response"; changing the request under the same key yields "an error indicating that you used the idempotency key previously."
37 GoCardless Safely retrying API requests blog 2017 2026-09-01 search-verified https://gocardless.com/blog/idempotency-keys A deliberately different semantic: conflict instead of replay Search-result content: "GoCardless only allows that key to be used for a single successful request. Any requests to create a resource with a key that has previously been used will not succeed, and will respond with a 409 idempotent_creation_conflict error"; client libraries "automatically generate idempotency keys."
38 Uber Engineering Uber's Next-Gen Payments Platform blog 2018 2026-09-01 search-verified https://www.uber.com/us/en/blog/payments-platform/ Design goal stated as exactly-once via idempotency plus auditability via double-entry Search-result content: goals include "exactly-once payment processing by the means of idempotency and strong consistency, auditability via double-entry bookkeeping"; external "payment service providers and banking systems are normally implementing their services as idempotent message processors."
39 Uber Revolutionizing Money Movements at Scale with Strong Data Consistency blog 2020 2026-09-01 search-verified https://www.uber.com/us/en/blog/money-scale-strong-data/ Idempotence implemented through immutable orders and a versioned change log, not only keys Search-result content: "systems guarantee orders to be immutable and process orders after persisting them. The system was built to be idempotent"; writebacks serialized "by the entity change log's version number per user."
40 Shopify (Bart de Water) 10 Tips for Building Resilient Payment Systems blog 2023-05 2026-09-01 search-verified https://shopify.engineering/building-resilient-payment-systems The key store is hot-path infrastructure: ULID keys cut INSERT time 50% vs UUIDv4; window ≤ 24h; 409 on concurrent reuse Search-result content: "In one high-throughput system at Shopify we've seen a 50 percent decrease in INSERT statement duration by switching from UUIDv4 to ULID for idempotency keys"; "An idempotency key needs to be unique for the time we want the request to be retryable, typically 24 hours or less"; "A lock around the API call based on the client and idempotency key will allow the server to reject the request with an HTTP code of 409."
41 Sidekiq (Mike Perham) Best Practices / FAQ: make your jobs idempotent source wiki, current 2026-09-01 search-verified https://github.com/sidekiq/sidekiq/wiki/Best-Practices The job-queue half of the ecosystem refuses to promise exactly-once and pushes idempotence onto the handler Search-result content: "Sidekiq will execute your job at least once, not exactly once. Even a job which has completed can be re-run if Redis goes down between the point where your job finished but before Sidekiq has acknowledged it"; "Sidekiq makes no exactly-once guarantee at all." Uniqueness is a paid Enterprise feature with a declared time window (Ent-Unique-Jobs wiki).
42 Hatchet The First Idempotency Key blog 2026 2026-09-01 search-verified https://hatchet.run/blog/first-idempotency-key Independent history hunt: Stripe's header is ~2015 in the primary record, EC2's ClientToken predates it, and the trail runs back to PARC RPC Search-result content: the author "found that Stripe's Idempotency-Key header was published circa 2015 (though some blogs cite it without primary sources to be earlier)"; explores "Amazon EC2's ClientToken behavior, which predates Stripe" and traces "back even further to distributed systems research built around remote procedure calls (RPC), including work from the Cedar programming environment at Xerox PARC in the early 1980s."
43 Gergely Orosz (ex-Uber) Distributed architecture concepts I learned while building a large payments system blog 2018 2026-09-01 search-verified https://blog.pragmaticengineer.com/distributed-architecture-concepts-i-have-learned-while-building-payments-systems/ Practitioner corroboration from a second payments team that idempotency is the retry-safety mechanism Post exists at this URL (search-verified); covers idempotency among the core concepts learned building Uber's payments system.
44 danluu et al. A collection of postmortems (index) casestudy maintained collection, fetched 2026-09-01 fetched (raw README) https://github.com/danluu/post-mortems The public postmortem corpus contains remarkably few duplicate-side-effect incidents; Twilio 2013 is the canonical one Fetched README: Twilio entry reads "the auto-recharge system continued to retry the transaction again and again, resulting in multiple charges to customer's credit cards"; no other entry in the collection describes duplicate charges from retries.