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 |
| 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. |