A velocity rule counts how often something happens inside a window and acts when the count crosses a threshold: five card attempts in a minute, or three new payees added in an hour. Done right, it is a cheap, explainable gate that stops obvious abuse before your model runs. Done wrong, it blocks your best customers at quarter-end.
The reason velocity survives forty years of fraud tooling is that it works on signal you already have and it explains itself. When a rule fires you can point to the exact events that tripped it, which matters when a customer complains and when a regulator asks. The reason it goes wrong is that most teams treat the threshold as a setting rather than a decision with a cost attached. Someone picks five because five feels right, ships it, and never measures what five actually did to the people who were not committing fraud.
Get the counter right before you touch the threshold
Most velocity failures are not tuning failures. They are counting failures, and they are invisible until someone reconciles the numbers.
The counter has to be point-in-time correct. When you score a transaction, the count you use must reflect only events that had settled by that instant, not events that arrived later. If your training data joins against a counter computed from the full history, the model learns from information the production system will not have at decision time. That is leakage, and it inflates your offline metrics while your live block rate drifts somewhere else entirely. The fix is to compute velocity features from an immutable event log with an event-time index, and to recompute the count as of the decision timestamp for every training row.
Then there is the key. A velocity rule is only as good as the entity it counts against. Counting attempts per card number is trivial to evade: the fraudster rotates cards and stays under every threshold. You want to count against a resolved entity that survives the rotation. That means entity resolution across device, card, email, and payee before the counter increments, so ten attempts from one actor across ten cards register as ten, not as one each.
A few things we check before trusting any velocity counter in production:
- Counts are keyed on a resolved entity, not a raw identifier a fraudster controls.
- The streaming count reconciles against a daily batch recomputation, and the gap is alerted on.
- Late-arriving and out-of-order events are handled explicitly, with a defined watermark, not dropped silently.
- Every counter has lineage back to the source events, so a fired rule can be reconstructed for the audit trail.
Skip this and you will spend your threshold-tuning effort compensating for a counter that is quietly wrong.
Tune against a false-positive budget, not a gut feeling
A threshold is a trade. Lower it and you catch more fraud and block more legitimate customers. Raise it and you do the reverse. The number that makes this a decision rather than a guess is the false-positive budget: how many good customers you are willing to block, per segment, per day.
Set the budget per segment because the cost of a false positive is not uniform. Blocking a new account mid-signup costs you an acquisition. Blocking a payroll run for an established business customer costs you the relationship. A single global threshold treats those as equal, which is why global thresholds are usually wrong for someone.
The method we use is unglamorous and it works:
- Build an eval set of labelled outcomes, held out by time so you are testing on a period the threshold never saw.
- For each candidate threshold, measure fraud caught and legitimate customers blocked, split by segment.
- Read the block rate against the segment’s budget. If a threshold overspends the budget without a matching rise in fraud caught, it is not a candidate.
- Pick the point on that curve the business will actually stand behind, and write down why.
The last step matters more than it sounds. Thresholds decay. Customer behaviour shifts, a marketing push changes your traffic mix, a new product moves the distribution. A threshold that was correct in March is silently overspending its budget by June. Monitor the realised false-positive rate as a drift signal and revisit when it breaches, rather than waiting for the complaints queue to tell you.
Rules and models are one system
The tired framing is rules versus machine learning. In a working stack they are layers of the same pipeline, and each does the job the other is bad at.
Velocity rules are the cheap hard gate. They run first, on features that cost almost nothing to compute, and they handle the abuse patterns that are unambiguous: a credential-stuffing burst, or a payee added and drained in ninety seconds. Blocking these outright keeps them out of the model’s scoring budget and keeps your latency down for the transactions that deserve real analysis.
The model handles ambiguity. It weighs the same velocity counts as features, alongside everything else, and produces a score for the cases a hard rule cannot resolve without collateral damage. A customer who makes four transfers in an hour might be a fraudster or might be paying contractors. A rule says block at three; a model says look at the payees, the amounts, the device history, and decide.
Between them sits the case-management layer, and it needs the same rigour as the automation. Straight-through processing should clear the clean transactions without a human touching them. Everything a rule or model flags but does not hard-block goes to review with the counter values, the triggering events, and the score attached, so an analyst can act in seconds and so the disposition feeds back as a label. That feedback loop is what keeps both layers honest: rules you never review turn into permanent tax on good customers, and models you never relabel drift.
Treat the two as one system with a shared false-positive budget and a shared eval set, and velocity earns its place as the oldest control that still pulls its weight. Treat the threshold as a set-and-forget config value, and it becomes the reason your fraud team spends quarter-end apologising.
FAQ
Should velocity rules run before or after the fraud model?
Run cheap velocity checks first as a fast gate, then let the model score what passes. Hard velocity blocks handle the obvious abuse patterns so the model spends its budget on the ambiguous cases.
What is a false-positive budget for velocity rules?
It is an explicit ceiling on how many legitimate customers a rule is allowed to block per day or per thousand transactions. You set it per segment, measure against it, and retire rules that overspend without catching enough fraud.
How do you keep velocity counters correct in production?
Build counters as point-in-time aggregations over an immutable event log, keyed by resolved entity rather than raw identifier, and reconcile the streaming count against a batch recomputation daily.