Designing a Real-Time Credit Card Fraud Detection System (Sub-100ms Decisions)
How to build a system that looks at a credit card swipe, scores it for fraud, and says APPROVE or DECLINE — all in less time than it takes you to blink — while processing millions of transactions per minute across the globe.
Introduction & History
Every time you tap your card at a coffee shop, a decision has to be made almost instantly: is this really you, or is it someone who stole your card number five minutes ago in a different country? That decision is not made by a human — it is made by a fraud detection system that must respond before the payment terminal times out, before the cashier gets impatient, and before you start wondering why your coffee is taking so long. The industry-standard target for this decision is under 100 milliseconds — faster than the blink of an eye (a blink takes roughly 100-150ms) — end to end, including network round trips.
This tutorial designs exactly that system: one that ingests a live stream of credit card authorization requests at marketplace-payment-processor scale (millions of transactions per minute across global peak periods like Black Friday or Singles’ Day), extracts and looks up features about the cardholder’s recent behavior, runs one or more machine learning models and rule engines, and returns a binary (or graded) decision — all inside a strict, non-negotiable latency budget, because a payment network will simply time out and treat a non-response as a failure if the deadline is missed.
Think of an airport security checkpoint that must process millions of passengers per hour, at multiple airports worldwide, in a matter of seconds each — not by inspecting every single item in every bag (that would take too long) but by using X-ray machines, watchlists, and behavior patterns to instantly flag high-risk passengers for a closer look, while letting everyone else through at full speed. Real-time fraud detection does exactly this for financial transactions, except the “closer look” queue doesn’t exist during authorization — the decision has to be immediate and final within the time budget.
1.1 A short history of the problem
Era 1 — Static Rules
Simple hand-written rules (“decline if transaction amount > $5,000 and country ≠ home country”) evaluated against a single transaction. Fast, but easily bypassed and blind to sophisticated patterns.
Era 2 — Batch-Scored Risk Models
Nightly batch jobs computed a cardholder risk score used the next day. Better accuracy, but a fraudster active today wasn’t caught until tomorrow.
Era 3 — Online Scoring with Cached Features
The rise of low-latency key-value stores (Redis, Memcached) allowed pre-computed features (rolling spend, velocity counters) to be looked up in single-digit milliseconds, enabling real-time scoring for the first time at acceptable latency.
Era 4 — Streaming Features + Real-Time ML
Modern systems combine streaming feature computation (Flink/Kafka Streams updating velocity and behavioral features within milliseconds of each transaction), low-latency model serving (gradient-boosted trees or neural networks served in under 10ms), and hybrid rule+ML decisioning — all orchestrated to fit inside a 100ms end-to-end budget, at a scale of millions of transactions per minute globally.
This tutorial designs an Era-4 system, with an explicit latency budget breakdown (Section 8) because, unlike most system designs where “make it faster” is a nice-to-have, here missing the 100ms deadline is a hard functional failure — the transaction gets an implicit decline or timeout regardless of how good the fraud model would have said “approve.”
By the end of this tutorial you will be able to answer, in interview-level depth, questions like: how do you keep every dependency in a decision pipeline fast enough that their combined cost still fits inside 100 milliseconds; how do you combine a machine learning model’s probabilistic judgment with deterministic, instantly explainable business rules; how do you decide, region by region and merchant by merchant, whether the system should fail open or fail closed when something goes wrong; and how do you scale all of this to millions of transactions per minute without a single global bottleneck. Every architectural box in the diagrams below is explicitly labeled — API Gateway, Load Balancer, Decision Orchestrator, Model Serving Cluster, and so on — exactly as you would draw them on a whiteboard in a real system design interview.
Why is 100ms the target, and what happens if we miss it? A strong answer explains that payment networks (Visa, Mastercard, card-issuer processors) enforce their own timeout windows on the authorization message flow — typically a small number of seconds shared across every hop from merchant to acquirer to network to issuer — and the fraud-decision hop is only one link in that chain, so it’s allocated a strict sub-slice of the total budget. Missing it doesn’t mean “slightly stale data,” it means the transaction is declined by default or the whole authorization fails, directly costing the business a completed sale and harming the customer experience.
Problem & Motivation
2.1 Problem statement
Design a system that, for every incoming card-authorization request, makes a fraud decision (APPROVE / DECLINE / STEP-UP-CHALLENGE) within a strict 100 millisecond end-to-end budget, at a throughput of millions of transactions per minute globally, using real-time and historical features about the card, the merchant, the device, and the transaction context, combined with machine learning models and deterministic rules, while maintaining extremely high availability (a fraud system that’s down cannot simply “fail open” without cost, nor “fail closed” without blocking legitimate commerce).
2.2 Why this is hard
| Challenge | Why It’s Hard |
|---|---|
| Hard latency ceiling | 100ms must cover network hops, feature lookups, model inference, and rule evaluation — combined, not each in isolation. There is very little room for anything slow, including a single unlucky disk read or GC pause. |
| Massive scale | Millions of transactions per minute at global peak (holiday shopping, major sales events) means the system must be horizontally scaled across regions with no single point of contention. |
| Class imbalance | Fraud is rare — often well under 1% of transactions — making naive accuracy metrics meaningless and requiring careful model evaluation (precision/recall, not just “% correct”). |
| Adversarial adaptation | Fraudsters actively probe and adapt to whatever rules/models are in place, meaning the system must evolve continuously, not be a “build once” static system. |
| Feature freshness | The most predictive signals (e.g., “5 transactions on this card in the last 2 minutes across 3 countries”) are only useful if computed and available within milliseconds of the events that produced them. |
| Cost of both error types | A false decline angers a legitimate customer and costs the merchant a sale (and can drive customer churn); a false approval directly costs money via chargebacks. The system must be tunable to the business’s risk appetite, not just “as accurate as possible” in the abstract. |
| Global regulatory variation | Different regions (EU’s SCA/PSD2, US, APAC) impose different requirements on when a strong customer authentication step-up is mandatory versus optional, which the decisioning logic must respect. |
A frequent design mistake is optimizing purely for model accuracy while ignoring the “cold” and “warm” path split — trying to fetch a customer’s entire multi-year transaction history from a large historical data store synchronously, on every single transaction, inside the 100ms window. That data belongs in pre-aggregated, low-latency feature stores updated asynchronously, not queried live from a data warehouse during the hot decision path.
2.3 Goals
- Functional: real-time, per-transaction fraud decisioning (APPROVE/DECLINE/CHALLENGE) with explainable contributing factors, at P99 latency under 100ms end to end.
- Non-functional: horizontal scalability to millions of transactions/minute, 99.99%+ availability (with an explicit, safe fail-open/fail-closed policy per merchant risk tier), strict data security/compliance (PCI-DSS), and continuous model/rule evolution without downtime.
2.4 Non-goals
This system is not a post-transaction dispute/chargeback investigation tool (that’s a separate, offline workflow), not a general anti-money-laundering (AML) case-management system (though it may share signals with one), and not responsible for merchant-side fraud (fake merchants, refund fraud) — this tutorial is scoped specifically to the real-time authorization-time decision for a single card transaction.
Core Concepts You Need First
Authorization Request
What: The message sent from a merchant’s payment terminal (via an acquirer and card network) to the issuing bank asking “should this transaction be approved?” Why: It’s the trigger event for the entire fraud-decisioning pipeline — nothing happens until this arrives. Analogy: Like a bouncer at a club being asked “can this person come in?” — a yes/no answer is needed immediately. Example: Card ending 4242, $87.50, merchant “Downtown Coffee Co.”, card-present, timestamp 14:32:07.113Z.
Feature Store (Online/Offline)
What: A system that stores precomputed, ready-to-use signals (features) about entities (cards, merchants, devices) for fast lookup at decision time, plus a separate offline store for training data. Why: Computing “how many transactions has this card made in the last 5 minutes” from scratch on every request would be far too slow; instead it’s maintained incrementally and read in under a millisecond. Analogy: A hospital’s whiteboard summary of a patient’s vitals at the nurses’ station, updated continuously, versus digging through the patient’s entire lifetime medical archive for every question. Example: card_id → {txn_count_5min: 3, distinct_countries_1hr: 2, avg_amount_30d: 42.10}.
Velocity Features
What: Features measuring the rate or frequency of activity over short time windows — how many transactions, how much money, across how many merchants/locations, in the last N minutes/hours. Why: Fraud very often manifests as a burst of rapid activity (a stolen card being used quickly before it’s blocked), making velocity one of the single strongest fraud signals. Analogy: A single sip from your coffee is normal; someone gulping ten cups in five minutes is a red flag regardless of how “normal” any one sip looks alone. Example: “5 transactions in 3 minutes across 3 different countries” is a classic high-velocity fraud pattern.
Model Serving / Inference
What: The act of taking a trained machine learning model and using it to produce a prediction (a fraud probability score) for a new, live input. Why: This is where the “intelligence” of the system lives — turning a feature vector into an actionable risk number. Analogy: A trained doctor glancing at a patient’s chart and immediately giving a risk assessment, versus a med student re-deriving medical knowledge from a textbook each time. Example: A gradient-boosted tree model taking 40 numeric features and returning fraud_probability = 0.87 in under 5 milliseconds.
Rule Engine
What: A component that evaluates deterministic, human-authored conditions (“if amount > $10,000 and country is on the high-risk list, then decline”) independent of or alongside the ML model. Why: Rules are instantly explainable, can encode hard regulatory/business constraints the model shouldn’t be trusted to learn on its own, and can react to newly discovered fraud patterns in minutes rather than waiting for a model retrain. Analogy: Airport security’s explicit “no liquids over 100ml” rule alongside the X-ray machine’s pattern-based judgment — both operate together. Example: A rule instantly declining any transaction from a card already reported stolen, regardless of what the ML model says.
Circuit Breaker
What: A pattern where a component detects that a downstream dependency is failing or too slow, and “trips” to bypass it (using a fallback) rather than waiting and risking a timeout. Why: If the ML scoring service becomes slow, the entire transaction pipeline must not slow down with it — a fallback (like rules-only decisioning) has to kick in instantly. Analogy: A backup generator that kicks in automatically the instant the main power flickers, rather than waiting to see if the lights come back on their own. Example: If the model-serving p99 latency exceeds 15ms for a sustained period, the orchestrator falls back to rules-only scoring for new requests until it recovers.
Sidecar / Co-located Caching
What: Placing a small, fast local cache physically close to (or embedded within) the service that needs it, rather than always making a network call to a remote store. Why: Even a fast network call to Redis (sub-millisecond) adds up when you have several sequential lookups inside a 100ms budget with global network hops involved; local caching shaves off round trips. Analogy: Keeping frequently used spices on your kitchen counter instead of walking to the pantry every time you cook. Example: The Decision Orchestrator keeps a local in-memory LRU cache of recently seen merchant risk tiers to avoid a remote lookup on every request.
Idempotency Key
What: A unique identifier attached to a request so that retries (from network blips) don’t cause duplicate processing. Why: Payment networks retry authorization requests under uncertain network conditions; without idempotency, a single physical transaction could be double-scored, double-declined, or double-approved. Analogy: A deli’s numbered ticket system — showing the same ticket number twice doesn’t get you two sandwiches. Example: Each authorization carries a unique transaction_id; the Decision Orchestrator caches the decision for that ID for a short TTL so a retry within that window returns the identical decision instantly.
Fan-Out / Fan-In
What: A pattern where one incoming request triggers several independent downstream calls simultaneously (fan-out), and the orchestrating service waits for all (or enough) of them to complete before combining their results into a single response (fan-in). Why: Inside a strict latency budget, doing several independent lookups one after another wastes time that parallelism can reclaim, since the total wait becomes the slowest single call rather than the sum of all of them. Analogy: A restaurant kitchen starting the grill, the fryer, and the salad station all at once for one table’s order. Example: The Orchestrator fans out simultaneously to the Feature Store, Device Risk Service, and Rule Engine, then fans in their three results before calling the model.
Chargeback
What: A formal dispute process where a cardholder (or issuer) reverses a completed transaction, typically weeks after it happened, because it was fraudulent or otherwise disputed. Why: Chargebacks are the delayed “ground truth” label that tells the system, after the fact, whether a transaction it approved was actually fraudulent — the primary source of training labels for the ML model. Analogy: A returned, defective product arriving back at a warehouse weeks after it shipped. Example: A transaction approved as low-risk that later generates a chargeback becomes a labeled false-negative example fed back into the next model training cycle.
Model Drift
What: The gradual degradation of a machine learning model’s accuracy over time as the real-world patterns it was trained on change. Why: Fraud is adversarial — fraudsters actively adapt to whatever detection patterns are currently effective, meaning a fraud model’s accuracy decays faster than in most other ML domains, and left unchecked, a model can quietly become far less effective without any code change ever occurring. Analogy: A security guard who memorized last year’s list of troublemakers’ faces but has no idea what this year’s new troublemakers look like. Example: A model’s precision drops from 92% to 81% over three months as a new fraud ring’s tactics diverge from the training data, triggering a scheduled retrain.
Architecture & Components
Every box below is deliberately labeled with its concrete role, exactly as it would appear on a whiteboard in a system design interview.
4.1 High-level architecture diagram
Ingestion auth validation”] LB1[“Load Balancer L7
Decision path”] ORCH[“Decision Orchestrator
parallel fanout coordinator”] subgraph Parallel[“Parallel Lookups Inside Budget”] FEAT[“Online Feature Store
velocity behavior features”] DEV[“Device Identity Risk Service”] RULE[“Rule Engine Service
deterministic overrides”] end MODEL[“Model Serving Cluster
gradient boosted tree inference”] CACHE[“Decision Cache Redis
idempotency”] CFG[“Config Rules Management Service”] KAFKA[“Kafka Message Broker
transaction events”] STREAM[“Streaming Feature Pipeline
Flink rolling counters”] SINK[“Async Event Sink Data Lake
audit and retraining”] GW2[“API Gateway Serving Path”] LB2[“Load Balancer L7 Serving Path”] API[“Serving API case management”] DASH[“Analyst Dashboards”] MER –> ACQ ACQ –> NET NET –> EDGE EDGE –> GW1 GW1 –> LB1 LB1 –> ORCH ORCH –> CACHE ORCH –> FEAT ORCH –> DEV ORCH –> RULE CFG –> RULE ORCH –> MODEL ORCH –> KAFKA KAFKA –> STREAM STREAM –> FEAT KAFKA –> SINK ORCH –> NET DASH –> GW2 GW2 –> LB2 LB2 –> API API –> SINK
4.2 Component responsibilities
| Component | Responsibility |
|---|---|
| Merchant / Acquirer / Card Network | External sources of the authorization request; the network enforces the overall timeout budget the whole chain must respect. |
| Edge Ingress / WAF | TLS termination and network-level protection at the point the issuer’s infrastructure receives the authorization message. |
| API Gateway | Single entry point for authorization requests; enforces authentication between the issuer’s systems and internal services, request validation, and per-merchant rate limiting. |
| Load Balancer (L4/L7) | Distributes each incoming authorization request across many stateless Decision Orchestrator instances, health-checking and evicting unhealthy nodes in milliseconds. |
| Decision Orchestrator Service | The central hot-path service: receives the request, triggers parallel feature lookups, calls the model-serving layer and rule engine, combines results, and returns the final decision within budget. |
| Online Feature Store (low-latency KV store) | Serves precomputed velocity/behavioral features for the card, merchant, and device in sub-millisecond time. |
| Streaming Feature Pipeline (Flink/Kafka Streams) | Continuously consumes the transaction event stream and updates rolling velocity/behavioral features in the Online Feature Store within milliseconds of each event. |
| Message Broker (Kafka) | Durable, ordered event backbone carrying transaction events to the streaming feature pipeline and to downstream analytics/audit consumers, decoupled from the synchronous decision path. |
| Model Serving Cluster | Hosts the trained fraud ML model(s) for ultra-low-latency inference, returning a fraud probability score for a given feature vector. |
| Rule Engine Service | Evaluates deterministic business/regulatory rules in parallel with the ML model, producing hard overrides (e.g., instant decline for a reported-stolen card). |
| Decision Cache (Redis) | Stores recent decisions keyed by transaction/idempotency key to serve instant, identical responses to network retries. |
| Device/Identity Risk Service | Provides device fingerprint and identity-risk signals (e.g., known-bad device IDs) via a fast cached lookup, feeding into both the model and rule engine. |
| Config/Rules Management Service | Stores and versions rule definitions and per-merchant risk thresholds, editable without redeploying the hot path. |
| Async Event Sink (Kafka + Data Lake) | Every decision and its full context is asynchronously logged for audit, model retraining, and offline analytics — entirely off the synchronous critical path. |
| Serving API + its own API Gateway/Load Balancer | A separate, isolated read path fronting case-management/analyst dashboards, so investigative queries never compete with hot-path traffic. |
Why have a separate Rule Engine Service instead of just encoding hard rules inside the ML model or the orchestrator itself? — Rules need to be added/changed within minutes (e.g., instantly blocking a newly identified compromised merchant) without a model retrain-and-redeploy cycle, and they need to be independently auditable for regulatory reasons (a regulator can ask “why was this declined” and a rule gives a crisp, deterministic answer, whereas an ML model’s reasoning is comparatively opaque). Keeping them as a distinct, fast, versioned service lets both concerns evolve on their own release cadence.
4.3 Component deep-dive
API Gateway
What: The single entry point that all authorization requests pass through before reaching the Decision Orchestrator. Why here: Centralizes authentication of the network/acquirer connection, request-schema validation, and per-source rate limiting, so the orchestrator’s hot-path code stays entirely focused on fraud logic, not connection/protocol concerns.
Load Balancer
What: Distributes each request across many stateless Decision Orchestrator replicas. Why here: At millions of transactions per minute, no single instance can handle the load; the load balancer’s health checks are also what removes a slow or degraded instance from rotation within milliseconds, which matters enormously under a 100ms budget where one bad instance could otherwise blow the deadline for many requests.
Online Feature Store
What: A low-latency key-value store (often an in-memory store like Redis, or a purpose-built low-latency feature-serving system) holding the latest computed features per card/merchant/device. Why here: Feature lookups must return in low single-digit milliseconds; a system designed for analytical queries (like a data warehouse) simply cannot meet this latency at this request volume.
Streaming Feature Pipeline
What: A stateful stream-processing job (Flink is the industry-standard choice) that consumes the transaction event stream and incrementally updates rolling counters/aggregates. Why here: Fraud’s strongest signals are velocity-based and time-sensitive; if features were only refreshed by a nightly batch job, they would be useless for catching a fast-moving fraud burst happening right now.
Model Serving Cluster
What: A dedicated, horizontally scaled inference service hosting the trained fraud model, optimized specifically for latency (not just throughput). Why here: Separating model serving from the orchestrator allows independent scaling, independent deployment of new model versions (via canary), and hardware specialization (e.g., optimized numeric libraries, sometimes GPU acceleration for deep models) without touching orchestration logic.
Rule Engine Service
What: A fast, deterministic evaluator of business/compliance rules, typically compiled or JIT-evaluated for speed rather than interpreted line-by-line at request time. Why here: Rules must both run inside the same tight budget as the model and be independently auditable/explainable — qualities a black-box ML model alone cannot provide for regulators or dispute resolution.
Decision Cache (Redis)
What: A short-TTL cache mapping a transaction’s idempotency key to its already-computed decision. Why here: Payment networks retry authorization messages under ambiguous network conditions; without this cache, a retried message could be independently re-scored, potentially producing an inconsistent decision or double-counting the transaction in velocity features.
Internal Working
- A cardholder taps their card. The merchant terminal sends an authorization message through the acquirer to the card network, which routes it to the issuer’s infrastructure — arriving at the Edge Ingress / API Gateway.
- The API Gateway authenticates the connection, validates the message schema, and forwards it through the Load Balancer to an available Decision Orchestrator instance.
- The Decision Orchestrator immediately checks the Decision Cache using the transaction’s idempotency key — if this exact transaction was already scored (a network retry), the cached decision is returned instantly, skipping the rest of the pipeline entirely.
- On a cache miss (the normal case), the Orchestrator fires off several lookups in parallel, not sequentially: a feature lookup to the Online Feature Store (card velocity, merchant risk tier, recent geography), a device/identity risk lookup, and a call to the Rule Engine Service.
- Once features are assembled, the Orchestrator calls the Model Serving Cluster with the feature vector, which returns a fraud probability score in a few milliseconds.
- The Orchestrator combines the rule engine’s verdict (which can hard-override to DECLINE regardless of the model) with the model’s probability score against a merchant/region-specific threshold, producing a final decision: APPROVE, DECLINE, or CHALLENGE (step-up authentication).
- The decision is written to the Decision Cache (for retry-safety) and returned through the Load Balancer and API Gateway back through the network to the merchant — ideally with tens of milliseconds still to spare inside the 100ms budget.
- Asynchronously, and entirely off this critical path, the full transaction plus its decision and contributing factors is published to Kafka for the streaming feature pipeline (to update velocity counters for the next transaction) and to the Async Event Sink / Data Lake for audit, dispute handling, and future model retraining.
This mirrors a hospital emergency room’s triage process: multiple checks (vital signs, medical history lookup, doctor’s quick assessment) happen in parallel rather than one after another, because a patient in a true emergency cannot wait for each check to finish sequentially. The “rule engine” is like an immediate, non-negotiable protocol (“if no pulse, start CPR now”) that overrides more nuanced judgment when a hard threshold is crossed.
Step 4 — doing feature lookup, device-risk lookup, and rule evaluation in parallel rather than sequentially — is the highest-leverage architectural call in the entire design. Inside a 100ms budget, sequential I/O calls are the single biggest threat to meeting the deadline: three sequential 10ms lookups cost 30ms, while the same three run in parallel cost roughly 10ms (bounded by the slowest one), which is precisely the difference between comfortably meeting the SLA and blowing it under any added network jitter.
Data Flow & Lifecycle
As with the earlier tutorial’s category-anomaly design, this system has two parallel lifecycles: the short, strict synchronous lifecycle of a single authorization request (must complete in under 100ms), and the long-running, continuously updating lifecycle of a card’s or merchant’s rolling risk features (never “finishes,” constantly refreshed by the streaming pipeline). The sequence diagram below focuses on the synchronous request lifecycle, since that is where the hard latency constraint lives.
What happens to the feature update if the streaming pipeline falls behind during a traffic spike? — The synchronous decision path never blocks on the streaming pipeline being caught up. It always reads whatever the Online Feature Store currently has, even if it’s a few hundred milliseconds stale during an extreme spike. This is a deliberate availability-over-consistency trade-off (see the CAP theorem discussion later): a slightly stale velocity feature is far preferable to blocking or slowing down every authorization decision while waiting for the pipeline to catch up.
Fraud Scoring & Decisioning
Let’s look at how the actual decision is computed once features, a model score, and rule verdicts are all in hand.
7.1 Hybrid rules + ML scoring
What: Combining fast, explainable, deterministic rules with a probabilistic ML model rather than relying on either alone. Why: Rules catch known, hard-and-fast patterns instantly and are trivially explainable to regulators and dispute teams; ML catches subtle, evolving patterns humans haven’t explicitly encoded yet. How they combine: Rules can hard-override to DECLINE (e.g., card reported stolen) regardless of model score; otherwise, the model’s fraud probability is compared against a threshold to decide APPROVE / CHALLENGE / DECLINE.
7.2 Gradient-boosted trees for low-latency inference
What: An ensemble machine learning model (like XGBoost or LightGBM) that is fast to evaluate at inference time (often sub-millisecond to a few milliseconds for a single prediction) and works well on the kind of structured, tabular features (amounts, counts, categorical merchant codes) that describe a transaction. Why: Deep neural networks can be more powerful for some fraud patterns but are typically slower and heavier to serve at this latency budget unless carefully optimized; gradient-boosted trees remain the industry default for the primary real-time score precisely because of their excellent latency/accuracy trade-off.
7.3 Threshold calibration per risk tier
What: Instead of one global fraud-probability threshold, the system uses different thresholds per merchant category, region, and transaction amount band. Why: The cost of a false decline versus a false approval isn’t uniform — a $5 coffee purchase can tolerate a much more lenient threshold than a $5,000 electronics purchase, because the financial exposure of a wrong decision differs by orders of magnitude.
7.4 Step-up challenge as a third option
What: Instead of a strict binary APPROVE/DECLINE, transactions in an ambiguous risk band (moderate fraud probability) can be routed to a step-up authentication challenge (e.g., a one-time code or biometric confirmation) rather than an outright decline. Why: This recovers legitimate transactions that would otherwise be falsely declined, at the cost of some added friction — the “smart middle ground” required by regulations like PSD2’s Strong Customer Authentication in the EU.
7.5 Cost-sensitive threshold selection
What: Choosing the decision threshold not by pure statistical accuracy but by explicitly weighing the dollar cost of a false decline (lost sale, customer churn risk) against the dollar cost of a false approval (chargeback liability, fees, reputational cost). Why: Because fraud is rare, a model optimized purely for accuracy would learn to nearly always predict “not fraud” and still score well on paper while missing almost every real case — the threshold has to be chosen against the business’s actual cost structure. Example: If a false decline costs the business an estimated $8 in lost margin/goodwill on average, and a false approval costs $45 in chargeback and fee liability on average, the threshold is tuned so that the expected combined cost is minimized:
$$ text{ExpectedCost} = C_{text{FD}} cdot P(text{FD} mid text{approve}) + C_{text{FA}} cdot P(text{FA} mid text{approve}) $$
where $C_{text{FD}}$ and $C_{text{FA}}$ are the per-error costs and the threshold $tau$ is chosen to minimize the total expected cost across the traffic mix.
7.6 Model explainability for regulatory and dispute needs
What: Techniques (such as SHAP values or simpler feature-contribution breakdowns) that attribute a model’s fraud-probability output to specific input features, producing a human-readable explanation alongside the raw score. Why: Regulators, dispute-resolution teams, and sometimes customers themselves are entitled to understand why a transaction was declined; a bare probability number with no explanation is both an operational liability and, in some jurisdictions, a compliance gap. Example: A declined transaction’s response carries not just fraudProbability: 0.87 but also its top three contributing factors — e.g., “unusual merchant category for this card,” “high transaction velocity in the last 10 minutes,” “new/unrecognized device.”
7.7 A simplified decision combiner (Java)
// Combines rule-engine verdicts and an ML fraud-probability score
// into a final APPROVE / CHALLENGE / DECLINE decision.
public class FraudDecisionCombiner {
private final double declineThreshold;
private final double challengeThreshold;
public FraudDecisionCombiner(double declineThreshold, double challengeThreshold) {
this.declineThreshold = declineThreshold;
this.challengeThreshold = challengeThreshold;
}
public Decision decide(RuleVerdict ruleVerdict, double modelFraudProbability,
RiskTier riskTier) {
// Hard rule overrides always win, regardless of model score.
if (ruleVerdict == RuleVerdict.HARD_DECLINE) {
return new Decision(Outcome.DECLINE, "rule_hard_override", modelFraudProbability);
}
if (ruleVerdict == RuleVerdict.HARD_APPROVE) {
return new Decision(Outcome.APPROVE, "rule_trusted_override", modelFraudProbability);
}
// Adjust thresholds by risk tier (e.g., high-value electronics
// gets stricter thresholds than a low-value grocery purchase).
double effectiveDeclineThreshold = declineThreshold - riskTier.thresholdAdjustment();
double effectiveChallengeThreshold = challengeThreshold - riskTier.thresholdAdjustment();
if (modelFraudProbability >= effectiveDeclineThreshold) {
return new Decision(Outcome.DECLINE, "model_high_risk", modelFraudProbability);
} else if (modelFraudProbability >= effectiveChallengeThreshold) {
return new Decision(Outcome.CHALLENGE, "model_medium_risk", modelFraudProbability);
}
return new Decision(Outcome.APPROVE, "model_low_risk", modelFraudProbability);
}
public enum Outcome { APPROVE, CHALLENGE, DECLINE }
public enum RuleVerdict { HARD_DECLINE, HARD_APPROVE, NO_OVERRIDE }
public record Decision(Outcome outcome, String reasonCode, double fraudProbability) {}
public interface RiskTier {
double thresholdAdjustment(); // positive value = stricter effective threshold
}
}
Treating the ML model’s fraud probability as the only input and ignoring hard rule overrides is a common and dangerous mistake — a model trained on historical data has no way to instantly react to a card being reported stolen five seconds ago, or to a newly identified compromised merchant. The rule engine exists precisely to handle these “we already know this is bad, don’t wait for the model to learn it” cases.
The 100ms Latency Budget
This is the section that makes this design fundamentally different from most system designs: latency isn’t a “nice to have” metric to optimize after the fact — it’s a hard constraint that shapes every architectural decision from the very start. Let’s break the budget down explicitly.
8.1 Illustrative latency budget (P99, single transaction)
| Stage | Budget (ms) | Notes |
|---|---|---|
| Network: merchant → acquirer → network → issuer edge | ~20-30ms | Largely outside this system’s control; varies by geography and network hops. |
| API Gateway + Load Balancer routing | ~1-2ms | Kept minimal via connection reuse (keep-alive/HTTP2) and lightweight auth checks. |
| Decision Cache lookup (idempotency check) | ~0.5-1ms | In-memory/Redis lookup, always attempted first. |
| Parallel: feature store lookup, device-risk lookup, rule engine evaluation | ~5-10ms | Run concurrently, bounded by the slowest of the three, not their sum. |
| Model inference | ~3-8ms | Gradient-boosted tree evaluation on a pre-optimized serving runtime. |
| Decision combination + cache write | ~1ms | Simple in-memory logic, asynchronous cache write (fire-and-forget where safe). |
| Return network path: issuer → network → acquirer → merchant | ~20-30ms | Symmetric with the inbound network hop. |
| Total (typical) | ~55-80ms | Leaves headroom under the 100ms ceiling for jitter, retries, and regional variance. |
If you’re already spending 40-60ms just on network round trips outside your control, how do you protect the remaining budget? — Treat the remaining ~40-50ms as the system’s actual internal SLA, and enforce per-stage timeouts aggressively — for instance, giving the feature lookups and rule engine a strict 10ms timeout each, with a well-defined fallback (proceed with whatever features are available, or fall back to rules-only scoring) rather than waiting indefinitely. A single slow dependency must never be allowed to consume the entire remaining budget.
8.2 Timeout & fallback strategy
- Feature store timeout (e.g., 8ms): On timeout, proceed with whatever features are available (possibly stale, cached-elsewhere copies) rather than blocking; log the degradation for monitoring.
- Model serving timeout (e.g., 15ms): On timeout or model-service failure, the circuit breaker trips and the Orchestrator falls back to rules-only decisioning for a cooldown period, accepting a temporarily higher false-negative rate in exchange for guaranteed latency.
- Overall Orchestrator deadline (e.g., 45ms internal budget): If the cumulative elapsed time approaches this ceiling, the Orchestrator short-circuits to a safe default decision (typically a conservative APPROVE for very low transaction amounts, or CHALLENGE for higher amounts) rather than risk a network-level timeout that produces an even worse implicit decline with zero visibility.
Large card networks and issuer processors are known to enforce end-to-end authorization timeouts in the single-digit seconds across the entire merchant-to-issuer round trip, with issuers allocating only a small slice of that budget to their own fraud-decisioning hop — reinforcing why internal designs treat sub-100ms (or even tighter, in some issuer implementations) as a strict, load-bearing requirement rather than an aspirational target.
Advantages, Disadvantages & Trade-offs
Advantages
- Catches fraud within the same transaction it occurs in, preventing loss rather than only detecting it afterward.
- The hybrid rules+ML approach gets the best of both worlds: instant reaction to known bad patterns plus adaptive detection of new ones.
- Parallelized feature/rule lookups and aggressive per-stage timeouts make the system resilient to partial slowdowns without blowing the overall latency budget.
- Separating the streaming feature pipeline from the synchronous decision path means feature computation can be arbitrarily sophisticated without threatening the hot-path SLA.
Disadvantages / Trade-offs
- Complexity vs. speed: A pure rules-only system is far simpler to build, test, and explain, but misses subtle fraud patterns a model would catch; the hybrid approach trades operational complexity for both speed and accuracy.
- Fail-open vs. fail-closed: When the fraud system itself is degraded, the business must choose between approving transactions with reduced scrutiny (fail-open, risking fraud losses) or declining more aggressively (fail-closed, risking legitimate customer friction) — there’s no free option, only a documented, tier-specific policy.
- Model staleness vs. retraining cost: A model retrained too rarely drifts as fraud patterns evolve; retraining too frequently risks instability and requires heavier MLOps investment (validation, canarying, monitoring for regressions).
- Explainability vs. raw accuracy: More complex models (deep neural nets, large ensembles) can outperform simpler ones on raw accuracy but are harder to explain to regulators/dispute teams and often slower to serve within budget.
Would you ever recommend NOT building the full real-time ML pipeline? — Yes. A smaller issuer or a low-fraud-risk vertical might reasonably rely on rules plus a lightweight, cheap-to-operate model, since the operational cost (MLOps, feature pipeline, on-call burden) of a full real-time ML system is only justified once transaction volume and fraud exposure are large enough to make the incremental accuracy gain worth the investment.
Performance & Scalability
10.1 Back-of-the-envelope estimation (million-requests-per-minute scenario)
- Assume 2 million authorization requests/minute at global peak, or roughly 33,000 requests/sec sustained, with bursts several times higher during major shopping events.
- Each Decision Orchestrator instance, if it can sustain roughly 2,000-3,000 requests/sec at sub-100ms latency (a realistic figure for a well-tuned, mostly-I/O-bound service with async parallel fan-out), requires on the order of 12-17 instances at sustained peak, with headroom (typically 2-3×) provisioned for burst and failover — so a fleet sized in the several dozens of instances per region is a reasonable planning number.
- Each request triggers roughly 3-4 downstream calls (feature store, device-risk, rule engine, model serving) run in parallel, meaning the Online Feature Store and Model Serving Cluster must each independently sustain the full 33,000+ QPS, not a fraction of it.
- Regional deployment is essential: routing each authorization to the nearest region (geo-routing at the network/DNS or acquirer-routing level) both reduces network latency (a large chunk of the 100ms budget) and naturally partitions load across independent regional fleets.
10.2 Scaling techniques per layer
| Layer | Scaling Technique |
|---|---|
| API Gateway / Load Balancer | Horizontally auto-scaled, deployed per region; HTTP keep-alive/connection pooling to avoid repeated TLS handshake overhead per request. |
| Decision Orchestrator | Stateless, horizontally scaled per region; sized generously with headroom since it sits directly in the latency-critical path — never runs “hot” at the edge of its capacity. |
| Online Feature Store | Sharded/clustered in-memory store (e.g., Redis Cluster) keyed by card/merchant/device ID hash, with regional replicas to avoid cross-region lookups during the hot path. |
| Streaming Feature Pipeline | Partitioned Flink job scaled by adding parallelism/task managers matching Kafka partition count; RocksDB state backend with incremental checkpointing for large keyed state. |
| Model Serving Cluster | Horizontally scaled, stateless inference replicas; batched-but-bounded inference where feasible, though in the strict low-latency path single-request inference is usually preferred over micro-batching to avoid added queueing delay. |
| Kafka | Scaled via additional brokers/partitions; the synchronous decision path never waits on Kafka writes (transaction events are published asynchronously, fire-and-forget with at-least-once guarantees), keeping Kafka entirely off the latency-critical path. |
10.3 Regional sharding & global consistency trade-off
Because network latency itself consumes a large share of the 100ms budget, this system is deployed as independent regional stacks (their own Decision Orchestrator fleet, feature store replica, model serving cluster) rather than one global cluster. This means a card used in two different regions within a short window relies on cross-region feature replication (typically asynchronous, with a small propagation delay) rather than a single global source of truth queried synchronously — an explicit, deliberate trade-off favoring low latency over perfectly fresh global consistency, discussed further in the CAP theorem context below.
10.4 CAP theorem applied to this design
Under the CAP theorem, a distributed system facing a network partition must choose between strict Consistency and Availability. This design deliberately chooses availability with eventual consistency for the feature layer: a card used first in Tokyo and moments later in London will have its London-region feature lookup reflect the Tokyo transaction only after cross-region replication catches up (typically well under a second, but not instantaneous), rather than the London Decision Orchestrator blocking on a synchronous cross-region read to guarantee perfect freshness. The alternative — synchronous cross-region consistency — would add tens to hundreds of milliseconds of network latency to every single transaction, which is simply incompatible with a 100ms global budget. The small residual risk this trade-off accepts (a fraudster rapidly using a card across two regions within the replication-lag window) is explicitly mitigated by velocity rules and step-up challenges rather than by trying to force strict consistency into a latency budget that cannot afford it.
10.5 Storage & state sizing
- Online Feature Store: With hundreds of millions of active cards, each holding a compact rolling-feature record (velocity counters, recent geography, a handful of aggregates — a few hundred bytes each), total feature-store data volume lands in the range of tens to a few hundred gigabytes per region, comfortably served from memory by a modestly sized Redis Cluster.
- Kafka retention: At roughly 33,000 transaction events/sec and a modest per-event payload (a few hundred bytes), 24 hours of retention on the transaction-event topic is on the order of a few terabytes — well within a standard multi-broker cluster’s capacity, especially with compression enabled.
- Model Serving Cluster sizing: If a single inference-serving replica can sustain a few thousand low-latency predictions per second, sustaining 33,000+ requests/sec per region requires a modest fleet (low double digits of replicas) with generous headroom, since this cluster sits directly in the latency-critical path and should never be run near saturation.
10.6 Handling traffic spikes (holiday shopping style)
- Predictive/pre-warmed scaling: Capacity for the Decision Orchestrator and Model Serving Cluster is scaled ahead of known peak shopping periods rather than purely reactively, since reactive autoscaling can lag a sudden multi-fold spike by the very seconds that matter most for a strict latency SLA.
- Load shedding as an absolute last resort: If the ingestion path is truly saturated beyond provisioned headroom, the system sheds the least-critical non-transactional traffic (e.g., analyst dashboard queries against the Serving API) long before it would ever consider degrading the core authorization-scoring path.
- Elastic feature-store and Kafka partition scaling: Additional Redis Cluster shards and Kafka partitions can be added ahead of a known peak event, spreading load more finely across the fleet rather than relying on a fixed partition count sized for average-day traffic.
Global payment processors operate regional data centers specifically so that authorization decisions for a transaction in, say, Singapore never have to make a round trip to a US-based data center — the latency cost of such a round trip alone could consume the entire 100ms budget before any fraud logic even runs.
High Availability & Reliability
- Multi-AZ, multi-region deployment: Every component is deployed across multiple availability zones within a region, and multiple regions globally, so a zone or regional failure degrades capacity rather than causing an outage.
- Fail-open/fail-closed policy per merchant tier: When the Model Serving Cluster or Rule Engine is unavailable beyond its circuit-breaker threshold, the Orchestrator falls back to a pre-defined, tier-specific safe default (e.g., approve low-value transactions from established, low-risk merchants; challenge or decline higher-value/higher-risk ones) rather than blocking indefinitely.
- Graceful degradation of the feature store: If a specific feature lookup times out, the Orchestrator proceeds with a reduced feature set (flagging the decision as “degraded” for monitoring) instead of failing the entire request.
- Chaos testing: Regularly killing Decision Orchestrator instances, Model Serving replicas, and feature store nodes in staging to verify failover and circuit-breaker behavior under realistic conditions before a real incident tests them for the first time.
- Disaster recovery: Regional data replicated asynchronously to a standby region; the Async Event Sink’s Data Lake archive is the ultimate source of truth for full historical reconciliation if a region needs to be rebuilt.
11.1 Failure scenarios worked through
| Failure | System Behavior |
|---|---|
| Model Serving Cluster becomes slow (p99 > 15ms) | Circuit breaker trips; Orchestrator falls back to rules-only decisioning for a cooldown window, preserving latency at the cost of temporarily reduced model-driven accuracy. |
| Online Feature Store node fails | Cluster’s replication (e.g., Redis Cluster replicas) promotes a replacement automatically; a brief window of degraded (partially stale) feature reads is tolerated rather than blocking. |
| Entire region becomes unreachable | Acquirer/network-level routing fails over to the nearest healthy region; asynchronous cross-region feature replication means the new region has slightly stale — but present — feature data rather than none at all. |
| Kafka is temporarily unavailable | The synchronous decision path is unaffected (it never depends on Kafka availability); asynchronous feature updates and audit logging simply buffer/retry once Kafka recovers. |
| Decision Cache (Redis) fails | Idempotency checks fall back to a best-effort in-memory-per-instance cache; a small risk of a rare duplicate score on retry is accepted as preferable to blocking every request on cache availability. |
How would you decide, as a design choice, whether a merchant tier fails open or fails closed? — A well-established, low-risk merchant with historically low chargeback rates can reasonably fail open (approve) during a fraud-system outage, since the expected fraud loss is low and customer friction is costly; a high-risk merchant category or unusually large transaction amount should fail closed (decline or challenge), since the expected loss from a missed fraud case is higher than the cost of a delayed legitimate sale. Tie this directly to the false-decline vs. false-approval cost trade-off from Section 7.
Security
- PCI-DSS compliance: Card data (PAN, CVV) is tokenized at the earliest possible point in the pipeline; the fraud system operates on tokens and hashed/derived identifiers wherever possible, never storing raw card numbers in feature stores or logs.
- Encryption everywhere: TLS for all network hops (merchant-to-acquirer, acquirer-to-network, network-to-issuer, and every internal service-to-service call via mTLS); encryption at rest for the feature store, Decision Cache, and Data Lake.
- Least-privilege access: The Decision Orchestrator and Model Serving Cluster only have read access to the specific feature namespaces they need; the Config/Rules Management Service enforces role-based access so only authorized fraud analysts can modify live rules, with every change immutably audit-logged.
- Rate limiting & abuse protection: The API Gateway enforces per-merchant/per-acquirer rate limits to prevent a compromised or misbehaving upstream integration from overwhelming the pipeline.
- Model security: Model artifacts are versioned, signed, and validated before deployment to the Model Serving Cluster, preventing tampering or accidental deployment of an unvalidated/experimental model to the live decision path.
- Adversarial robustness: Because fraudsters actively probe the system, feature and rule definitions are treated as sensitive — a compromise of the Config/Rules Management Service could let an attacker learn exactly which patterns evade detection, so it’s isolated and access-controlled as carefully as the decisioning path itself.
Logging full request/response payloads (including raw card data) for debugging convenience is a serious and common compliance violation. All logging in this system must pass through a redaction/tokenization layer before ever reaching a log aggregator, and this must be enforced at the logging library level, not left to individual engineers’ discipline.
Monitoring, Logging & Metrics
13.1 Key metrics to track
| Metric | Why It Matters |
|---|---|
| End-to-end decision latency (p50/p95/p99/p99.9) | The single most critical metric — directly measures compliance with the 100ms SLA; p99.9 matters as much as p99 here because even rare breaches have real financial/customer-experience cost. |
| Circuit breaker trip rate (feature store, model serving) | Indicates how often the system is operating in a degraded fallback mode, which correlates with temporarily reduced fraud-catch rate. |
| Fraud precision/recall (measured after chargeback data arrives, offline) | The ultimate business measure of model/rule quality, necessarily lagging since confirmed fraud (chargebacks) arrives weeks later. |
| Approve/Decline/Challenge rate by merchant tier | Sudden shifts can indicate a misconfigured rule, a model regression, or an actual fraud attack in progress. |
| Feature staleness (age of last successful streaming pipeline update per shard) | A stale feature pipeline silently degrades detection accuracy without any obvious error at the API level. |
| Kafka consumer lag on the transaction event stream | Leading indicator that the streaming feature pipeline is falling behind, which will eventually manifest as stale velocity features. |
13.2 Logging & tracing
- Structured, correlation-ID-tagged (transaction ID) logs across every hop, with all sensitive fields redacted/tokenized before they ever leave the service boundary.
- Distributed tracing (OpenTelemetry) spanning API Gateway → Orchestrator → parallel feature/rule/model calls → decision, broken down per stage, so a latency regression can be pinpointed to the exact stage responsible.
- Real-time dashboards showing the latency budget breakdown (as in Section 8’s table) live, per region, so an emerging latency regression in one specific stage is visible immediately rather than only as an aggregate SLA breach.
- Sampled, structured logging for high-cardinality debug details versus unsampled logging for anything tied to a decline or challenge decision, balancing storage cost against the forensic completeness needed for dispute resolution and regulatory inquiries.
13.3 Precision, recall, and the business cost function
Because confirmed fraud labels (chargebacks) arrive weeks after the original decision, this system’s most important quality metrics are necessarily lagging indicators, tracked over rolling multi-week windows rather than in real time: precision (of all declined/challenged transactions, what fraction were truly fraudulent) and recall (of all eventually-confirmed fraud, what fraction was caught at authorization time). These are combined into a single cost-weighted metric reflecting the business’s actual false-decline versus false-approval cost trade-off discussed in Section 7, and that combined metric — not raw model accuracy — is what ultimately governs whether a new model version or threshold change is considered an improvement.
Large-scale payment fraud teams commonly maintain a “shadow scoring” pipeline — running a candidate new model or rule set against live traffic in parallel with the production decision path, logging what it would have decided without actually affecting the real transaction — as a safe way to validate changes against real-world traffic patterns before a canary rollout to the live decision path.
Deployment & Cloud
- Containerization + orchestration: The Decision Orchestrator, Rule Engine Service, and Model Serving Cluster are containerized and run on Kubernetes (or similar) for self-healing and rolling deployments, with pod anti-affinity rules ensuring replicas spread across failure domains.
- Regional, multi-cluster deployment: Each geographic region runs its own full stack (Orchestrator fleet, feature store replica, model serving cluster) to minimize network latency and provide regional fault isolation.
- Canary deployment for models and rules: A new model version or rule change is first deployed in shadow mode (scoring live traffic without affecting decisions), then rolled out to a small percentage of real traffic, with automated comparison of key metrics (approve/decline rates, latency) against the incumbent before full rollout.
- Blue-green for the Decision Orchestrator: Given its statelessness and criticality, blue-green deployment allows instant rollback if a new version regresses latency or introduces a bug, without any partial-traffic ambiguity.
- Infrastructure as Code: Terraform (or similar) defines the regional Kubernetes clusters, feature store clusters, and networking, enabling reproducible, auditable environments — particularly important given the regulatory scrutiny financial infrastructure receives.
Databases, Caching & Load Balancing
- Online Feature Store: An in-memory, sharded key-value store (Redis Cluster or a purpose-built low-latency feature-serving system) holding only the recent, hot window of features (e.g., trailing 24-72 hours of velocity counters); older/aggregate features live in a separate offline store used only for training, never queried on the hot path.
- Decision Cache: A short-TTL (minutes, not hours) Redis store keyed by transaction/idempotency ID, purely for retry-safety, not a general-purpose data store.
- Offline/Training Feature Store: A larger, slower data warehouse or data lake storing full historical features and labeled outcomes (confirmed fraud/chargeback data), used exclusively for model training and offline analytics — never in the synchronous decision path.
- Load balancing strategy: L4 load balancing for raw connection distribution across API Gateway instances; L7 load balancing at the gateway for health-check-aware routing to Decision Orchestrator replicas; consistent hashing at the feature store client level to route each card/merchant’s lookups to the correct shard with minimal added latency.
Why not just query the issuer’s core banking/transaction database directly for a cardholder’s history? — Because core banking systems are optimized for transactional correctness and durability, not sub-millisecond read latency at this request volume; querying them directly on every authorization would both risk violating the 100ms budget and add unacceptable load to systems that must also guarantee the integrity of account balances and ledgers.
APIs & Microservices
16.1 Sample Decision Orchestrator API (internal)
POST /v1/authorize/score
Request:
{
"transactionId": "txn_9f2a1c",
"cardToken": "tok_4242_abcd",
"merchantId": "merch_88213",
"amount": 87.50,
"currency": "USD",
"cardPresent": true,
"deviceId": "dev_77a1",
"timestamp": "2026-08-03T14:32:07.113Z"
}
Response 200 (within 100ms):
{
"transactionId": "txn_9f2a1c",
"decision": "APPROVE",
"reasonCode": "model_low_risk",
"fraudProbability": 0.014,
"elapsedMs": 62
}
This is a classic microservices architecture built around clear domain boundaries: the Decision Orchestrator owns the synchronous request/response contract, the Model Serving Cluster and Rule Engine Service are called internally as fast, narrowly-scoped dependencies, and the streaming feature pipeline communicates exclusively through Kafka events rather than direct calls — allowing each to be deployed, scaled, and evolved independently.
16.2 Internal event contract (Transaction Event, simplified)
// TransactionScored event published asynchronously after every decision
message TransactionScored {
string transaction_id = 1;
string card_token = 2;
string merchant_id = 3;
double amount = 4;
string decision = 5;
double fraud_probability = 6;
int64 timestamp_ms = 7;
}
A schema registry enforces backward/forward compatibility on this event as it evolves, since the streaming feature pipeline, the audit/data-lake sink, and any future consumers all depend on a stable contract without needing to coordinate deployments with the Decision Orchestrator team.
Design Patterns & Anti-Patterns
17.1 Patterns used
CQRS
The synchronous, latency-critical scoring path is entirely separate from the read-heavy case-management/analyst dashboard path, each with its own API Gateway and Load Balancer.
Circuit Breaker
Around calls to the Model Serving Cluster and Online Feature Store, tripping to a safe fallback rather than risking a timeout that blows the latency budget.
Bulkhead Isolation
Regional stacks are isolated from one another; the hot decision path is isolated from the asynchronous audit/analytics path so neither can degrade the other.
Sidecar / Local Caching
Frequently accessed, slowly changing data (like merchant risk tiers) cached locally within the Orchestrator to shave off network round trips.
Shadow Deployment
New models/rules scored against live traffic without affecting real decisions, validating behavior before a canary rollout.
17.2 Anti-patterns to avoid
Sequential dependency calls
Chaining feature, device, rule, and model calls one after another inside the hot path — the single most common cause of blown latency budgets in systems like this.
Warehouse queries on the hot path
Querying a data warehouse or core banking system directly for real-time features instead of maintaining a dedicated low-latency feature store.
No circuit breakers around model serving
Treating the ML model as an always-available dependency rather than planning explicitly for its degradation.
One global threshold
Using one global fraud-probability threshold for all merchants/regions/amounts, ignoring that the cost of false positives and false negatives varies enormously by context.
Direct 100% model rollout
Deploying a new model directly to 100% of traffic without shadow scoring or canarying first — a subtle model regression at this scale can cause a sudden spike in false declines or false approvals before anyone notices.
Best Practices & Common Mistakes
18.1 Best practices
- Treat the 100ms budget as a hard architectural constraint from day one, not an optimization target applied after the system is built — it should shape which calls are parallel, which have timeouts, and which have fallbacks.
- Always pair an ML model with a fast, explainable rule layer capable of instant hard overrides for known-bad patterns.
- Version and shadow-test every model and rule change against live traffic before it ever affects a real decision.
- Design an explicit, documented fail-open/fail-closed policy per merchant risk tier, rather than leaving it as an implicit accident of how the code happens to handle timeouts.
- Keep the synchronous decision path’s dependencies to the absolute minimum required — every additional dependency is another way to miss the deadline.
18.2 Common mistakes
- Under-provisioning the Model Serving Cluster’s capacity margin, causing latency to creep up under peak load exactly when fraud attempts (and legitimate volume) both spike.
- Forgetting to test the system’s behavior under partial degradation (one dependency slow, not fully down) — full outages are often easier to handle correctly than “slightly too slow,” which is exactly what a strict latency budget is most vulnerable to.
- Not separating the synchronous decision path’s logging/audit trail from the analytical Data Lake pipeline, risking the audit write itself becoming a latency-critical dependency.
- Retraining models without validating against a held-out, recent time period — fraud patterns shift, and a model validated only on older data can look great in offline metrics while already being stale in production.
18.3 Testing strategy
Beyond ordinary unit and integration tests, this system needs: latency load testing that simulates realistic peak traffic (including bursty patterns like a flash sale) while measuring the full p99.9 latency distribution, not just the average; chaos/fault-injection testing that deliberately slows or fails individual dependencies (feature store, model serving) to verify circuit breakers and fallbacks actually engage correctly under real conditions; shadow-mode validation comparing a candidate model/rule change’s decisions against the incumbent on identical live traffic before any real transaction is affected; and replay testing against a labeled historical dataset (including known confirmed fraud cases) to verify a new model version doesn’t regress on previously-caught fraud patterns.
Real-World Examples
Visa Advanced Authorization
A real-time scoring service that evaluates transactions as they flow through the network, returning a risk score to issuers within the authorization window, reflecting the same rules-plus-model, strict-latency-budget pattern described in this tutorial.
Mastercard Decision Intelligence
Uses real-time AI-based scoring integrated directly into the authorization flow, similarly bound by the shared network-level timeout across the entire transaction chain.
Stripe Radar
A widely used real-time fraud detection layer for online (card-not-present) transactions, combining machine learning with configurable rules, and explicitly designed to return a decision within the payment authorization’s tight latency window.
PayPal fraud infrastructure
Has publicly discussed combining real-time feature computation with machine learning models served at low latency to score transactions during checkout, reflecting the same streaming-feature-pipeline-plus-fast-model-serving pattern.
A consistent pattern across all of these real-world systems is the layered decision approach: instant, deterministic rules for known-bad patterns, combined with a probabilistic ML score for everything else, all wrapped in aggressive timeouts and safe fallbacks — precisely because a fraud-scoring system that occasionally times out is, from the payment network’s perspective, indistinguishable from one that’s completely down.
Frequently Asked Questions
Why not just always approve if the fraud system is running slow, to protect the customer experience?
Because the right answer depends on the merchant’s risk tier and the transaction’s exposure — a blanket “always approve when slow” policy would be exploited by fraudsters who could intentionally induce slowdowns (or simply wait for organic ones) to bypass scrutiny. The fail-open/fail-closed policy must be deliberately tiered, not a single global default.
How do you keep the ML model accurate as fraud patterns evolve?
Through continuous retraining on recent labeled data (confirmed fraud from chargebacks, confirmed legitimate transactions), validated via shadow-mode testing against live traffic before any production rollout, with drift-monitoring metrics tracked over time to detect when the live score distribution starts diverging from what the model was trained on.
What’s the difference between this system and a case-management/dispute system?
This system makes the instant, automated authorization-time decision; a separate case-management system handles what happens after a chargeback is filed weeks later, including human investigator review — the two share data (this system’s decisions and features feed the offline store used for later investigation) but operate on entirely different timescales and are architecturally distinct.
Can the 100ms target vary by region or network?
Yes — the true end-to-end timeout is set by the payment network and varies somewhat by market and integration, but 100ms (or tighter) for the fraud-decisioning hop specifically is a widely used internal target because network round-trip time already consumes a significant, largely fixed portion of the overall budget, especially for cross-border transactions.
Why use gradient-boosted trees instead of a deep neural network?
Gradient-boosted trees typically offer an excellent balance of accuracy and inference speed on structured, tabular transaction features, and are simpler to serve at very low latency reliably at scale. Deep learning approaches (including sequence models over a cardholder’s transaction history) can improve accuracy further and are used by some large processors, but require more careful latency engineering (model optimization, sometimes specialized hardware) to stay within budget, so many systems adopt them as a secondary/ensemble signal rather than the sole real-time model.
How does this system avoid being gamed by fraudsters who study its rules?
By never relying on rules alone and by keeping the most sensitive rule definitions and thresholds access-controlled and audit-logged, since rules are more easily reverse-engineered through trial and error than a statistical model’s learned decision boundary. The ML layer’s constantly retrained, less transparent decision surface makes pure trial-and-error probing far less effective, and velocity-based features specifically punish exactly the kind of rapid, repeated probing an attacker would need to do to map out the rule set.
What role does the merchant play in all of this?
The merchant is upstream of this system — it only sees requests as they arrive from the acquirer/network and cannot directly query the merchant’s own systems inside the 100ms window. Merchant-level signals (like historical chargeback rates, business category, and average transaction size) are instead precomputed and included as features in the Online Feature Store, refreshed on a much slower cadence (hours to a day) than the millisecond-fresh, per-card velocity features.
Summary & Key Takeaways
- Real-time fraud detection under a strict 100ms budget requires treating latency as a first-class architectural constraint, not an afterthought — every dependency needs a timeout and a fallback.
- Parallelizing feature lookups, device/identity checks, and rule evaluation (rather than calling them sequentially) is the single highest-leverage architectural decision for meeting the latency budget.
- A hybrid approach — deterministic, instantly explainable rules for known-bad patterns, combined with a probabilistic ML model for everything else — outperforms either approach alone, both on accuracy and on regulatory explainability.
- An event-driven architecture — API Gateway → Load Balancer → Decision Orchestrator → parallel feature/rule/model calls → decision — keeps the synchronous hot path minimal, while a separate streaming feature pipeline and asynchronous audit/analytics path handle everything that doesn’t need to block the response.
- Scaling to millions of transactions per minute globally is achieved through regional sharding (minimizing network latency), horizontal scaling of every stateless component, and an explicit, deliberate trade-off favoring availability and low latency over perfectly fresh global consistency.
- Reliability here means more than “don’t crash” — it means having an explicit, tiered fail-open/fail-closed policy, circuit breakers around every hot-path dependency, and continuous validation (shadow deployment, chaos testing) that the fallbacks actually work before a real incident tests them for the first time.