Skip to main content
Migrate Already selling? Move your customers to Keylight without re-issuing a single key.
Keylight
Blog
licensing piracy metrics

How Much Piracy Do You Actually Have? Measure Before You Fix

9 min read Nicolas Demanez — Founder

You cannot measure your software piracy rate. Not approximately, not with a clever query, not at all.

The reason is structural, and once you see it you stop reaching for the number. A cracked build has your license check removed. Someone patched the branch, stubbed the verifier, or replaced your server hostname with a loopback address. That binary never contacts you. It produces no activation, no validation, no failed request, no log line. It is invisible by construction, because invisibility is the entire point of the crack.

So when a developer tells me piracy is 40% of their user base, I ask where the number came from. It is always a torrent search, a download counter on a warez aggregator, or a vibe.

This matters because the fake number drives real spending. Developers who believe they have a 40% piracy problem go build obfuscation, checksum loops, and tamper detection. Every one of those ships to 100% of paying customers and stops approximately zero determined attackers.

Why your software piracy rate is a guess

The measurement is impossible because the thing being measured has deliberately opted out of measurement.

Think through the three places a number could come from. Server logs only contain requests from builds that still make requests, which is the licensed population by definition. Download counts on piracy sites count bots, curiosity, duplicate mirrors, and broken builds people deleted. Comparing your revenue to an assumed market size requires you to know the market size, which you do not.

There is one narrow exception. If your app is useless without a server your team controls, for example a hosted AI backend that does the actual work, a cracked client still has to talk to you. But what you are measuring there is API abuse, not piracy, and the fix is authentication at the API boundary rather than hardening in the binary.

For everything else, the honest entry on the dashboard is unknown. I left estimated piracy off the list entirely in the nine licensing metrics worth tracking, for exactly this reason. A number you cannot verify is worse than a blank space, because a blank space does not authorize a budget.

The “one pirate equals one lost sale” mistake

The assumption underneath most anti-piracy spending is that each cracked install is a sale you would otherwise have made. It is wrong, and it is wrong in a direction that inflates the problem by a large multiple.

Someone running a cracked copy of a $49 utility falls into one of a few groups. A student in a country where $49 is a meaningful fraction of a week’s income. A person who hit a 7-day trial wall and looked for a way around it. A collector who downloads everything and opens almost none of it. Someone who would have paid but preferred not to. Only the last group is a lost sale, and it is the smallest group.

Say you have 1,000 cracked installs. If 5% of those people would have paid at your price, that is 50 sales, or $2,450 at $49. Now price the response. Two weeks of engineering on obfuscation and tamper checks, plus permanent maintenance every time the OS or your build toolchain changes, plus the support burden from the false positives it creates. The math stops working almost immediately, and it stops working before you account for the damage in the next section.

There is a second-order effect worth naming. Some cracked installs behave like distribution. People use the app, tell colleagues, and some of those colleagues buy it where buying is normal, like on a company card. That does not make piracy good. It makes the naive subtraction wrong.

What you can actually observe: key sharing

Key sharing is measurable, unlike cracking, because a shared key still runs through your licensing system. The credential is real. The check is intact. Every use leaves a record.

This is the practical substitution. Stop trying to count pirates and start watching the three signals that indicate one credential is serving more people than it was sold to.

The devices-per-license tail. Not the average. The average is boring and stays near 1.4 for most apps. The tail is where the information is. A key on 11 devices when your cap is 5 means either your cap is not enforced or your dedupe logic is broken. A key repeatedly bouncing off the cap means it is being passed around.

Geographic spread on a single key. One key validating from six countries within a day is not a traveler. It is a weak signal alone, since VPNs produce noise, but strong alongside a high device count.

Activation velocity. Five devices in the first hour after issuance is a different shape from five devices over eight months. The first is a key that got posted somewhere. The second is a customer with a lot of hardware.

None of these is conclusive alone. Score them together, look at the top of the distribution, and investigate by hand.

// Rank licenses by sharing signal. This is a triage list, not a verdict.
// Every row still needs a human to look at it before anything happens.
type SharingSignal = {
  licenseId: string
  deviceCount: number        // distinct fingerprints ever activated
  limitRejections30d: number // activations refused at the cap
  distinctCountries7d: number
  hoursToNthDevice: number | null // time from issuance to hitting the cap
}

function shareScore(s: SharingSignal): number {
  let score = 0
  if (s.deviceCount > 8) score += 3
  if (s.limitRejections30d > 5) score += 2
  if (s.distinctCountries7d >= 4) score += 2
  if (s.hoursToNthDevice !== null && s.hoursToNthDevice < 24) score += 3
  return score
}

// Review the top 20 by hand, once a month. That is the whole process.
// If the list is short, you do not have a sharing problem worth automating.
const review = licenses.map(shareScore).sort((a, b) => b - a).slice(0, 20)

Run that query once. Most people who do are surprised by how short the list is. If your top offender is a key on 7 devices, you do not have a piracy problem. You have a customer with a laptop, a desktop, a work machine, and a reinstall history.

The mechanics of capping and enforcing this belong to how to prevent license key sharing, and the counting model underneath sits in how device activations work. This post is only about deciding whether you have a problem at all.

A false positive costs more than a pirate

A pirate costs you nothing you were going to collect. A false positive costs you a refund, a support ticket, and a one-star review that stays up for years. Those are not close.

Work through the sequence. Your tamper check misfires on a legitimate copy running under an unusual configuration, maybe a VM, maybe an aggressive security suite, maybe a beta OS. The app calls them a pirate, or worse, refuses to launch with a vague error. That person paid you. They now believe your software is broken and that you accused them of theft.

They ask for a refund, so you lose the revenue. They write a review, so you lose an unknown number of future sales. The public record of your app now includes a stranger explaining that it locked them out of something they bought. Undoing that costs far more than the sale was worth. What you owe them after the refund lands is covered in what happens after a refund.

Set the asymmetry explicitly and design against it. If your false-positive rate is 0.5% and your addressable-pirate rate is optimistically 5%, then for every 1,000 users you are angering 5 paying customers to inconvenience 50 people who were never going to pay. The 5 are worth more than the 50, because the 5 are worth more than zero.

This is why fail-open is the correct default everywhere ambiguity exists. Network unreachable: keep running. Fingerprint shifted after an OS upgrade: keep running. Lease expired but the signature is valid and the clock looks sane: keep running and revalidate later. Reserve the hard refusal for the one unambiguous case, which is a genuinely new device on a key that is genuinely over a generous limit.

Where to draw the line

Draw it at three rules, and stop there. Make honest use frictionless, make casual sharing mildly inconvenient, and accept that determined cracking is unwinnable at indie scale.

The first rule means a paying customer should never think about licensing after the first 30 seconds. Signed offline validation so your server going down does not become their outage. Generous device limits. Self-service device removal so nobody emails you to change laptops. Sensible caps for the kind of app you sell are covered in device activation limits for indie Mac apps.

The second means a cap that a friend-to-friend share bumps into within a few uses. Three to five devices does this. It converts unlimited sharing into a bounded number without the honest customer ever noticing the ceiling exists.

The third is the one people resist. If your app runs on the user’s machine, the check runs on the user’s machine, and a sufficiently motivated person will remove it. This is not a defeat, it is a property of the platform. Adobe, Microsoft, and JetBrains all get cracked within days, with security budgets larger than your entire revenue. You are not going to out-engineer that, and the attempt is what produces the false positives above.

So here is the proportionate ladder, in order:

  1. Do nothing. Ship a normal license check. This is correct until you have evidence.
  2. Measure sharing with the score above, monthly, by hand.
  3. Cap devices generously, with self-service deactivation, using device activations.
  4. Contact the outliers. A polite email to the owner of a key on 14 devices resolves most cases. Frequently it is a small team that assumed one key covered everyone, and the outcome is an upsell rather than an enforcement action.
  5. Revoke individually, rarely, for the small number of keys that are clearly published rather than shared.

There is no rung six. If you find yourself writing obfuscation, you skipped rungs — see best anti-piracy and copy protection for Mac apps for the fuller menu of approaches, ranked the same way: by return on effort, not by how strong they sound.

Go fix activation rate instead

The number you should be worried about is activation rate, not piracy, because it measures customers who paid you and never got in.

Compare the two honestly. Piracy: unmeasurable, mostly not lost revenue, expensive to fight, dangerous to fight badly. Activation failure: exactly measurable, definitely lost revenue since the money is already yours and about to be refunded, cheap to fix, and improving it has no downside for anyone.

If your activation rate is 88%, then 12 out of every 100 paying customers are sitting on an app they cannot open. Those are not hypothetical pirates. They are people who gave you money last Tuesday. Recovering half of them is worth more than every anti-piracy measure you will ever ship, and the fix is usually unglamorous: an email that lands in the inbox, a clearer activation screen, or a key format that survives being copied out of Gmail.

Building the measurement side yourself is reasonable. You need a device table with fingerprints and first-seen timestamps, a validation log with reason codes and coarse geography, and a monthly query. That is a weekend of work, mostly additive if you already have a licensing system. Do it, and you will know more about your business than the developer with the 40% piracy estimate.

If you would rather not maintain the log, Keylight records device counts, activation history, and validation reason codes per license by default, because the system has to track that to enforce a limit at all. Stripe stays your payment processor. See pricing for what the licensing layer costs.

Either way, the discipline is the same. Refuse to put a piracy number on your dashboard, watch the sharing tail instead, and spend the engineering time you just freed up on the customers who already paid.

Frequently asked

Can I measure my software piracy rate?+

Not directly. A cracked build has the license check removed or stubbed out, so it never contacts your server and never appears in any log you own. Every piracy percentage on a dashboard is an estimate built on assumptions, not a measurement.

What piracy signals can I actually observe?+

Key sharing signals, because a shared key still uses your licensing system. Watch the devices-per-license tail, validation attempts on one key from many distant regions, and activation velocity spikes shortly after issuance.

Is a pirated copy a lost sale?+

Usually not. Most people running a cracked build were never going to pay at that price, on that platform, in that country. Treating every crack as lost revenue inflates the problem and justifies spending that does not pay back.

How much should an indie developer spend on anti-piracy?+

Less than they spend on activation rate. A false positive that locks out a paying customer costs a refund plus a public bad review. A determined cracker costs nothing you were ever going to collect.

Ready to ship?

Create your account and start licensing your apps in under a minute. Free forever tier included.

Start Free