Portreeve
checklist · 5 Sept 20268 min read

Before you launch a free tier: the abuse checklist

Free tier abuse checklist for launch: meter expensive endpoints, capture identity keys, review before you block, fail open, and plan for the first attack.

You are about to ship a free tier or a no-card trial. Somewhere a script is already pointed at signup forms that look like yours. This free tier abuse checklist is the eight things to have in place before launch, ordered by how much each one buys you, with the why and the how for each and a link to the longer post where one exists.

Do the first three before you ship. The rest can follow in the first week, but the last one needs to be written down before the first attack, not during it.

1. Meter the expensive thing, not the signup

Why. The farmer's cost per account is cents. 2Captcha sells reCAPTCHA v2 solves at $1.00 to $2.99 per thousand and Turnstile at $1.45 per thousand, and Okta's threat intelligence team logged more than 105,000 automated signup attempts in one month against a single AI video service with a free trial. Every hurdle at the door is a line item they have already priced. What they want is behind the door: inference, sends, exports, storage.

How. Give a brand-new account a small allowance and grow it with age and behavior. Put the hard limit on the endpoint that costs you money, keyed by account and by linked cluster rather than by IP. The mechanics of that allowance are in free tier abuse: how credit farming works.

The standard advice here is "require a card." For most readers of this post that is wrong. A card gate turns your trial into a card-validation endpoint, because a SetupIntent checks a card with the issuer without charging it, and Stripe's own guidance calls card setup the method preferred by fraudulent actors because those authorizations do not typically show up on a statement. You trade credit farmers for card testers and lose the signups that would have converted. The details are in card testing on Stripe.

2. Capture identity keys at the door

Why. Every later step depends on being able to say "this is the same person as that account." You get one clean chance to collect the keys that make that possible, and it is the moment of signup.

How. Hash and store the email, load a device fingerprint on the signup page and store the resulting token, and ask for a phone number only where the product already justifies it. Store the card fingerprint from your processor at checkout, never the card. Treat IP as a soft signal that is never an identity key on its own: offices, universities, and carrier-grade NAT put thousands of real people behind one address, and residential proxies put one attacker behind thousands. What a fingerprint can and cannot tell you is in device fingerprinting for abuse prevention, and the integration is in the device fingerprinting docs.

3. Count on the right keys, review first

Why. A per-IP counter is wrong in both directions. It blocks the fourth signup from a coworking space and waves through a rotating residential proxy pool. Stripe makes the same point about card testing: filters based on a single heuristic such as IP address are usually not sufficient on their own.

How. Count signups per device, per email domain, and per linked cluster over one hour and one day. Set the first threshold to route to review rather than block, and set the block threshold at a level no human reaches: ten signups from one device fingerprint in an hour is not a family sharing a laptop. How to pick the windows and keys is in velocity checks.

4. Score email, do not gate on it

Why. A disposable-domain blocklist is bypassed with a fresh domain, a plus-address, or a Gmail dot variant, and it turns away privacy-minded people who would have paid. Geocodio scores each signup on dozens of factors, email domain among them, and now hears from about one wrongly flagged signup a month, a large drop from their earlier system that simply blocked repeat signups from one IP.

How. Score the domain (disposable list, domain age, MX present) and add it to the same score as device and velocity. Use the verification email as your medium-risk friction: it costs a real user thirty seconds and costs a farmer a working inbox per account. The list-maintenance problem and why it never ends is in disposable email domains.

5. Instrument before you block

Why. On launch day you have no baseline. A rule tuned against your imagination will block your first real customers and miss the actual attack, which will not look like the one you pictured. The scale can be startling: on Hacker News, caydenm reported customers where free tier abusers created 80k+ accounts in a day.

How. Log every signup with its identity keys and the score you would have assigned, run every rule in shadow mode for the first week, and read the flagged list each morning. Before you turn any rule to block, pull the accounts it would have blocked and check whether any of them paid. The same comment notes that some serious abusers, once they feel caught, refuse a discount and pay full price. Silent blocking forfeits that.

6. A queue and a revoke path

Why. Review is only free for the user if someone acts on it, and it is only useful to you if you can turn an account off after the fact. A flag that nobody reads is a log line. A confirmed abuser you cannot revoke is a subscription to their compute bill.

How. Build one page that lists flagged accounts with everything linked to them (same device, same card fingerprint, same phone) and one function that revokes credits, invalidates sessions, and cancels the trial. Wire that function to a webhook or a button, and make it idempotent, because you will call it twice. The linked-cluster part matters most: confirming one account and marking the whole cluster is how free trial abuse stops being a weekly chore. What a review should do in your flow is in handling verdicts.

7. Fail open

Why. Any check you add is now in the critical path of signup. If the check is down, your signup form is down, and that is a worse outcome than a bad afternoon of farmed accounts.

How. Give every external call a budget of a few hundred milliseconds, return allow on timeout, tag the record as degraded, and alert when the degraded rate climbs. Reserve fail-closed for the one endpoint where an open door costs real money per request, and make that a deliberate configuration rather than the default.

8. The first attack: what to read and roll

Why. It will come, usually within weeks of anything appearing on Product Hunt or a subreddit, and the panic response is to turn signups off. Write the runbook now so the response takes an hour and not a weekend.

How. Before launch, know where these live and how to pull them in one query:

  • Signups per hour by device fingerprint, email domain, and ASN, so you can see which cluster produced the spike.
  • Consumption per new account in its first hour, so you can find the accounts that burned their allowance immediately.
  • If you take cards, the Stripe logs. Stripe's own active card testing checklist says to look for a spike in 402 errors and generic_decline outcomes, refund anything fraudulent that got through so it does not become a dispute, and then add controls.
  • Which keys to roll. A leaked publishable key lets an attacker drive your payment form directly; a leaked secret key lets them create payments and set up cards with your account. Know where both are configured and how long a rotation takes.
  • The revoke function from item 6, run against the whole cluster and not one account at a time.

Then, once it is over, feed the outcome back into your scoring: which accounts were confirmed, which flags were wrong. That feedback is what makes the second attack cheaper than the first.

Where Portreeve fits

Most of this list is a description of what I ended up building after doing it by hand more than once. Portreeve is one API call at signup, trial_start, trial_convert, checkout_attempt, and login that returns allow, review, or block with reason codes in under 100 ms. It links accounts across hashed email, device, card fingerprint, phone, and payer wallet, treats IP as a soft signal only, routes uncertain events to a review queue that never blocks the user, delivers a later deny to your server by signed webhook, and fails open within a 400 ms budget. The free tier is 1,000 screened events a month with no card.

If you would rather not build the queue, the counters, and the cluster graph before launch, create a free account and put the call in front of your signup form this afternoon.

← Back to all posts