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

Free Is the Floor: What Your App Does When Someone Stops Paying

9 min read Nicolas Demanez — Founder

A card fails, the retries run out, and the customer definitively stops paying. What does your app do the next time they open it?

Most apps show a wall. The window loads, the content is blurred, and there is one button that says Renew. Everything the person made with your software is on the other side of it.

That is the wrong answer. It is wrong ethically, because the work is theirs. It is also the worst-performing option commercially. A locked-out customer does not renew at a higher rate than a reduced-tier one. They ask for a refund, file a chargeback, or post a screenshot of your wall.

Free should be the floor. Not zero.

One clarification first, because these get conflated constantly: a lapse is not a refund. A refund means the money went back, and revoking access is correct and fair. That case has its own mechanics, covered in what happens after a refund. A lapse is different. The customer paid for every month they used and stopped buying more. Nothing was taken back, so nothing they earned should be.

The real problem is data hostage, not feature access

Locking a lapsed customer out of your app usually locks them out of their own files, and that is what generates the damage.

A document editor holds documents. A design tool holds project files in a proprietary format nothing else opens. A note app holds years of notes. Gate the app behind a renew wall and you have not gated a feature set. You have taken custody of work the customer produced and are holding it against a payment.

Customers understand this instantly. The support ticket is not “how do I renew.” It is “I need my files.” That email has a tone, and it escalates fast, because from their side you have done something close to theft.

Three things follow:

  1. Refund demands for past months. They will ask for the last three payments back, and the argument is emotionally coherent even when contractually wrong.
  2. Chargebacks. If you say no, some go to their bank instead. A chargeback costs you the payment, a fee, and a mark against your processor account.
  3. Public complaints. A screenshot of a paywall sitting on top of somebody’s own work is the most reliably shareable form of software criticism there is.

None of those is renewal. You built a mechanism meant to force payment and it produced three flavors of loss instead.

The failure is a category error. You gated the wrong thing. Your product is not the file. It is the ability to keep doing new work.

Gate features, never artifacts

The line that holds up under pressure is between features and artifacts. You may gate features. You may not gate artifacts.

A feature is capability your engineering produced: the 4K export, the batch processor, the sync, the plugin system. Charging for continued access is fair. A subscription buys ongoing work, and when it stops, the ongoing work stops.

An artifact is what the customer made: their documents, projects, libraries, presets. Your software was the tool. The output belongs to the person who did the work, and their payment history bought the right to create it. That right does not retroactively expire.

So the practical rule for a lapsed state:

  • Opening existing work: always, permanently. No time limit, no ten-file cap, no thirty-day grace that quietly ends.
  • Exporting existing work: always, permanently. In an open format, not just yours. If the only way out is a paid feature, the data is still hostage.
  • Creating new work: fair to limit. A ceiling on new documents or projects is reasonable and readable.
  • Premium features: fair to gate entirely. This is what they were paying for.
  • Updates and new versions: fair to stop. They pay for future work or they do not get it.

That last one is the whole logic of perpetual fallback licensing.

Perpetual fallback licensing, and when it fits

A perpetual fallback license means that after a qualifying period of paid subscription, the customer keeps a permanent, working license to the version current when they stopped paying.

They stop receiving updates. They do not stop having software. Twelve months is the most common qualifying period, so someone who pays one month and cancels does not walk away with a perpetual license for a twelfth of the price.

This fits products whose value does not decay: an editor, a compiler, a converter, a utility. Version 4.2 does the job in 2029 as well as it did the day it shipped. Charging rent on software that already works, then taking it away when the rent stops, is hard to defend.

It fits badly when your product requires you to keep spending: hosted sync, server-side inference, anything with a per-use cost. There, continued access has a continued price, and stopping service when payment stops is honest. Even then, export survives. The compute is yours. The data is not.

One-time purchase versus subscription and subscription licensing for Mac apps cover the model choice itself. The narrower point here: whatever model you pick, decide the floor before you ship, not the first time a customer hits it.

Make the floor honest, not a nag

A reduced state only works if a reasonable person could live on it indefinitely. If they cannot, it is not a free tier. It is a trial in disguise, and customers recognize the difference immediately.

Here is the dishonest version. Everything technically works, but there is a modal on launch, a badge on four toolbar items, and a banner every session. Saving takes an extra click that reminds you what you used to have. Nothing is quite blocked and nothing is quite usable.

That is worse than a hard lockout. It converts about as badly and it makes the person dislike your app every day. Resentment is not a funnel stage.

An honest floor has four properties:

  • A shape you can state in one sentence. “Free keeps your library, opens anything you made, and lets you create up to three new projects.” If it takes a table to explain, it is a maze, not a tier.
  • Quiet. One dismissible notice on the transition. After that, gated features are labeled where they live and nowhere else. No launch modals. Paywall design patterns apply here as much as pre-purchase.
  • No degradation over time. No stealth ratchet where the tier gets worse at day 30 and again at day 90. If you would not ship those terms to a new free user, do not apply them to a lapsed paying one.
  • It never touches saved data. No deletion after inactivity, no read-only lock on files, no expiring exports.

The test: would you offer this exact state to a new user who never paid a cent? If yes, it is a floor. If no, it is a hostage situation with better manners.

The recovery math favors keeping them

A lapsed customer still using a reduced version of your app is a warm prospect. A locked-out one is gone, and a meaningful share are negative.

Walk both paths. In the reduced state, the person opens your app next month because their files are in it. When their situation changes, or you ship something they want, reactivation is one click and no reinstall. Reactivating an existing user has always been cheaper than acquiring a new one, because you skip discovery, evaluation, trust, and install entirely.

In the lockout path, the app comes off the machine within a week. Getting them back means reacquisition at full cost, and it is worse than a cold prospect, because they already have a story about you and it ends with your paywall sitting on their work. Some tell it publicly.

Track lapse recovery rate separately from churn. Churn treats a lapse as terminal. It often is not, and the number tells you whether your floor is working. It is one of the licensing metrics worth watching.

There is a second-order effect. A reduced free tier is a permanent demo installed on the machine of someone who already knows the product. That is a better trial than any trial you could design, and it costs you only the features you were not going to sell this month.

Encode the fallback in the lease

The app has to resolve into the reduced state correctly with no network, which means the lease must say what happens after expiry rather than only when it expires.

This is where most implementations quietly break. The lease carries expiresAt and nothing else. The app wakes up offline, sees a past date, cannot ask the server what that means, and does the only thing it can: treats the license as invalid. A customer who should be on your free floor is staring at a lockout you never intended to build, with no network to fix it. Same outcome as the hostile design, arrived at by accident.

The fix is to make the post-expiry state part of the signed payload. Full entitlement set for the paid window, fallback set for after. The app resolves against the clock alone.

// The signed lease carries BOTH states. Nothing here needs a network.
type Entitlements = {
  openExisting: boolean   // never false. this is their work.
  exportExisting: boolean // never false. this is their work.
  createNew: number | 'unlimited'
  premium: string[]
  updateChannel: 'stable' | 'none'
}

type Lease = {
  licenseId: string
  expiresAt: string          // ISO 8601
  active: Entitlements
  fallback: Entitlements     // what a lapse resolves INTO, not a lockout
  signature: string          // Ed25519 over the payload above
}

export function resolve(lease: Lease, now = new Date()): Entitlements {
  // Verify first. An unsigned or tampered lease is a real failure.
  if (!verify(lease)) throw new InvalidLeaseError()

  // Expiry is not a failure. It is a transition to a known state.
  return new Date(lease.expiresAt) > now ? lease.active : lease.fallback
}

// Perpetual fallback (one-time-purchase-with-updates product):
const perpetual: Entitlements = {
  openExisting: true,
  exportExisting: true,
  createNew: 'unlimited',
  premium: ['batch-export', 'plugins'], // earned, kept
  updateChannel: 'none',                // future work is not paid for
}

// Reduced floor (service-backed product):
const floor: Entitlements = {
  openExisting: true,
  exportExisting: true,
  createNew: 3,
  premium: [],
  updateChannel: 'stable',
}

Two properties matter. First, openExisting and exportExisting are true in every fallback set you will ever write, which is a rule you can enforce in a test. Second, expiry produces a state, never an exception. Only a signature that does not verify throws, because that is an integrity failure rather than a business condition. Code that cannot tell those apart will eventually punish a paying customer for being on a train. Verification mechanics are in how offline license validation works, payload structure in the Ed25519 lease format.

Then tell them it is coming. One email before the transition saying plainly what changes and what does not, one in-app notice on the first launch after. The sentence customers need is short: your projects stay open and exportable, forever, and here is what pauses. A customer portal where they can restart without emailing you closes the loop, because the moment someone decides to come back should not depend on your support response time.

You can build all of this yourself. It is a signed payload with two entitlement sets, a resolve function, and the discipline to write the fallback down before you ship. The hard part is not the code. It is remembering the offline path exists, and keeping the fallback honest a year later when a growth idea suggests tightening it.

If you would rather not maintain that, Keylight issues leases carrying the post-expiry entitlement set as signed data, so a lapsed app resolves into your floor with no server call. Stripe keeps handling payments and the subscription lifecycle.

Decide your floor now, while nobody is angry. It is a much harder conversation to have for the first time in a support thread.

Frequently asked

What happens when a software subscription ends?+

That is entirely your design choice, not a technical constraint. The two common patterns are a hard lockout, where the app refuses to open, and a reduced free state, where the app still runs with premium features gated. For desktop apps that hold customer files, the reduced state performs better on both support load and reactivation.

Is a lapsed subscription the same as a refund?+

No, and treating them the same is a bug. A refund means the money came back and access should be revoked. A lapse means the customer paid for the time they used and simply stopped renewing. A lapsed customer keeps everything they already earned. A refunded one does not.

What is a perpetual fallback license?+

A perpetual fallback license means that after a qualifying period of paid subscription, the customer keeps a permanent license to the version current at the time they stop paying. They lose future updates, not the software. It is the standard model for one-time-purchase-with-updates products.

Should a lapsed customer still be able to export their data?+

Always, and permanently. Export and read-only access to work the customer already created should survive a lapse with no time limit. Gating it produces refund demands, chargebacks, and public complaints instead of renewals.

How does the app know it lapsed if it cannot reach the server?+

The lease has to encode the post-expiry state, not just an expiry date. A lease that only says "valid until" leaves the offline app guessing, and most implementations default to invalid. A lease that carries a fallback entitlement set resolves correctly with no network at all.

Ready to ship?

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

Start Free