I Built a Serverless Fraud Detection Pipeline on AWS. Here's What It Actually Costs to Do It Right.
Source: Dev.to
Most cloud portfolio projects look like this
Spin up an EC2 instance, deploy a web app, take a screenshot. Done.
That tells a hiring manager you can follow a tutorial.
This is not that.
I built a real‑time transaction‑screening pipeline modeled after how financial institutions actually handle suspicious‑activity routing.
The entire processing backbone costs $2.48 /month to run at 500 000 transactions.
Below is how it works, why every decision was made, and what it actually costs to secure it properly.
The Problem This Solves
Payment processors and banks screen every transaction before it clears. A transaction above a defined threshold, or matching a suspicious pattern, needs to be flagged, stored, and routed to an analyst in near real‑time. Latency here is not a UX problem – it is a compliance and fraud‑exposure problem.
The architecture must handle three things without failing:
- Ingest transactions reliably, even under burst load.
- Evaluate and persist every transaction, regardless of outcome.
- Alert immediately when a transaction crosses the threshold, with zero alert loss.
A traditional EC2‑based approach handles this with always‑on servers. You pay for compute whether transactions are flowing or not, and you must manage patching, availability zones, and process monitoring yourself.
The serverless approach inverts this entirely.
Architecture
- Ingress – Every transaction enters through Amazon SQS.
- Processing – An AWS Lambda function processes each message, writes the full record to Amazon DynamoDB (regardless of whether it is flagged), and fires an Amazon SNS alert only if the amount exceeds the threshold.
- Failure handling – If Lambda fails to process a message three times, SQS routes it to a Dead‑Letter Queue for manual investigation. Nothing is silently dropped.
All components run inside a VPC across two Availability Zones. Connections to SQS, DynamoDB, SNS, and CloudWatch use VPC interface and gateway endpoints, so no traffic touches the public internet at any point in the pipeline.
Lambda Function
import json
import boto3
import os
from decimal import Decimal
dyn = boto3.resource('dynamodb')
sns = boto3.client('sns')
TABLE = os.getenv("TABLE", "fraud-detections")
SNS_ARN = os.getenv(
"SNS_ARN",
"arn:aws:sns:us-east-1:461840362463:fraud-alerts"
)
# Threshold represents configurable screening rule for the institution
THRESHOLD = 500_000 # NGN
def lambda_handler(event, context):
for record in event["Records"]:
body = json.loads(record["body"])
txn_id = body["transaction_id"]
amount = Decimal(str(body["amount"]))
merchant = body["merchant"]
flagged = amount > THRESHOLD
# Persist the transaction first – audit trail is mandatory
dyn.Table(TABLE).put_item(
Item={
"transaction_id": txn_id,
"amount": amount,
"merchant": merchant,
"flagged": flagged,
}
)
# Send alert only when the transaction is flagged
if flagged:
sns.publish(
TopicArn=SNS_ARN,
Message=(
f"Suspicious transfer Flagged: {txn_id} — "
f"NGN {amount} — {merchant}"
),
Subject="Fraud Alert",
)
return {"statusCode": 200}Key points
- Audit first – Every transaction is written to DynamoDB before the flag check. Regulators require a complete, gap‑free record.
- Configurable threshold – In production the threshold would be pulled from a configuration store (e.g., AWS Systems Manager Parameter Store) so compliance teams can adjust rules without a code deployment.
- Decimal over float – Financial amounts must use
Decimalto avoid silent precision errors; DynamoDB does not accept Python floats.
Verified Results
Two transactions were sent through the pipeline.
| Transaction | Amount (NGN) | Flagged | Alert Sent |
|---|---|---|---|
| TXN‑001 | 600,000 | ✅ | ✅ (SNS → Email) |
| TXN‑002 | 120,000 | ❌ | ❌ |
The DynamoDB table shows both records.

The SNS alert triggered an email.

Both records are present in DynamoDB, providing a complete audit trail.
What It Actually Costs
| Service | Monthly Cost |
|---|---|
| AWS Lambda (500 k requests) | $1.14 |
| Amazon SQS (1.5 M requests) | $0.60 |
| Amazon DynamoDB (1 GB) | $0.56 |
| Amazon SNS (10 k alerts) | $0.18 |
| Pipeline Total | $2.48 |
| VPC Interface Endpoints (3×) | $43.81 |
| Secured Total | $46.29 / month |
- The pipeline itself costs $2.48 /month to process 500 000 transactions.
- The VPC endpoints, required for a secure, audit‑compliant deployment, add $43.81 /month – 94.6 % of the total bill.
This is an intentional trade‑off. Without VPC endpoints, Lambda would communicate with SQS, DynamoDB, SNS, and CloudWatch over the public internet, which is unacceptable in a financial context. VPC endpoints keep all traffic private and satisfy audit requirements.
## Why Keep This Private?
Running the pipeline **private within the AWS network** satisfies network‑isolation requirements common in PCI‑DSS and SOC 2 environments and eliminates the data‑exfiltration risk that comes with public‑endpoint exposure.
> **Cost note:**
> If this were a cost‑only conversation, you would skip the endpoints and save **$43.81 /month**. In a production fintech environment, that decision gets flagged in the first security review.
---
## What This Is **Not**
This pipeline has a single threshold rule. Production fraud detection at scale uses:
- ML‑based anomaly scoring
- Velocity checks across merchant categories
- Device fingerprinting
- Graph‑based relationship analysis
These are layered on top of an event‑driven backbone exactly like this one.
> **This is the infrastructure layer.** It must work before any model or rule engine is plugged in. Getting this layer wrong means no amount of ML sophistication above it can recover cleanly.
---
## Why Serverless for This?
**Three concrete reasons:**
1. **Burst handling without pre‑provisioning**
Payment transaction volume is not linear—end‑of‑month salary runs, Black Friday, public‑holiday spikes. Lambda scales to concurrency automatically. An EC2‑based system requires capacity planning or auto‑scaling lag measured in minutes.
2. **No idle cost**
An EC2 `t3.micro` running 24/7 costs ≈ $7.59 /month (before storage, monitoring, or patching overhead). Lambda handling 500 k transactions costs $1.14 /month. At zero transactions it costs nothing.
3. **Operational surface reduced to code**
No OS to patch, no SSH access to harden, no process monitor to configure. The attack surface is the IAM role and the function code—both auditable and version‑controlled.
---
## What Carries Into Production
The patterns here are **not demo‑specific**:
- **SQS** as a durable ingest buffer decouples transaction producers from the processing layer. A downstream Lambda failure does **not** lose the transaction.
- **DLQ** after three failures prevents silent message loss; every failed transaction is recoverable.
- **VPC‑private connectivity** satisfies network‑isolation requirements out of the box.
- **IAM roles** scoped to least privilege ensure Lambda cannot touch anything outside its defined resource set.
These are the same architectural decisions you find in production payment infrastructure. The scale is different; the patterns are not.
---
*Victor Ojeje is a Cloud and Infrastructure Engineer based in Lagos. He builds production‑grade AWS infrastructure with a focus on security, automation, and cost‑conscious design.*
**LinkedIn:** [linkedin.com/in/victorojeje](https://linkedin.com/in/victorojeje)
**GitHub:** [github.com/escanut](https://github.com/escanut)