Designing a Triangulation Fraud Detection System
A complete, from-first-principles walkthrough of how to design a real-time system that catches “triangulation fraud” — where a seller lists items they do not own and fulfils orders using another retailer’s stolen payment details — at a scale of millions of requests per minute.
Introduction & History
Imagine a shady middleman standing between two shops. He tells you, a customer, “I have that exact sofa you want and I will sell it to you for a great price — just pay me directly.” You pay him. He then walks into a real furniture store across the street, buys that exact sofa using someone else’s stolen credit card and has the store ship it straight to your house. You get your sofa, so you are happy and leave a good review. The furniture store eventually finds out the card was stolen and reverses the charge, losing the sofa entirely. The middleman walks away with your money and never had a sofa, a warehouse or any real business at all.
This is exactly the mechanics of triangulation fraud, translated into online marketplace terms. A fraudulent seller lists a product on a marketplace (Amazon, eBay, Etsy or any multi-seller platform) that they do not actually own or stock. When a real buyer orders and pays, the fraudulent seller takes that payment, then uses a completely different, usually stolen, card to buy the same item from a legitimate retailer and has it shipped directly to the original buyer’s address. The buyer receives a real product and is often none the wiser, which is exactly what makes this fraud pattern so dangerous — the buyer-side experience looks completely normal, so complaints rarely trigger the investigation.
The name “triangulation” comes from the three-party shape of the scheme: the fraudulent seller sits between the buyer, who never suspects anything is wrong and the legitimate retailer, whose real inventory and real cardholder absorb all of the actual loss. The diagram below shows this triangle clearly.
Triangulation fraud has grown alongside the rise of open, multi-seller marketplaces. It became especially prevalent once large platforms lowered the barrier to becoming a seller — anyone can register, list products and start receiving payouts within days. Marketplaces such as Amazon Marketplace, eBay, Etsy and large regional platforms in India and Southeast Asia have all publicly discussed this fraud pattern as a persistent operational challenge, because the fraud is largely invisible from the buyer’s side and only becomes visible once the legitimate retailer or the victim cardholder disputes the charge, often weeks after the fraudulent seller has already been paid out and disappeared.
Think of a ticket scalper who does not actually have any tickets. They take your money promising a concert ticket, then buy a real ticket from the official box office using a stolen credit card and have it emailed to you. You get a valid ticket and are happy. The box office loses money to the stolen card. The scalper made a profit without ever owning a single ticket and without you ever knowing anything was wrong.
Problem & Motivation
2.1 Why is this fraud pattern so hard to catch?
Triangulation fraud is uniquely difficult compared to most other e-commerce fraud patterns for a specific reason: from the marketplace’s point of view, the buyer-side transaction looks completely legitimate. The buyer pays with their own valid card, receives their item and is satisfied. There is no chargeback on the buyer’s side, no complaint, no obviously suspicious velocity of failed payments. The fraud signal lives almost entirely on the seller’s side — in the mismatch between what the seller claims to own and what they actually ship — and in a second transaction that happens entirely outside the marketplace’s own systems, at a different retailer altogether.
2.2 Why does this matter to a business?
| Impact area | What happens |
|---|---|
| Direct financial loss via clawbacks | Once a victim cardholder disputes the charge with the legitimate retailer, the retailer often traces the shipment back to the marketplace’s buyer and the marketplace can be forced to claw back seller payouts or absorb losses if the seller has already withdrawn funds and disappeared. |
| Legal and reputational exposure | Marketplaces that repeatedly host triangulation fraud sellers face regulatory scrutiny and in some jurisdictions can face liability for facilitating the sale of goods purchased with stolen payment data. |
| Damage to legitimate retailer relationships | If a marketplace’s buyers are frequently identified as receiving items purchased fraudulently from a partner retailer, that retailer may restrict shipments to addresses linked to the marketplace or blacklist the marketplace’s associated IP ranges entirely. |
| Erosion of seller ecosystem trust | Legitimate sellers suffer when trust and safety systems become either too slow (fraud persists) or too aggressive (honest new sellers get wrongly suspended), so getting the detection balance right protects the whole seller ecosystem. |
| Card network fraud rate monitoring | Even though the fraud happens at a third-party retailer, patterns of shipping addresses repeatedly linked to disputed charges can eventually affect the marketplace’s own standing with payment processors if not addressed. |
2.3 Why is this a hard system design problem?
- The core evidence is off-platform. The actual fraudulent purchase happens at a different retailer’s website, which the marketplace has no direct visibility into. Detection must rely on indirect signals: seller behaviour, shipment patterns and inventory claims.
- It must be caught before payout, not after. Once the fraudulent seller has withdrawn funds, recovering the loss is far harder. This creates a hard real-time constraint: the system must assess seller and order risk within the payout processing window, which itself must operate under tight latency at huge scale.
- Massive scale. Large marketplaces process millions of orders per hour across millions of active sellers and the detection system must evaluate every single order and every seller behaviour change without becoming the platform’s bottleneck. At the scale specified for this design (millions of requests per minute), naive per-request database lookups or synchronous cross-service calls simply will not survive contact with real traffic.
- Legitimate drop-shipping looks similar. Many completely legitimate sellers use drop-shipping models, where they also do not hold physical inventory and have a supplier ship directly to the buyer. The system must distinguish “legitimate drop-shipping using a legitimate business relationship and the seller’s own valid payment method” from “triangulation fraud using someone else’s stolen payment method”, which is a genuinely subtle distinction.
- Sellers rotate identities. A banned fraudulent seller often reappears under a new account, a new business registration and a new bank account, so entity resolution and identity linkage across accounts becomes essential, not optional.
“How is triangulation fraud different from a seller simply not shipping an order at all?” A strong answer highlights that non-shipment fraud is easy to detect (the buyer complains, tracking never updates) and easy to explain to the seller (no proof of shipment, no payout). Triangulation fraud is fundamentally harder because the buyer genuinely receives their item and is satisfied, so the traditional “did the buyer get what they paid for” signal, which drives most marketplace trust systems, says everything is fine. Detection has to shift from buyer-outcome signals to seller-behaviour and shipment-origin signals instead.
Core Concepts You Must Understand First
3.1 Drop-shipping versus triangulation fraud
Both patterns involve a seller who does not hold physical inventory and relies on a third party to fulfil the order. The critical difference is the payment method used for that third-party fulfilment purchase:
| Aspect | Legitimate drop-shipping | Triangulation fraud |
|---|---|---|
| Fulfilment payment method | Seller’s own valid business payment method, often with a pre-negotiated supplier account | A stolen card belonging to an unrelated victim cardholder |
| Supplier relationship | Documented, repeatable business relationship, often with a wholesale account | None — an anonymous retail purchase at a random legitimate retailer |
| Shipping origin pattern | Consistent, predictable set of supplier warehouses over time | Highly varied, often matching whichever retailer happened to have that specific item in stock and cheapest at that moment |
| Order-to-fulfilment timing | Reasonably consistent processing time reflecting a real supply chain | Often unusually fast, reflecting an automated “buy it right now, from anywhere” purchasing pattern |
3.2 Entity linkage graph
Because triangulation fraud often involves the same fraudster operating multiple seller accounts or reusing the same shipping addresses, bank accounts or device fingerprints across accounts, a graph structure connecting sellers, buyers, addresses, bank accounts, devices and orders is one of the most powerful detection tools available. A single suspicious order is weak evidence; the same shipping address appearing across twelve different “new” seller accounts, all created in the last month, is very strong evidence.
Think of how detectives build a case board with strings connecting photos and locations. No single photo proves guilt, but when the same address, the same car and the same phone number connect five seemingly unrelated cases, the pattern itself becomes the evidence. An entity linkage graph is exactly that case board, built and searched automatically at software speed.
3.3 Chargeback and dispute signals
A chargeback happens when a cardholder disputes a charge with their bank. In triangulation fraud, the chargeback lands on the legitimate retailer, not the marketplace, which is precisely why marketplaces cannot rely on their own chargeback data alone. Many marketplaces build data-sharing partnerships or monitor public retailer fraud advisories and correlate shipment tracking numbers reported by buyers against known patterns of disputed retail orders, to close this visibility gap.
3.4 Seller trust score and account age
Just like a credit score for a person, a seller trust score aggregates a seller’s history — account age, order volume, dispute rate, listing accuracy, prior warnings — into a single evolving risk indicator. New seller accounts inherently carry more risk simply because they have no track record, which is why most systems apply stricter scrutiny (holding payouts longer, requiring identity verification, capping order volume) during a defined probation period.
3.5 Payout holds versus payout blocks
A payout hold is a temporary delay releasing a seller’s earned funds while a risk signal is investigated — reversible, low-friction if wrong. A payout block is a harder, longer-term freeze applied once a pattern is confirmed. Building a system with a graduated response, rather than only a binary “pay or do not pay”, lets you act early on weak signals without unfairly punishing legitimate sellers who trip a soft signal.
3.6 Rules engine versus machine learning versus graph analysis
As with most fraud systems, no single technique catches everything. Rules catch known, well-understood patterns fast (for example, “seller’s declared warehouse country does not match the shipping carrier’s pickup location country”). Machine learning scoring captures subtler combinations of weaker signals across many order and seller attributes. Graph analysis catches identity and relationship patterns that neither rules nor a row-level ML model can see on their own, because the signal only exists when you look across many connected entities together.
“Why do you need a graph database here specifically, instead of just adding more columns and rules to the existing rules engine?” A strong answer: relational, row-level rules and models are good at asking “is this one order suspicious”, but triangulation rings are fundamentally about relationships between entities — the same address across many sellers, the same device creating many accounts, the same bank account receiving payouts under different business names. These are graph traversal problems (find all sellers within two hops of this shipping address) that are extremely inefficient to express as SQL joins at scale, but are natural and fast in a graph database purpose-built for relationship queries.
Requirements & Scale
4.1 Functional requirements
- Evaluate every order and every payout request for triangulation risk, returning Approve, Hold or Block.
- Maintain an identity linkage graph connecting sellers, buyers, shipping addresses, bank accounts and devices.
- Verify, where possible, that a seller’s claimed inventory ownership is plausible (matching declared warehouse location, supplier relationships and historical fulfilment origin patterns).
- Track seller-level behavioural velocity: new listings, order volume growth rate, shipping origin diversity and address reuse across accounts.
- Support a graduated response: soft flags, payout holds, payout blocks and account suspension, each reversible up to the point of full confirmation.
- Provide fraud analysts a case management workflow to review flagged sellers and orders, with full supporting evidence from rules, ML and graph signals.
- Feed confirmed fraud cases back into both the ML training pipeline and the entity linkage graph for future detection.
- Maintain a full audit trail of every decision, usable for regulatory response and seller disputes.
4.2 Non-functional requirements
| Requirement | Target | Why it matters |
|---|---|---|
| Throughput | Sustain millions of requests per minute at peak (see Section 4.3) | Large marketplace order and listing volume at global scale, including flash sale and festive traffic multipliers |
| Latency | p99 under 200 ms for the synchronous order-time risk check | Order confirmation is latency sensitive; slow checks directly hurt conversion and buyer experience |
| Availability | 99.99 percent for the order-time decision path | If the fraud check is down, order placement across the entire marketplace is affected |
| Payout decision latency | Under a few seconds, asynchronously, before funds are released | Payout timing has more slack than order confirmation, allowing deeper, more expensive checks (graph traversal, ML ensemble) before funds actually move |
| Graph query latency | p95 under 50 ms for a 2-hop relationship query | Graph checks are on the synchronous or near-synchronous path for payout decisions and must not become the bottleneck |
| False positive rate | Keep below an agreed business threshold, for example under 0.3 percent of legitimate sellers held or blocked | Every false hold damages a legitimate seller’s business and marketplace trust |
| Data freshness for velocity and graph signals | Within a few seconds of the triggering event | Coordinated fraud rings can create and exploit many seller accounts within hours; stale signals miss the window entirely |
4.3 Scale estimation for millions of requests per minute
This is the headline scale constraint for this design, so let us work through it carefully, the way an interviewer expects.
Target: sustain up to 5,000,000 requests per minute at peak
(this includes order placement, listing views/updates, and payout-triggering events combined)
Converting to requests per second:
5,000,000 requests / 60 seconds ~= 83,333 requests per second (RPS) sustained at peak
Assume roughly 15 percent of total requests actually require
a full fraud evaluation (order placement and payout triggers,
not simple browsing or listing views):
83,333 x 0.15 ~= 12,500 fraud evaluation RPS at peak
Fraud Decision Gateway capacity planning:
- Assume each stateless Fraud Decision Gateway pod can safely handle
~500 evaluation RPS given parallel calls to Rules Engine, ML Scoring,
and Graph Service, each with strict timeouts
- Required pod count at peak: 12,500 / 500 = 25 pods minimum,
with autoscaling headroom typically targeting 2 to 3x that for
safety margin and sudden spikes: ~60 to 75 pods per active cell
Velocity Cache (Redis) sizing:
- Assume 50 million active seller/buyer/address/device keys tracked
in rolling windows at any given time
- Each key's sliding window record: ~250 bytes
- 50,000,000 x 250 bytes ~= 12.5 GB of hot data,
comfortably shardable across a Redis Cluster with headroom
Kafka event pipeline volume:
- Each order/payout event: ~3 KB including features and metadata
- At 12,500 evaluation RPS average: 12,500 x 3 KB ~= 37.5 MB/sec
~= 3.24 TB/day into Kafka, partitioned by seller ID for parallelism
Graph database sizing:
- Assume 200 million sellers, buyers, addresses, and devices as nodes,
with an average of 6 edges per node from historical orders and shared attributes
- 200,000,000 nodes x 6 edges ~= 1.2 billion edges,
requiring a horizontally partitioned graph database rather than a single-node graph store
At 12,500+ fraud evaluations per second, a design that does even a handful of synchronous cross-service database calls per request (say, five sequential calls each averaging 20 ms) would need roughly 100 ms just for network round trips before any actual computation happens and would require enormous connection pool sizes across every downstream dependency. This is exactly why this design leans so heavily on parallel fan-out calls with strict timeouts (Section 6), pre-aggregated velocity counters in Redis rather than live database queries (Section 9) and a cell-based, horizontally partitioned deployment topology (Section 13) — none of these are optional nice-to-haves at this scale, they are load-bearing architectural decisions.
Architecture & Components
The diagram below shows the full system, organised into the same familiar layers as any high-scale marketplace: edge and gateway, core marketplace services, the triangulation fraud detection platform, an asynchronous event and graph-building pipeline and the data layer.
5.1 Component responsibilities
Edge and Gateway Layer
- CDN / Edge Cache: Serves static storefront and listing page assets close to the user, absorbing a large share of read-heavy traffic before it reaches origin infrastructure — critical at millions-of-requests-per-minute scale.
- WAF (Web Application Firewall): Blocks known malicious request signatures and applies coarse IP reputation filtering before requests reach the application layer.
- Load Balancer: Distributes incoming traffic across API Gateway instances within each deployment cell (see Section 13), performing health checks and connection-level rate limiting.
- API Gateway: Handles authentication, request validation, per-seller and per-buyer rate limiting and routes requests to the correct backend service and cell.
Marketplace Core Services
- Listing Service: Owns the product catalog; new and updated listings pass through a lightweight risk check here too, since suspicious listing patterns (implausibly low prices, sudden bulk listing of high-demand items) are an early triangulation signal.
- Seller Onboarding Service: Manages seller registration, identity verification and the probation period for new sellers described in Section 3.4.
- Order Service: Owns order creation and lifecycle state.
- Payment Orchestrator Service: Coordinates payment capture from the buyer and payout release to the seller, calling the Fraud Decision Gateway before each payout is released.
Triangulation Fraud Detection Platform
- Fraud Decision Gateway: The stateless, horizontally scaled synchronous entry point that fans out to the Rules Engine, ML Scoring Service, Identity Linkage Graph Service and Inventory Verification Service in parallel, combining their outputs into one final decision within the latency budget.
- Rules Engine: Evaluates deterministic rules about seller behaviour and order patterns using data from the Velocity Cache.
- ML Scoring Service: Produces a real-time risk probability using features from the Feature Store, covering both order-level and seller-level risk signals.
- Identity Linkage Graph Service: Answers relationship queries against the graph database — for example, “how many distinct seller accounts share this exact shipping address or bank account”.
- Inventory Verification Service: Cross-checks a seller’s declared inventory source and shipment origin patterns against historical data, flagging implausible ownership claims.
- Velocity Cache: A sharded Redis Cluster holding sliding-window counters across sellers, buyers, addresses and devices.
- Feature Store: Serves pre-computed, low-latency features for online ML scoring, kept consistent with offline training data.
Async Event Pipeline
- Event Stream (Kafka): Every order, listing and payout event is published here, partitioned by seller ID for parallel, ordered processing per seller.
- Stream Processor: Computes rolling velocity aggregations and writes them back into the Velocity Cache and Feature Store.
- Graph Builder Job: Continuously updates the Identity Linkage Graph with new nodes and edges as new orders, accounts and shared attributes appear.
- Case Management Service: Groups related flagged sellers and orders into cases for fraud analyst review.
- Notification Service: Alerts trust and safety analysts, on-call engineers and can notify partner retailers of confirmed fraud patterns where data-sharing agreements exist.
Data Layer
- Order Database: Sharded Postgres, the system of record for orders and payments.
- Graph Database: A horizontally partitioned graph store (such as Amazon Neptune or JanusGraph) holding the full identity linkage graph.
- Analytics Warehouse: An OLAP store for historical fraud analysis and generating training data.
- Model Registry: Stores trained model versions with rollback support.
“At this scale, would not the Identity Linkage Graph Service become a bottleneck since it is on the decision path?” A strong answer separates two different query patterns: cheap, cached “does this exact address or device already have a known risk flag” lookups can be served synchronously from a fast cache layer in front of the graph (populated by the Graph Builder Job), while expensive multi-hop traversal queries (“find all sellers within two hops of any flagged entity”) run asynchronously, off the synchronous order path and their results are cached back into that fast lookup layer for the next request. This keeps the expensive graph computation off the hot path while still benefiting from graph-derived signals in real time.
Internal Working
6.1 The synchronous decision path, step by step
The diagram below shows what happens between a buyer submitting an order and the marketplace deciding whether the associated seller payout should proceed normally, be held or be blocked.
6.2 Why the order always completes, even when risk is high
A subtle but important design decision: for buyer experience reasons, the order itself is almost never blocked at checkout based on seller-side triangulation risk, because the buyer has done nothing wrong and blocking their purchase would be a confusing, harmful false positive from their perspective. Instead, risk signals control the seller’s payout, which can be held or blocked without the buyer ever noticing anything unusual. This is a very different pattern from the card-testing fraud use case (buyer-side risk) and is worth explicitly contrasting in an interview if asked to compare the two.
6.3 Combining multiple signal types into one decision
| Signal source | Example trigger | Weight in final decision |
|---|---|---|
| Identity Linkage Graph | Shipping address shared across 5+ distinct “new” seller accounts within 30 days | Strong — often a near-automatic Hold, sometimes an immediate Block if the graph pattern matches a previously confirmed fraud ring signature |
| Rules Engine | Seller’s declared warehouse country does not match shipment carrier pickup location for 3+ consecutive orders | Strong — high-confidence deterministic pattern |
| ML Scoring Service | Combination of order value, seller account age, listing price deviation from market average and buyer / seller distance | Moderate to strong, scaled by model confidence |
| Inventory Verification Service | Seller has no verified supplier relationship on file and item category historically shows high triangulation rates | Moderate — contributes to score, rarely triggers a block alone |
6.4 Java example: the signal combiner
public class TriangulationDecisionCombiner {
private static final double BLOCK_THRESHOLD = 0.8;
private static final double HOLD_THRESHOLD = 0.4;
public PayoutDecision decide(
GraphRiskSignal graphSignal,
RulesVerdict rulesVerdict,
double mlScore,
InventoryConfidence inventoryConfidence) {
// A confirmed fraud-ring graph match is treated as near-certain
if (graphSignal.matchesKnownFraudRingSignature()) {
return PayoutDecision.block("GRAPH_FRAUD_RING_MATCH");
}
if (rulesVerdict.isHardTrigger()) {
return PayoutDecision.block(rulesVerdict.getReasonCode());
}
double combinedScore = (mlScore * 0.5)
+ (graphSignal.getRiskContribution() * 0.3)
+ (inventoryConfidence.getRiskContribution() * 0.2);
if (combinedScore >= BLOCK_THRESHOLD) {
return PayoutDecision.block("COMBINED_HIGH_RISK");
}
if (combinedScore >= HOLD_THRESHOLD) {
return PayoutDecision.hold("COMBINED_MODERATE_RISK");
}
return PayoutDecision.approve();
}
}
6.5 Java example: seller-level sliding window velocity in Redis
public class SellerVelocityChecker {
private final RedisTemplate<String, String> redis;
private static final long WINDOW_SECONDS = 3600;
private static final int MAX_NEW_LISTINGS_PER_HOUR = 50;
public boolean isSuspiciousListingBurst(String sellerId) {
String key = "velocity:seller_listings:" + sellerId;
long now = System.currentTimeMillis();
long windowStart = now - (WINDOW_SECONDS * 1000);
redis.opsForZSet().removeRangeByScore(key, 0, windowStart);
redis.opsForZSet().add(key, String.valueOf(now), now);
redis.expire(key, java.time.Duration.ofSeconds(WINDOW_SECONDS * 2));
Long count = redis.opsForZSet().zCard(key);
return count != null && count > MAX_NEW_LISTINGS_PER_HOUR;
}
}
“Why hold the payout instead of the order itself?” This question tests whether the candidate understands that triangulation fraud is fundamentally a seller-trust problem, not a buyer-trust problem. The correct answer separates the two: the buyer transaction is legitimate and should proceed normally to protect conversion and buyer trust, while the seller’s right to receive funds is conditional on continued trust and is the appropriate lever to pull while investigating.
Data Flow & Lifecycle
A confirmed triangulation fraud case rarely comes from a single order — it emerges as a seller’s behaviour accumulates evidence over time. The state diagram below shows the full lifecycle.
7.1 How the graph and velocity signals feed the lifecycle
Every state transition in the diagram above is triggered by signals produced elsewhere in the architecture. The transition from UnderWatch to Confirmed, for example, is typically driven by the Identity Linkage Graph Service detecting repeated shipment-origin mismatches or shared address patterns across multiple orders, combined with the Stream Processor’s rolling velocity aggregations crossing a defined threshold. This is why the async pipeline (Kafka, Stream Processor, Graph Builder Job) is just as important to this system’s effectiveness as the synchronous decision path — the synchronous path catches individual bad orders, while the async pipeline is what actually detects the pattern across time and across seller accounts that makes triangulation fraud identifiable in the first place.
7.2 Why the probation period for new sellers matters
New seller accounts are disproportionately used for triangulation fraud, because they have no history to build trust and because a banned fraudster’s fastest path back into the marketplace is simply registering again under a new identity. A defined probation period — with lower order value limits, delayed payouts and stricter inventory verification requirements — dramatically raises the cost of running triangulation fraud through freshly created accounts, without meaningfully harming genuine new sellers, most of whom start small anyway.
Advantages, Disadvantages & Trade-offs
Advantages of this architecture
- Separating buyer-side order completion from seller-side payout control protects buyer experience while still stopping fraud before funds leave the platform.
- The identity linkage graph catches coordinated fraud rings that row-level rules and ML models alone would miss entirely.
- Cell-based deployment (Section 13) allows the system to scale horizontally to millions of requests per minute by adding cells, without any single component becoming a global bottleneck.
- A graduated response (soft flag, hold, block) minimises harm to legitimate sellers caught by early, uncertain signals.
- Async graph building keeps expensive relationship computation off the critical decision path.
Disadvantages and costs
- Very high operational complexity — graph databases, stream processing and ML infrastructure all need dedicated expertise and on-call ownership.
- Graph databases at billions of edges require careful partitioning and are genuinely difficult to operate reliably at scale.
- Payout holds directly and immediately affect legitimate seller cash flow when the system is wrong, which has real business consequences beyond a simple false positive metric.
- Detecting triangulation requires signals that partly live outside the platform (retailer chargebacks, victim cardholder disputes), which are inherently delayed and incomplete.
- Cell-based architecture adds real complexity to routing, data consistency across cells and cross-cell entity resolution (a fraud ring might deliberately spread accounts across cells to evade detection).
8.1 Key trade-off: detection speed versus evidence strength
Acting on a single suspicious signal (say, one address shared by two sellers) catches fraud early but risks many false positives, since address sharing sometimes has innocent explanations (family members, small business incubators, shared fulfilment centres). Waiting for stronger, accumulated evidence (repeated pattern across many orders and many linked accounts) is more accurate but slower, giving a fraud ring more time and more orders before detection. The graduated response model in Section 3.5 is the direct answer to this trade-off: act early with a soft, reversible response and escalate only as evidence strengthens.
8.2 Key trade-off: global consistency versus cell independence
The cell-based deployment model (Section 13) trades some global consistency for massive horizontal scalability — a fraud ring could, in principle, spread its accounts deliberately across different cells to avoid appearing connected within any single cell’s local graph and velocity data. This is addressed by a global, asynchronous cross-cell reconciliation job that periodically merges cell-local graphs into a global view, accepting a delay (typically minutes, not milliseconds) in exchange for the ability to scale each cell independently without cross-cell coordination on every request.
Performance & Scalability at Millions of Requests / Minute
9.1 Where the bottlenecks are at this scale
| Component | Likely bottleneck at millions of RPM | Mitigation |
|---|---|---|
| Velocity Cache (Redis) | Hot keys during a coordinated fraud ring hitting the same address / device repeatedly; single-shard throughput ceiling | Redis Cluster sharded by entity hash; use Lua scripts to batch read-modify-write velocity checks into one round trip; monitor and manually re-shard around detected hot keys |
| Identity Linkage Graph | Multi-hop traversal queries are expensive and do not parallelise trivially across a sharded graph | Serve cached, pre-computed 1-hop and 2-hop risk flags synchronously from a fast lookup cache in front of the graph; run expensive deep traversals asynchronously and cache their results (Section 5.1) |
| ML Scoring Service | Inference latency multiplied across millions of requests per minute, GPU / CPU capacity limits | Use lightweight gradient-boosted models for the synchronous path; batch inference where request patterns allow; horizontally scale stateless inference pods aggressively with autoscaling tied to queue depth |
| Kafka event pipeline | Consumer lag under sustained 12,500+ events/sec load | Partition aggressively by seller ID (not a low-cardinality key) for parallelism; autoscale consumer groups; alert on lag growth rate, not just absolute lag |
| Order Database | Write throughput and connection pool exhaustion at peak | Shard by seller ID or region; use connection pooling with strict per-service limits; move non-critical reads to read replicas |
9.2 Cell-based architecture: the core scaling strategy
At the scale required here (millions of requests per minute), a single monolithic deployment of any component, no matter how well it is scaled vertically, eventually hits a ceiling and worse, becomes a single blast-radius for any failure or bad deployment. The solution used throughout this design is a cell-based architecture: the entire fraud platform (API Gateway, Fraud Decision Gateway, Redis, Kafka and supporting services) is replicated into multiple independent “cells”, each responsible for a fixed shard of sellers (see the deployment diagram in Section 13). A request for a given seller is always routed to the same cell, which means each cell only needs to handle a fraction of total platform traffic and a failure or overload in one cell never affects sellers assigned to a different cell.
Think of a huge food court with twenty identical restaurant counters instead of one giant kitchen. If a customer is always routed to “their” assigned counter based on a simple rule (like the first letter of their order number), each counter only ever needs to handle a fixed slice of total demand and if one counter’s grill breaks down, only that fraction of customers is affected — the other nineteen keep serving food normally.
9.3 Caching strategy at scale
- Blocklist and known-fraud-ring cache: Local in-memory cache (Caffeine) on every Fraud Decision Gateway pod, refreshed from Redis via pub/sub invalidation, avoiding a network round trip for the highest-confidence, most frequently hit rejections.
- Graph 1-hop cache: Pre-computed “does this address / device / bank account already have a known risk flag” answers cached aggressively (seconds to low minutes TTL), since this is the single most frequently needed graph query.
- Feature cache tiering: Slowly changing seller-level features (account age, historical dispute rate) cached longer than fast-changing order-level features (current hour’s order count).
9.4 Algorithms and data structures for extreme scale
Consistent hashing for cell routing
Routing a seller to a cell needs to be fast, stable (the same seller should almost always land on the same cell, even as cells are added or removed) and evenly distributed. Consistent hashing is the standard solution: sellers are hashed onto a ring and cells own contiguous ranges of that ring, so adding or removing a cell only requires reshuffling a small fraction of sellers rather than the entire population.
Bloom filters for fast negative lookups
Before doing an expensive graph or database lookup to check “has this address ever been associated with a flagged seller”, a Bloom filter can answer “definitely not” instantly for the vast majority of addresses that have never appeared in any fraud case, at a small, tunable false-positive rate, dramatically cutting load on the more expensive exact-match systems behind it.
Approximate counting with HyperLogLog
Tracking “how many distinct shipping addresses has this seller used in the last 30 days” exactly requires storing every unique address, which gets expensive at scale across millions of sellers. HyperLogLog, a probabilistic data structure for approximate distinct counting, estimates this cardinality using a tiny, fixed amount of memory per seller, with a small, well-understood error margin — more than sufficient for a velocity-style risk signal.
Graph partitioning
At 200 million nodes and over a billion edges (Section 4.3), the graph database itself must be partitioned. A common approach is partitioning by entity type and by cell boundary where possible, accepting that some cross-partition edges (a fraud ring deliberately spanning cells) require the asynchronous cross-cell reconciliation job mentioned in Section 8.2 rather than a synchronous cross-partition query.
“You are targeting millions of requests per minute — walk me through exactly what breaks first if you just deployed a single, non-cell-based cluster of every component.” A strong answer identifies Redis and the graph database as the first likely failure points (hot keys and expensive multi-hop queries respectively), explains that vertical scaling of a single cluster has a hard ceiling and a single blast radius and connects this directly to why the design adopts cell-based horizontal partitioning rather than trying to scale one giant cluster indefinitely.
High Availability & Reliability
10.1 Redundancy within and across cells
Every stateful component within a cell (Redis, Kafka, Postgres) is deployed across multiple availability zones with automatic failover, exactly as in a single-region design. What is different here is that cells themselves are a redundancy boundary: if an entire cell becomes unhealthy, its assigned sellers can, in a well-designed system, be temporarily rerouted to a neighbouring cell with spare capacity, accepting a brief period of degraded (rules-only, cache-only) decisioning during the transition rather than a full outage for those sellers.
10.2 Graceful degradation
| Failure scenario | Degraded behaviour |
|---|---|
| ML Scoring Service down or timing out | Fall back to rules and graph signals only; temporarily lower the Hold threshold slightly to compensate for the missing signal |
| Identity Linkage Graph Service unreachable | Fall back to the local 1-hop cache only (Section 9.3); flag affected orders for mandatory async re-evaluation once the graph service recovers |
| Velocity Cache (Redis) unreachable within a cell | Apply stricter default rule thresholds temporarily; route new payout decisions to Hold rather than Approve until Redis recovers |
| An entire cell unavailable | Reroute affected sellers to a neighbouring cell with spare capacity and degraded (cache-only) decisioning, per Section 10.1 |
10.3 Idempotency at very high throughput
At millions of requests per minute, retries are frequent and expected. Every fraud decision request carries an idempotency key (the order or payout attempt ID) and the Fraud Decision Gateway short-circuits duplicate requests by checking a short-TTL idempotency record in Redis before doing any real work, both protecting velocity counters from double-counting and reducing unnecessary load on downstream services during retry storms.
A retry storm during a partial outage can itself create a self-inflicted denial-of-service on the very system trying to recover. Combining idempotency keys with client-side exponential backoff and jitter, plus server-side load shedding that prioritises new requests over retries once queues back up, prevents a recovering system from being immediately overwhelmed again by its own clients’ retries.
Security
11.1 Protecting sensitive seller and buyer data
The graph and velocity systems work with hashed or tokenised representations of sensitive identifiers (bank account numbers, government ID numbers used for seller verification) rather than raw values wherever possible, minimising the blast radius if any single component is compromised and reducing the platform’s exposure under relevant data protection and financial services regulations.
11.2 Protecting the fraud system from manipulation
A sophisticated fraud ring will actively probe and adapt to detection systems, so the platform itself needs defences against being reverse-engineered:
- Never expose specific hold or block reasons to sellers. A generic “your payout is under review” message prevents a fraud ring from learning exactly which signal triggered detection and adjusting their next attempt accordingly.
- Strong authentication and full audit logging on the Trust and Safety Dashboard and any tool capable of modifying rules, thresholds or graph data, since these are exactly the internal tools an insider threat or compromised credential would target.
- Rate limit and monitor seller account creation itself, since rapid, automated creation of many new seller accounts is often the first observable step of a triangulation fraud ring assembling its operation.
- Periodically rotate detection thresholds and add controlled randomness to exactly where soft-flag boundaries sit, making systematic probing of the system’s limits less reliable for an attacker.
11.3 Identity verification for sellers
Because a banned fraudster’s fastest path back into the marketplace is registering a new account, stronger identity verification at onboarding (government ID checks, bank account ownership verification, business registration validation where applicable) raises the cost of creating new fraudulent identities. This should be risk-based: low-risk categories and low order-value sellers can onboard with lighter verification, while higher-risk categories (historically correlated with triangulation fraud, such as high-demand electronics) can require stronger verification before full marketplace privileges are granted.
“A fraud ring gets banned and immediately tries to come back with new accounts. How does your system make that harder?” Strong talking points: the Identity Linkage Graph is specifically designed to catch this — even with a new account, new email and new business name, a fraud ring tends to reuse at least one durable signal (a bank account for receiving payouts, a device fingerprint, a shipping address pattern or a phone number used for verification) and graph traversal from any previously confirmed fraud node can surface these reappearing connections even when every visible identity attribute has changed.
Monitoring, Logging & Metrics
12.1 Key metrics to track
| Metric | Why it matters |
|---|---|
| Decision latency (p50, p95, p99), per cell | Directly impacts checkout and payout experience; per-cell breakdown surfaces localised problems that a global average would hide |
| Approve / Hold / Block rate over time, per seller category | A sudden spike in holds for a specific product category can indicate either an active fraud ring or a broken rule |
| False positive rate (via analyst review outcomes) | The primary measure of harm caused to legitimate sellers by the detection system itself |
| Graph query latency and cache hit rate | Indicates health of the most architecturally novel and potentially fragile dependency |
| Cell-level request distribution and imbalance | Uneven cell load can indicate a hot seller shard or a routing bug, both of which threaten the scalability model in Section 9.2 |
| Kafka consumer lag, per partition | Growing lag means velocity counters and the graph fall behind real time, weakening detection during exactly the fast-moving events that matter most |
| Time-to-detection for confirmed fraud cases | Measures how long a fraud ring operated before detection — the single most important outcome metric for this entire system |
12.2 Logging and traceability
Every decision is logged with a structured record: a trace ID shared across every service touched, every rule that fired, the raw ML score and model version, the specific graph signals contributing to the decision and the final outcome. This supports both internal debugging and the seller dispute and appeal process required by most marketplace trust and safety policies.
12.3 Distributed tracing across a cell-based system
Because a single decision fans out across the Rules Engine, ML Scoring Service, Linkage Graph Service and Inventory Verifier, all within a specific cell, distributed tracing (OpenTelemetry with a propagated trace ID) is essential — and trace data should be tagged with the originating cell ID, so latency regressions can be isolated to a specific cell rather than investigated as a vague, platform-wide slowdown.
12.4 Alerting philosophy
- Alert on rate-of-change and per-cell deviation from the platform-wide baseline, not just absolute thresholds, since normal traffic patterns vary significantly by cell composition and time zone.
- Separate system health alerts (latency, errors, cell imbalance) from fraud pattern alerts (a new suspected fraud ring detected), routed to engineering on-call and trust and safety analysts respectively.
- Build a live “active fraud rings” dashboard surfacing the graph’s most recently formed high-risk clusters, so analysts can act while a ring is still small rather than after it has scaled up.
Deployment & Cloud
The deployment diagram below shows the cell-based topology introduced in Section 9.2, which is the foundation of how this system reaches millions of requests per minute without any single cluster becoming a bottleneck.
13.1 Containers and orchestration within each cell
Each service within a cell (Fraud Decision Gateway, Rules Engine, ML Scoring Service, Linkage Graph Service) runs as a container on Kubernetes, with Horizontal Pod Autoscaling driven by request rate and queue depth. Because each cell only serves a fixed shard of sellers, autoscaling within a cell is far more predictable than it would be for a single global cluster absorbing all platform traffic at once.
13.2 Rolling out new cells
Adding capacity at this scale means adding a new cell, not just adding more pods to an existing cluster. Using consistent hashing (Section 9.4) for seller-to-cell routing means a new cell can absorb a defined slice of sellers from existing cells with a bounded, predictable amount of data movement, rather than requiring a full re-shard of the entire seller population.
13.3 Canary deployments per cell
New rule sets and model versions are rolled out to a single cell first, with close comparison of that cell’s decision rates and latency against the platform-wide baseline, before progressively rolling out to remaining cells. This cell-by-cell canary strategy naturally limits the blast radius of a bad deployment to a fraction of total sellers, which is especially valuable given how directly a bad fraud decision affects real sellers’ cash flow.
13.4 Infrastructure as code for a cell-based system
Given that this design assumes cells will be added over time as traffic grows, the entire cell definition (Kubernetes manifests, Redis shard configuration, Kafka partition assignments) is templated as reusable Infrastructure as Code (Terraform modules), so spinning up a new cell is a repeatable, tested, single-command operation rather than manual, error-prone work.
13.5 Cost optimisation at this scale
- Route the cheapest, highest-confidence checks (blocklist and cache lookups) first, reserving expensive graph traversals and ML inference for requests that do not get resolved by cheap checks alone.
- Right-size each cell independently based on its actual seller population’s traffic pattern, rather than provisioning every cell identically for worst-case peak.
- Tier storage: keep only hot, recent velocity and graph-cache data in memory; move historical graph and transaction data to cheaper storage after a defined retention window.
Databases, Caching & Load Balancing
14.1 Choosing the right store for each job
| Data | Store | Why |
|---|---|---|
| Velocity counters (sliding windows) | Redis Cluster, sharded per cell | Sub-millisecond reads and writes essential for the synchronous decision path at this throughput |
| Seller / buyer / address / device relationships | Horizontally partitioned graph database (Neptune, JanusGraph) | Purpose-built for efficient multi-hop relationship traversal, which relational joins handle poorly at this scale |
| Orders and payments (system of record) | Sharded Postgres, per cell or per region | Strong consistency and transactional guarantees required for financial records |
| Real-time ML features | Online Feature Store, Redis-backed | Same low-latency requirement as the rest of the synchronous decision path, while staying consistent with offline training data |
| Historical analytics and training data | OLAP warehouse (Snowflake, BigQuery, ClickHouse) | Optimised for large-scale aggregation across months of historical order and seller data |
| Event stream and audit trail | Kafka, partitioned by seller ID, long retention with cold archive | Durable, ordered, replayable log needed for both real-time processing and later audits or disputes |
14.2 Sharding strategy across cells
Every data store that participates in the synchronous decision path — Redis, the graph database and Postgres — is sharded consistently by seller ID within each cell, matching the cell routing strategy from Section 9.2. This alignment is deliberate: it means a single seller’s complete data footprint (velocity, graph neighbourhood, order history) lives within one cell, avoiding expensive cross-cell queries for the vast majority of decisions.
14.3 Load balancing strategy
At the global layer, anycast DNS and a global load balancer route each request to the nearest healthy region and then to the correct cell based on the seller ID hash. Within a cell, a standard Layer 7 load balancer distributes traffic across API Gateway instances using least-outstanding-requests. Internal service-to-service calls within a cell use client-side load balancing integrated with service discovery, avoiding an extra network hop through a central load balancer for latency-critical internal calls like the Fraud Decision Gateway’s fan-out to the Rules Engine and ML Scoring Service.
14.4 Cross-cell data consistency
As discussed in Section 8.2, cells are intentionally not strongly consistent with each other in real time. A dedicated asynchronous cross-cell reconciliation job periodically merges newly discovered graph edges and confirmed fraud patterns across all cells, so that a fraud ring’s presence discovered in one cell eventually (typically within minutes) informs detection in every other cell, without requiring synchronous cross-cell coordination on the hot path.
“How do you handle a seller who somehow gets data split across two cells, for example after a re-sharding event?” A good answer acknowledges this as a real, if rare, operational scenario: the consistent hashing scheme (Section 9.4) is specifically chosen to minimise how many sellers move during a re-shard and any seller mid-migration is temporarily routed to both old and new cells with a defined cutover point, while the async reconciliation job ensures neither cell’s view of that seller becomes stale or inconsistent during the transition.
APIs & Microservices
15.1 The core fraud evaluation API
POST /v1/fraud/evaluate-payout
Content-Type: application/json
Idempotency-Key: payout_7f3a9c12
{
"orderId": "order_9182a3f0",
"sellerId": "seller_44821",
"buyerId": "buyer_20194",
"shippingAddressHash": "sha256:6b3f2e...",
"orderValue": 249.99,
"currency": "USD",
"listingCategory": "electronics",
"sellerAccountAgeDays": 12,
"declaredWarehouseCountry": "US"
}
Response 200 OK:
{
"orderId": "order_9182a3f0",
"decision": "HOLD",
"riskScore": 0.63,
"reasonCodes": ["GRAPH_SHARED_ADDRESS", "NEW_SELLER_HIGH_VALUE"],
"modelVersion": "triangulation-model-v9",
"cellId": "cell-b",
"decisionLatencyMs": 47
}
15.2 Internal service boundaries
- Rules Engine service: owns rule evaluation logic; rule definitions are stored in a versioned configuration store so trust and safety analysts can update them without a code deploy.
- ML Scoring service: owns model loading, feature retrieval orchestration and inference, hiding model-specific complexity behind a simple scoring API.
- Identity Linkage Graph service: owns graph storage and query execution, exposing both fast cached lookups and slower deep-traversal query endpoints as clearly distinct API operations with different latency expectations.
- Case Management service: owns the lifecycle of flagged sellers and cases, exposing APIs for the analyst dashboard.
15.3 Synchronous versus asynchronous communication
The Fraud Decision Gateway’s fan-out calls to the Rules Engine, ML Scoring Service and the fast graph lookup path are synchronous, using gRPC for low serialisation overhead and strict deadline propagation. Deep graph traversal, graph building, analytics and model feedback are all asynchronous, flowing through Kafka, since none of this needs to block a payout decision that already has enough signal from the fast synchronous checks.
“Would you make the Identity Linkage Graph Service’s API synchronous or asynchronous?” The nuanced answer is “both, as two distinct API operations”. A fast, cache-backed “known risk flag lookup” endpoint is synchronous and part of the hot decision path with a strict deadline. A “deep relationship traversal” endpoint is asynchronous, queued and processed off the hot path, with its results feeding back into the fast lookup cache for future requests. Conflating these into one API with unpredictable latency would be a design mistake at this scale.
Design Patterns & Anti-patterns
16.1 Useful design patterns
| Pattern | How it is used here |
|---|---|
| Circuit Breaker | Wraps calls to the ML Scoring Service and Identity Linkage Graph Service; trips to a fallback (rules-and-cache-only) path when a dependency is slow or failing |
| Bulkhead Pattern | Isolates connection pools per downstream dependency within the Fraud Decision Gateway, so a slow graph query cannot exhaust resources needed for Redis or the ML service |
| CQRS | Writes (order and payout events) flow through Kafka asynchronously; reads (velocity and cached graph signals) are served from fast, denormalised Redis views kept eventually consistent with the write side |
| Sharding / Cell-Based Architecture | The core scaling pattern for this entire design (Section 9.2), partitioning the seller population into independently scaled, independently failing cells |
| Saga Pattern | Coordinates the multi-step order-and-payout flow, with defined compensating actions (payout reversal, funds clawback) if fraud is confirmed after an earlier payout step already succeeded |
| Strategy Pattern | Lets the Rules Engine and ML Scoring Service plug in different evaluation strategies per seller category or region without changing calling code |
16.2 Anti-patterns to avoid
Running unbounded, uncached multi-hop graph traversals synchronously on every single order at millions-of-requests-per-minute scale will overwhelm even a well-partitioned graph database. Always separate cheap cached lookups from expensive deep traversals, as described in Section 15.3.
As discussed in Section 6.2, blocking a legitimate buyer’s purchase because of seller-side risk creates confusing, harmful false positives for someone who did nothing wrong. The payout, not the order, is almost always the correct control point.
Attempting to scale one giant Redis cluster, one giant graph database and one giant service fleet to millions of requests per minute, rather than adopting a cell-based partitioning strategy, creates both a scaling ceiling and a single blast radius for the entire platform (Section 9.2).
Without the asynchronous cross-cell reconciliation job (Section 8.2 and 14.4), a fraud ring can deliberately split its accounts across cells specifically to stay under each individual cell’s local detection threshold, exploiting the very partitioning that makes the system scale.
Best Practices & Common Mistakes
17.1 Best practices
- Always log the full reasoning behind every decision — every rule, graph signal and model score that contributed — since this drives both analyst review and seller dispute resolution.
- Run new rules, thresholds and model versions in shadow mode on a single cell first, comparing outcomes against the live baseline before any real payout impact.
- Design the graduated response (soft flag, hold, block) explicitly and make every automated action reversible until human confirmation, given how directly a wrong decision affects a legitimate seller’s business.
- Invest as much in the async graph-building and reconciliation pipeline as in the synchronous decision path — the pattern detection that actually catches triangulation fraud rings lives largely in the async layer.
- Treat cell capacity planning as an ongoing operational practice, not a one-time design decision, since seller population and traffic patterns shift over time.
- Build strong data-sharing relationships with major partner retailers where possible, since off-platform chargeback signals close a real visibility gap that no amount of internal-only signal can fully replace.
17.2 Common mistakes
- Optimising purely for buyer-side fraud signals and missing that triangulation fraud is fundamentally a seller-behaviour and off-platform visibility problem.
- Under-investing in the identity linkage graph because it is the least familiar, most operationally complex component, even though it is often the single most effective tool against coordinated fraud rings.
- Designing for average throughput instead of true peak and discovering the cell-based architecture’s benefits only after an outage caused by a single over-scaled cluster.
- Ignoring the seller experience impact of false positives, leading to legitimate seller churn that quietly undermines the whole marketplace’s supply side.
- Failing to build the cross-cell reconciliation job early, leaving an exploitable gap for fraud rings that learn to distribute themselves across cell boundaries.
Real-World Industry Examples
Amazon Marketplace seller verification
Amazon has publicly discussed strengthening seller identity verification and account monitoring specifically to combat fraudulent listings and account takeover patterns that enable schemes like triangulation fraud, reflecting the broader industry recognition that seller-side trust signals, not just buyer-side signals, are essential to catching this pattern.
eBay’s seller performance and trust systems
eBay maintains seller performance standards and account-level monitoring that factor in patterns like unusual shipping origins and rapid account behaviour changes, illustrating the industry-standard practice of using seller-level behavioural signals, aggregated over time, rather than relying solely on individual transaction checks.
Retailer fraud advisory sharing
Large retailers frequently targeted by triangulation schemes (electronics and gift card retailers in particular) have engaged in industry fraud-data-sharing initiatives, recognising that no single company sees the whole triangle in a triangulation fraud case and that detection improves meaningfully when retailers and marketplaces share relevant fraud signals such as shipment-to-address patterns linked to disputed charges.
Graph-based fraud detection at financial institutions
Banks and payment networks have long used graph-based entity resolution to detect organised fraud rings that deliberately spread activity across many seemingly unrelated accounts, a technique directly analogous to the Identity Linkage Graph Service in this design and one of the clearest examples of a fraud-detection technique that generalises well from financial services into e-commerce marketplace trust and safety.
Frequently Asked Questions
Q: Can triangulation fraud be stopped completely?
No system eliminates it entirely, since some of the critical evidence (the fraudulent purchase at the legitimate retailer) happens entirely outside the marketplace’s visibility. The realistic goal is to catch it fast enough and often enough, that running a triangulation fraud operation stops being profitable, pushing fraudsters toward easier, less well-defended targets.
Q: How do you avoid punishing legitimate drop-shippers?
By focusing detection on the payment method and relationship evidence, not the drop-shipping business model itself (Section 3.1). A legitimate drop-shipper with a documented, repeatable supplier relationship and consistent shipping origins over time looks very different, structurally, from a seller whose fulfilment source varies unpredictably and whose declared warehouse location never matches actual shipment origins.
Q: Why hold payouts instead of just banning suspicious sellers immediately?
Because early signals are often uncertain and immediately banning a seller based on a single ambiguous signal risks significant harm to a legitimate business. The graduated response model (Section 3.5) exists specifically to let the system act early and reversibly, escalating to a permanent ban only once evidence is strong enough to justify that much more severe, much less reversible action.
Q: How does this system handle a fraud ring that deliberately splits itself across multiple cells?
This is directly addressed by the asynchronous cross-cell reconciliation job described in Sections 8.2 and 14.4, which periodically merges graph data across all cells specifically to catch patterns that a single cell’s local view would not see on its own.
Q: Does this system need to comply with any specific regulations?
Yes — seller identity verification touches Know Your Customer (KYC) and Know Your Business (KYB) style obligations in many jurisdictions and the graph and velocity systems handle personally identifiable information (addresses, bank details) that fall under data protection regulations. The audit trail and reason-code logging described in Section 12.2 support both regulatory reporting and the seller appeal process that most jurisdictions’ consumer protection frameworks require.
Summary & Key Takeaways
Designing a triangulation fraud detection system is a distinctive system design problem because the core evidence of the fraud lives partly outside the platform you are building, the correct point of intervention is the seller’s payout rather than the buyer’s order and the fraud pattern itself is fundamentally relational — making a graph-based approach not just useful but close to essential. Layer on a requirement to sustain millions of requests per minute and the design also becomes a strong test of horizontal scaling strategy, specifically cell-based architecture, consistent hashing and careful separation of cheap synchronous checks from expensive asynchronous ones.
Key takeaways
- Triangulation fraud hides in plain sight on the buyer side — the buyer receives a real item and is satisfied, so detection must shift to seller-behaviour and off-platform shipment-origin signals.
- The payout, not the order, is the correct control point — holding or blocking seller payouts protects against loss without harming an innocent buyer’s experience.
- An identity linkage graph is close to essential, not optional — coordinated fraud rings are fundamentally a relationship pattern that row-level rules and ML models alone will miss.
- Cell-based architecture is the core strategy for reaching millions of requests per minute — partitioning sellers into independently scaled, independently failing cells avoids both a scaling ceiling and a single blast radius.
- Separate cheap synchronous checks from expensive asynchronous ones — cached graph lookups and Redis velocity checks stay on the hot path; deep graph traversal and cross-cell reconciliation run asynchronously.
- A graduated response minimises harm from uncertain early signals — soft flags and reversible holds let the system act early without unfairly punishing legitimate sellers.
- This is a continuous, adaptive arms race — fraud rings actively probe and adapt to detection systems, including deliberately splitting activity across cell boundaries, requiring ongoing investment in reconciliation, monitoring and model retraining.
Design Alternatives Considered
| Alternative | Description | Why it was not chosen as the primary approach |
|---|---|---|
| Single global cluster, no cell-based partitioning | Scale Redis, the graph database and services as one large global cluster | Hits a hard scaling ceiling well before millions of requests per minute and creates a single blast radius where any component failure affects the entire platform |
| Relational-only detection, no graph database | Express relationship queries (shared addresses, shared devices) as SQL joins against a large relational table | Multi-hop relationship queries become prohibitively expensive at scale in a relational model; a purpose-built graph database handles this natural query shape far more efficiently |
| Block the buyer’s order instead of holding the seller’s payout | Apply high-risk decisions directly to order completion | Directly harms an innocent buyer’s experience for a risk that belongs entirely to the seller’s side of the transaction (Section 6.2) |
| Rely entirely on partner retailer chargeback data | Wait for legitimate retailers to report disputed charges and act only on that external signal | Far too slow and incomplete — chargebacks often surface weeks after the fraudulent seller has already been paid out and not all retailers share this data |
| Fully manual trust and safety review for all new sellers | Have human analysts review every new seller and every order before approval | Does not remotely scale to millions of requests per minute and would make onboarding legitimate sellers slow and costly |