My AI bill went up, so I went looking. The rate limit had been counting a number visitors write themselves — so it had never limited anything.
Verilay is free. No account, no card, paste in your app and get an answer.
What isn't free is running it. Every analysis makes several calls to Claude, and each one costs me somewhere between two and three cents. That's fine when a handful of people use it. It's a different conversation when a few hundred do.
Last week my bill went up enough that I went looking for why. What I found wasn't a surge of users. It was a limit that had never worked.
Verilay has always had a rate limit: ten analyses per hour, per person. More than generous — most people run one, fix something, run it again. Ten is plenty, and it means nobody can sit there in a loop spending my money.
The code was simple enough. For each visitor, keep a list of when they last ran something, throw away anything older than an hour, and refuse the eleventh.
The bit I got wrong was the words each visitor.
When your browser asks a website for a page, it sends along some extra information: what browser you're using, what language you prefer, and — if the request passed through anything in the middle — where it came from.
That last one lives in something called X-Forwarded-For. It's a list of
addresses, added to by each stop along the way, so the final website can work out who
originally asked.
Verilay was reading the first name on that list.
Here's the problem. The first name on that list is whatever your browser put there. Not what the network worked out. What the visitor themselves supplied.
It's a clipboard at the door where people write their own name, and I was counting the names on the clipboard.
Anyone who wanted unlimited free analyses only had to write a different name each time. Not a clever exploit. Not a tool you'd have to download. Change one line in the request and the limit disappears, because every request looks like a brand new person who has never visited before.
The limit had been there since the beginning. It just wasn't limiting anything.
While I was in there I found a second, smaller version of the same problem.
To handle several people at once, Verilay doesn't run as one program. It runs as four identical copies, and whichever one is free takes your request.
Each copy keeps its own list of who's been doing what. And they don't talk to each other.
So even for an honest visitor who wasn't faking anything, "ten per hour" was really up to forty — ten at each of four doors, none of the doormen aware the others exist.
For the first problem, the fix was small. Verilay sits behind Cloudflare, and Cloudflare adds its own record of where a request genuinely came from — one the visitor can't write on, because Cloudflare overwrites anything they put there. Read that instead of the clipboard and the limit starts working.
There was a small indignity here. Verilay had two functions doing this same job, in two different parts of the code. One of them already did it correctly. The two had been written at different times and drifted apart, and I'd been looking at the wrong one for months. There's now only one, and the other calls it.
The four-doors problem is a bigger fix — the copies need somewhere shared to keep the count — and I haven't done it yet. It's on the list. But it's a four-times-too-loose problem, not an infinitely-loose one, which is a much better place to be.
Some real numbers, because I don't think people building free tools talk about this enough.
| Scenario | Cost to me |
|---|---|
| One analysis | 2–3 cents |
| A good day — 100 people | $2–3 |
| A launch — 1,000 analyses | $20–30 |
| One person in a loop, unlimited | However long they feel like |
The first three are fine. I'd happily pay $30 for a thousand people trying something I built. The fourth is the one that keeps you up, and it's the one the broken limit had left wide open.
Worth saying plainly: a free tool with an AI behind it is a different animal from a normal free website. A normal website costs about the same whether ten people visit or ten thousand. Mine costs money per use, forever. That changes what "free" can mean, and it's why I'll eventually charge for something.
Three things worth checking today, none of which take long.
Do you actually have a limit? Not "did you mean to add one" — go and try to break it. Run your thing eleven times in a row. If the eleventh works, you don't have a limit, whatever the code says. I'd never done this, which is exactly why I didn't know.
Are you trusting something the visitor sent you? Anything arriving from someone's browser is a suggestion, not a fact. Names, addresses, counts, prices, who they claim to be. If a decision that costs you money depends on it, that decision can be bought for nothing.
Do you have a ceiling? I've since turned on automatic top-ups for my AI credits so the tool doesn't stop mid-sentence when they run out. That solved one problem and created another: "stops working" became "bills my card." So there's now a monthly cap alongside it. Automatic top-ups without a cap is a trapdoor, and I nearly left it open.
I build a tool that checks other people's apps for exactly this class of mistake.
I'd like to say I found this because I'm thorough. I found it because I looked at a bill, got a small fright, and went digging. The check I'd have needed didn't exist — not in Verilay, not anywhere I'd thought to look.
That's most of what I've learned building this thing. The problems aren't usually hiding in the clever parts. They're in the parts you wrote early, believed you'd finished, and never went back to.