Guide

Lemon Squeezy Churn Analytics: Track & Reduce Customer Churn

Lemon Squeezy handles payments beautifully, but it does not give you churn analytics out of the box. Here is how to track, measure, and reduce subscription churn for your Lemon Squeezy–powered SaaS.

·14 min read

The Churn Analytics Gap in Lemon Squeezy

Lemon Squeezy is an excellent merchant of record for SaaS companies. It handles taxes, payments, and license management in a single platform. But when it comes to understanding why customers cancel, it leaves a significant gap.

The Lemon Squeezy dashboard shows you basic subscription metrics: total subscribers, new subscriptions, and revenue. But it does not provide:

  • Monthly or annual churn rate calculations
  • Churn rate trends over time
  • Cohort analysis (do customers who signed up in January churn faster than March signups?)
  • Churn reasons and categorization
  • Revenue impact analysis (which plan tiers churn the most?)
  • Automated exit surveys or feedback collection

This means that if you use Lemon Squeezy as your payment provider, you are flying blind on churn. You can see that customers are leaving, but you do not have the tools to understand why or to take action.

The good news is that Lemon Squeezy provides webhooks that give you real-time notification of subscription events. You can use these to build your own churn analytics, or you can connect a tool like ChurnNote that does it automatically.

Setting Up Lemon Squeezy Webhooks

Lemon Squeezy webhooks work similarly to Stripe webhooks. You register a URL, choose which events you want to receive, and Lemon Squeezy sends a POST request to your URL whenever those events occur.

Step 1: Create a webhook in the LS dashboard

Go to Settings → Webhooksin your Lemon Squeezy dashboard. Click “Add Webhook” (or use the “+” button).

  • Callback URL: your endpoint, for example https://yourapp.com/api/webhooks/lemonsqueezy
  • Signing secret: Lemon Squeezy generates this for you. Copy it and store it in your environment variables.
  • Events: select subscription_cancelled, subscription_expired, and subscription_updated.

Step 2: Store your credentials

.env.local
LEMONSQUEEZY_WEBHOOK_SECRET=your_signing_secret_here
LEMONSQUEEZY_API_KEY=your_api_key_here

Lemon Squeezy subscription events

Lemon Squeezy fires several subscription-related events. The ones relevant to churn tracking are:

EventWhen it fires
subscription_cancelledCustomer cancels (may still have access until period ends)
subscription_expiredSubscription period ends after cancellation
subscription_updatedAny subscription change (plan swap, pause, resume)
subscription_payment_failedPayment attempt fails (involuntary churn risk)

Handling the subscription_cancelled Event

Here is a complete Next.js webhook handler for Lemon Squeezy cancellation events. The key difference from Stripe is how signature verification works—Lemon Squeezy uses HMAC SHA-256 with a hex digest.

app/api/webhooks/lemonsqueezy/route.ts
import { NextRequest, NextResponse } from "next/server"
import crypto from "crypto"

const webhookSecret = process.env.LEMONSQUEEZY_WEBHOOK_SECRET!

function verifySignature(
  payload: string,
  signature: string
): boolean {
  const hmac = crypto.createHmac("sha256", webhookSecret)
  const digest = hmac.update(payload).digest("hex")
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(digest)
  )
}

export async function POST(req: NextRequest) {
  const body = await req.text()
  const signature = req.headers.get("x-signature")

  if (!signature || !verifySignature(body, signature)) {
    return NextResponse.json(
      { error: "Invalid signature" },
      { status: 401 }
    )
  }

  const event = JSON.parse(body)
  const eventName = event.meta.event_name

  switch (eventName) {
    case "subscription_cancelled": {
      await handleCancellation(event)
      break
    }
    case "subscription_expired": {
      await handleExpiration(event)
      break
    }
    default:
      break
  }

  return NextResponse.json({ received: true })
}

Now implement the cancellation handler to extract the customer and subscription details:

Cancellation handler
interface LSWebhookEvent {
  meta: {
    event_name: string
    custom_data?: Record<string, string>
  }
  data: {
    id: string
    attributes: {
      user_email: string
      user_name: string
      status: string
      variant_name: string
      product_name: string
      cancelled: boolean
      ends_at: string | null
      created_at: string
      renews_at: string | null
    }
  }
}

async function handleCancellation(
  event: LSWebhookEvent
) {
  const { attributes } = event.data

  const cancellationData = {
    subscriptionId: event.data.id,
    customerEmail: attributes.user_email,
    customerName: attributes.user_name,
    planName: attributes.variant_name,
    productName: attributes.product_name,
    cancelledAt: new Date(),
    endsAt: attributes.ends_at
      ? new Date(attributes.ends_at)
      : new Date(),
    // Lemon Squeezy doesn't include a reason
    // in the webhook -- you need exit emails
    reason: null,
  }

  // Save to your database
  await db.cancellations.create({
    data: cancellationData,
  })

  // Send exit email to learn why
  await sendExitEmail(cancellationData)
}

async function handleExpiration(
  event: LSWebhookEvent
) {
  // Subscription has fully expired
  // Update status in your database
  await db.cancellations.update({
    where: {
      subscriptionId: event.data.id,
    },
    data: {
      status: "expired",
      expiredAt: new Date(),
    },
  })
}

Key difference from Stripe

Lemon Squeezy does not include a cancellation reason in the webhook payload. Unlike Stripe, which has a cancellation_details field, Lemon Squeezy gives you no built-in way to know why the customer left. This makes exit emails or post-cancellation surveys essential.

Building a Churn Dashboard

Once you are collecting cancellation events, you need to turn that raw data into actionable metrics. Here are the key metrics to track on your churn dashboard:

Monthly customer churn rate

Churn Rate = Cancellations This Month / Active Subscribers at Start of Month × 100

Track this monthly and look for trends. A rising churn rate is an early warning of product or market problems.

Revenue churn (MRR impact)

Not all cancellations are equal. A customer on your $99/month plan represents 10x the MRR impact of a $9.99/month customer. Track the dollar value of churned subscriptions alongside the count.

Churn by plan tier

Segment cancellations by variant_name to see which plans churn the most. If your free or lowest tier has much higher churn, that is expected. If your highest tier is churning, that is an urgent problem.

Cohort retention

Group customers by their signup month and track what percentage are still active after 1, 3, 6, and 12 months. This reveals whether your retention is improving over time as you make product improvements, or whether it is getting worse.

Time to churn

Calculate the average time between subscription creation and cancellation. If most cancellations happen in the first 30 days, you have an onboarding problem. If they happen around month 3–6, customers are likely not finding enough ongoing value.

Building all of this from scratch requires significant development time. You need database schema design, API endpoints, a frontend dashboard, and ongoing maintenance. For a quick estimate of your current churn metrics, try our churn rate calculator.

Collecting Churn Reasons

Since Lemon Squeezy does not provide churn reasons in its webhook data, you need another mechanism to find out why customers leave. There are three main approaches:

1. In-app cancellation survey

If you manage the cancellation flow in your own app (rather than using Lemon Squeezy's customer portal), you can ask a question before processing the cancellation. This captures the reason at the moment of highest intent but only works if the customer cancels through your UI.

Downside: customers who cancel via Lemon Squeezy's portal or by contacting support bypass your survey entirely.

2. Post-cancellation email survey

Send an email after cancellation with a link to a survey (Google Forms, Typeform, etc.). This catches all cancellations regardless of how they happened, but response rates are typically low (5–10%) because it requires the customer to click a link and fill out a form.

3. Personal exit email

Send a plain-text email from a real person (the founder, product lead, or customer success manager) that asks a simple question. No survey link, no form—just a genuine email that invites a reply. This approach gets 3–5x higher response rates than surveys because it feels personal and requires minimal effort to respond.

The challenge with approach #3 is the operational overhead. Crafting a personalized email for every cancellation, sending it within minutes, and then categorizing all the responses is time-consuming. This is exactly what ChurnNote automates.

Strategies to Reduce Lemon Squeezy Churn

Once you have churn data flowing, here are specific strategies that work well for Lemon Squeezy–powered products:

Update payment methods proactively

Lemon Squeezy handles dunning (failed payment retries) automatically, but you can reduce involuntary churn further by emailing customers before their card expires. Use the subscription data to identify cards expiring next month and send a friendly reminder.

Offer annual billing incentives

Annual subscribers churn at roughly one-third the rate of monthly subscribers. Offer a meaningful discount (15–20%) for annual billing and promote the upgrade to monthly subscribers who have been active for 3+ months.

Use license keys for engagement tracking

Lemon Squeezy supports license key validation. If your product uses license keys, track validation frequency as a proxy for engagement. Customers who stop validating their license have likely stopped using your product and are at risk of churning.

Leverage the customer portal

Lemon Squeezy provides a customer portal where subscribers manage their subscription. You can customize this experience and add messaging that reinforces the value of staying subscribed before they hit the cancel button.

For a deeper dive into churn reduction tactics, read our comprehensive guide on how to reduce SaaS churn rate.

The Faster Path: ChurnNote

Building webhook handlers, a cancellation database, exit email infrastructure, AI-powered response categorization, and a churn dashboard is a multi-week engineering project. And then you need to maintain it.

ChurnNote integrates with Lemon Squeezy natively. Connect your account with your API key, and ChurnNote automatically:

  • Listens for subscription cancellations via webhooks
  • Sends a personalized, AI-crafted exit email to every churned customer
  • Captures and categorizes their replies using AI
  • Provides a dashboard showing your top churn reasons, trends, and patterns
  • Sends you a weekly digest summarizing all cancellation feedback

Setup takes about 5 minutes. You paste your Lemon Squeezy API key, configure your sender identity, and ChurnNote handles the rest. No webhook code, no email infrastructure, no dashboard building.

Get churn analytics for Lemon Squeezy

Connect your Lemon Squeezy account and start understanding why customers cancel. No code required.

Start free trial →

Related guides & tools