Professional · Bank of AmericaBackend · ML · StreamingAug 2024 – Present

Real-Time Fraud Detection & Risk Scoring Platform

A high-throughput, event-driven fraud detection system at Bank of America — processing 1–2M daily transactions across card payments, Zelle, ACH, and online banking with end-to-end scoring latency under 2 seconds.

1–2M
Daily transactions processed
Across card payments, Zelle, ACH, online banking — with headroom for peak days
<2s
End-to-end processing latency
Down from 3–5 seconds — measured via end-to-end timestamp tracking
<200ms
Fraud scoring API response
FastAPI inference service response time under full production load
15%
Earlier fraud detection
Rule-based velocity + geo anomaly logic catching patterns ML alone missed
12–15%
Detection accuracy lift
XGBoost over prior rule-only system — measured on precision, recall, ROC-AUC
20%
Query time reduction
MySQL from ~200–250ms to ~150–180ms via indexing and partition strategy
30%
Deployment cycle cut
From 45–60 min manual process to 30–40 min automated Jenkins pipeline

01 — Problem

Batch detection wasn't fast enough to stop fraud

Bank of America processes millions of transactions daily across debit and credit cards, Zelle transfers, ACH payments, wire transfers, and online banking. Fraud can happen in milliseconds across any of these channels. The existing batch-based system analysed transactions hours after they occurred — by then, funds had already moved and the intervention window had closed.

Beyond speed, the system had to meet AML and KYC compliance requirements, reduce false positives that frustrated legitimate customers, and defend against sophisticated fraud patterns — card cloning, account takeover, identity theft, and card testing — that static rules alone couldn't catch.

Core problems
  • Processing lag of 3–5 seconds — needed to get below 2 seconds end-to-end
  • Batch detection cycle meant fraud was flagged hours after the event
  • Static rule engine caused false positives — legitimate customers incorrectly flagged
  • No ML layer — couldn't detect novel fraud patterns that rules missed
  • No real-time signal correlation across geo, device, and velocity data
  • Manual deployment process took 45–60 minutes — slowed model iteration
  • No observability — zero visibility into pipeline health, lag, or scoring drift

02 — Decisions

Architecture choices and why

Every technology decision was made against two hard constraints: end-to-end latency under 2 seconds and financial-grade reliability. The system follows an event-driven microservices architecture.

Transaction eventKafka topicSpark Structured StreamingFeature engineeringXGBoost + Rule engineFastAPI scoring APIDashboard + Audit log
Apache Kafka

Ingests transaction events from multiple banking channels — card swipes, Zelle transfers, ACH payments, and online banking — into partitioned topics. Configured producers and consumers for high-throughput streaming without data loss. Partition strategy distributes load evenly across brokers, keeping the system stable during peak events like holiday seasons where volume approaches 2M transactions per day.

Spark Structured Streaming

Consumes Kafka streams and runs real-time transformations — filtering invalid transactions, normalising currency formats, and enriching data with customer metadata from reference systems. Built checkpointing and fault-tolerance so no transaction is lost on node failure. If a Spark job restarts due to node failure, it resumes from the last checkpoint without duplicating transaction processing.

XGBoost + Scikit-learn

Selected over deep learning because it handles imbalanced fraud datasets better and consistently hits under 200ms inference — matching the latency SLA. Tuned using grid search and cross-validation. Primary evaluation metrics were precision, recall, F1, and ROC-AUC — minimising false negatives is more important than overall accuracy in fraud detection.

FastAPI

Exposes fraud scoring APIs that accept transaction payloads and return real-time risk scores under 200ms. Request validation layer rejects malformed or incomplete data early, reducing downstream processing failures. User profile caching reduces database calls and improves API performance under high concurrent load.

Flask (auxiliary services)

Rule evaluation, logging, and transaction validation services built in Flask — keeping the rules engine and ML scoring service independently deployable and evolvable. This separation meant the rule logic could be updated without touching the ML inference layer.

MySQL (optimised)

Indexed on transaction_id, user_id, and timestamp. Partitioned large transaction tables. Removed full table scans identified via MySQL EXPLAIN plans. Query time dropped from ~200–250ms to ~150–180ms — a 20% improvement that compounds significantly at 1–2M daily transactions.

Kubernetes + Jenkins

Before automation: manual build + test + deploy took 45–60 minutes. After: Jenkins pipeline with Docker and Kubernetes brings it to 30–40 minutes via parallel build execution, container reuse, and faster rollback. SonarQube and Nexus integrated for code quality gating and artifact management.

Rule engine — layered on top of ML, not replacing it

Both layers run in parallel and their outputs are combined using weighted scoring logic to generate a final fraud probability. Rules catch known patterns instantly; XGBoost catches novel patterns rules miss. Adaptive thresholds change fraud sensitivity based on transaction type and customer risk profile — reducing false positives on legitimate unusual transactions.

Velocity checks
Transaction count per minute, hour, and day — detects rapid-fire card testing fraud scenarios
Geo-location anomaly
Distance between successive transactions using lat-long — flags impossible travel patterns across countries
Device fingerprinting
Device ID, IP, browser metadata, login patterns — catches single account accessed from multiple devices
Behavioural profiling
Adaptive thresholds per customer risk profile — reduces false positives on legitimate unusual transactions

03 — Real scenario

How a fraud event flows through the system

A customer normally transacts locally in New Jersey. Then a $6,000 transaction is initiated from a new device in another country.

01Kafka captures the event instantly
02Spark detects geo-location anomaly — impossible travel from NJ
03Rule engine flags device mismatch — new device ID never seen before
04XGBoost assigns high fraud probability based on combined feature signals
05Combined score exceeds threshold — transaction blocked
06Fraud analyst dashboard shows alert in real time via React + Redux
07Customer receives security notification — financial loss prevented before settlement
Total time from transaction to block: under 2 seconds

04 — Timeline

How it was built

Discovery2 weeks

Audited existing batch pipeline. Mapped transaction volume patterns across channels — card, ACH, Zelle, online. Identified 3–5 second processing lag as primary risk. Defined latency SLA: fraud scoring must complete within 2 seconds end-to-end.

Architecture2 weeks

Designed Kafka topic structure and partition strategy. Defined Spark Streaming topology and microservice boundaries. Evaluated ML candidates — selected XGBoost over deep learning based on latency benchmarks and performance on imbalanced fraud datasets.

Core pipeline6 weeks

Built Kafka producers and consumers. Implemented Spark Structured Streaming jobs with checkpointing and fault-tolerance. Built feature engineering layer — 28+ features including velocity, geo, device fingerprinting, and behavioural signals. Integrated XGBoost inference with FastAPI scoring service.

Rule engine3 weeks

Implemented velocity checks (per minute/hour/day), geo-location anomaly detection via lat-long distance calculation, device fingerprinting, and adaptive behavioural profiling. Tested against real fraud scenarios: card cloning, account takeover, identity theft, card testing.

Hardening3 weeks

JWT auth + RBAC across all microservices for AML/KYC compliance. MySQL schema redesign and index optimisation. Load tested to 2M daily transactions. SonarQube + Nexus quality gates enforced on every PR. Prometheus + Grafana dashboards for pipeline observability.

ProductionOngoing

Deployed on Kubernetes (AKS). React.js fraud analyst dashboard with Redux state management for real-time alert visualisation. Centralised logging and exception handling across services. Continuous model retraining on new fraud signal data.


05 — Outcome

What shipped

The platform moved Bank of America from batch fraud detection with multi-second lag to a fully real-time event-driven system — blocking fraud before settlement, at scale, with full observability.

  • Processing latency cut from 3–5 seconds to under 2 seconds end-to-end via Kafka + Spark optimisation
  • FastAPI fraud scoring API responds under 200ms — well within the low-latency SLA
  • ML + rule hybrid layer caught 15% more fraud earlier than the previous rule-only system
  • XGBoost improved detection accuracy 12–15% — measured on precision, recall, F1, and ROC-AUC
  • Behavioural baseline profiling reduced false positives — fewer legitimate customers incorrectly flagged
  • MySQL query time dropped from ~200–250ms to ~150–180ms via indexing on transaction_id, user_id, timestamp
  • Deployment cycle cut 30% — 45–60 min manual process → 30–40 min automated Jenkins pipeline
  • JWT + RBAC enforcement across all microservices met AML/KYC compliance and audit requirements
  • Prometheus + Grafana dashboards gave the team real-time visibility into pipeline health and streaming lag
  • React.js fraud analyst dashboard with real-time alert updates replaced manual reporting
Want to talk through the architecture?
Open to backend, fullstack, and ML roles. Based in CA.
Get in touch →