How charges become a subscription
This is the only genuinely interesting algorithm in the series, and it is still not very interesting — which is the point. Finding subscriptions in a transaction feed is a clustering problem that people reach for machine learning to solve and that is better solved by noticing that subscriptions are, by definition, charges that happen at regular intervals.
Key takeaways
- Grouping is on interval regularity, not merchant name similarity.
- Four patterns: monthly, annual, quarterly, and per-seat monthly with a drifting amount.
- Annual subscriptions need two years of feed to see, and they are the expensive ones.
- A pattern that breaks is a finding: a price rise, a cancellation, or a failed payment.
- Two charges is a coincidence. Three at a regular interval is a subscription.
Group on interval, not on name
The instinct is to group by merchant: put all the charges from the same place together and see which repeat. It works badly, because merchant strings for the same service vary between charges — a processor prefix appears and disappears, a city is appended, a reference number is included. Meanwhile genuinely different things share a merchant, because one payment processor fronts hundreds of small services.
- App integration
- Security & identity
- Management
- Analytics
The four patterns
| Pattern | Looks like | Why it needs its own handling |
|---|---|---|
| Monthly | Same amount, gaps of 28–31 days | The easy case. Three charges is enough to be confident. |
| Annual | Same amount, gaps of 360–370 days | Needs two years of feed to see three charges. Usually the largest amounts. |
| Quarterly | Same amount, gaps of 88–95 days | Easily mistaken for irregular spending on a short feed. |
| Per-seat monthly | Monthly gaps, amount rising in steps | Amount changes as headcount changes, so exact-amount grouping misses it entirely. |
Why annual is the hard and valuable case
Annual subscriptions are where the money is — they are typically five to ten times the value of a monthly one and are exactly the ones nobody remembers. They are also the hardest to detect, because seeing three charges takes two years of transaction history, and most businesses can only export twelve or eighteen months.
So annual gets a relaxed rule: two charges roughly a year apart, from the same merchant, for the same amount, is treated as a probable annual subscription rather than waiting for a third. It is flagged as probable in the question, which is honest and costs nothing — “this looks like an annual subscription, renewing about the 14th of next month” is a perfectly actionable sentence even when the system is only reasonably sure.
When a pattern breaks
A subscription that stops behaving is at least as interesting as one that starts, and there are three cases worth telling apart.
- A price rise is the most common and the most quietly expensive. Software prices rise annually and nobody notices a monthly charge moving from £14.40 to £17.20. Stated as “up 19%, £33.60 a year more”, it is a decision.
- A missing charge is genuinely ambiguous. Somebody cancelled it, or the card expired and the payment failed. Those need completely different responses, and the feed cannot tell them apart, so it asks: “no charge from PROJTOOL this month — did we cancel, or has the payment failed?”
- An interval change almost always means somebody switched from annual to monthly billing, which usually costs about twenty per cent more per year. Worth a sentence.
- A new merchant string for the same amount and interval is a rename, and recognising it as the same subscription rather than a new one preserves the history and the owner.
Next: how a subscription gets an owner and a purpose, which is where the money actually gets saved.
All posts