One of the coolest things about being responsible for growth at a company building the next generation of messaging infrastructure is that I get to use our own product to implement real lifecycle marketing tactics and solve (or evade) common challenges other platforms face.

A recent project, dubbed “Usage-based upgrade nudges,” is a perfect example of the power of Knock. It’s a powerful automation that helps us proactively communicate with free plan users as they approach their usage limits. It combines Orb (for billing and usage metering) with Knock (for workflow automation and message delivery) to send perfectly timed, data-driven upgrade messages.

This project addresses a problem that many SaaS startups face if they use a usage-based billing model, where teams either communicate usage limits too late, too vaguely, or too inconsistently. As we evaluated how we handled this pattern, we realized there was room for improvement, so I wanted to fix that.

It’s a use case that’s simple on paper, but complex in execution due to a number of moving parts between usage tracking, event processing, and dynamic templating. When implemented correctly, these nudges can be a helpful reminder to the user about their usage and also a huge source of revenue. Here’s how we implemented it and some lessons we learned along the way.

The problem: visibility around usage limits

Knock has tiered pricing plans with ‘messages sent’ being the primary billable metric. Our free Developer plan gives users a generous 10,000 messages per month to test and evaluate Knock for their needs. Many startups can stay under this threshold every month and use Knock for free.

For other orgs, as they migrate more of their messaging to Knock, their usage scales and they approach the upper threshold of this plan…with some going far over it. The next tier up, Knock’s Starter plan, increases the limit to 50,000 messages per month, but we found many accounts weren’t upgrading to it when their volumes reached these levels.

At Knock, we’d never turn off a company’s critical communications, even if they went over their threshold. But after reaching out to a few customers about this overage, we realized there was almost no resistance to upgrading, they just weren’t aware they were over their limit.

We weren't doing enough to provide customers with visibility that they were nearing their message limit — signals were buried in billing dashboards, our own internal Slack alerts, or billing logs that never reached the user. It became obvious the existing signals weren’t enough to drive users to upgrade to a plan that’s a better fit for them.

The plan: automate usage-based warnings to increase upgrades

Obviously we could just pull our billing logs each month, see who went over their usage limits, and send them an email to let them know, but this was highly manual and would have to be repeated on a monthly basis. Plus, every Knock customer has a unique billing date based on the day they signed up, so a manual approach means we could be reaching out at the beginning, middle, or end of their billing period, even if they had reached their limit weeks ago.

It was clear we would need to automate this workflow to ensure the reminders were timely and relevant for each customer. We’d also need to make the usage communication clear, personalized, and actionable to ensure it was helpful to customers and led to the outcome we wanted.

Knowing this, we got to work figuring out how to use Knock itself to power this automation.

Step 1: Powering usage events via Orb webhooks

The first step was to make our usage data available in Knock. Since this type of data is constantly changing, it’s important to treat it like an event stream rather than a static datapoint. To keep our messaging immediate and contextual, it made the most sense to trigger it based on usage events.

For this project, we decided to listen for three thresholds:

  • 75% of limit
  • 90% of limit
  • 100% of limit

Our usage-based billing provider, Orb, tracks real-time message volumes for each account and can emit webhook events when usage crosses specific thresholds. For example, when Orb detects that an account on our free Developer plan sends their 7,500th message, it sends a webhook event to signal they’ve used 75% of their 10,000 message limit.

This ensures instant, event-based visibility into how close each account is to their current plan limits without any manual polling or scheduled jobs.

Step 2: Triggering the Knock workflow

Once our webhooks are firing, we can set up the infrastructure in Knock. First, we created a new Knock workflow, called “Usage-based billing upgrade nudges.”

After ingesting the Orb webhook in our backend, we find the account connected and fetch its users and relevant usage data, including:

  • The account ID
  • The plan type
  • The current usage count
  • The plan’s total limit
  • The list of users with owner or admin roles

Then, we trigger the Knock workflow for the list of users with an API call passing all of the data through to Knock. We added some conditions to only target users with owner and admin role types within the account. We also set some safeguards, so no one with a custom Enterprise plan gets an email.

From there, the workflow itself is relatively simple: once triggered, each user flows through a branch to determine which threshold has been hit (75%, 90%, or 100%), and after that a single email gets sent.

Knock’s usage-based upgrade nudge workflow

These alerts trigger for both accounts on our free Developer plan and our self-serve Starter plan, even though they require slightly different messaging. That single email is deceptively simple — because the power lies in how dynamic the content is.

Step 3: Dynamic email content using workflow variables

When Knock receives the webhook event, the webhook’s metadata comes through as a data payload and can be used as variables in the workflow. This allows us to personalize every message sent with up-to-date, account-specific information to ensure relevance and trust.

For example, free Developer plans will receive:

  • At 75%, the message is purely informational — a friendly heads-up that usage is climbing.
  • At 90%, the tone shifts to proactive — “you’re close to your limit, here’s how to upgrade.”
  • At 100%, it becomes an alert with clear instruction — “you’ve reached your free plan cap; upgrade to keep sending.”
Upgrade required: Message limit exceeded
The 100% usage email for a recipient on a free Developer plan.

Self-serve Starter plans are similar but different:

  • At 75%, the message is still purely informational — a friendly heads-up that usage is climbing.
  • At 90%, the tone stays mostly informational, but introduces the benefits of an Enterprise plan — “you’re close to your limit, Enterprise may be a fit for you.”
  • At 100%, it becomes a reminder — “you’ve reached your included limit; you’re now being charged overages. Reach out if you’d like to inquire about an Enterprise plan.”
Your account has moved to pay-per-message billing
The 100% usage email for a recipient on a paid Starter plan

All the logic for these messaging nuances is powered by Liquid variables inside Knock’s template editor. Conditions control which copy blocks render for each user based on their plan type, and we inject real data points like the customer’s current usage and plan reset date.

Take for instance this Liquid condition used in the 100% usage email. It modifies the subject line copy based on the user's plan type (free or starter):

Data
{
  "data": {
    "plan_type": "free"
  }
}
Template
{% if data.plan_type == "free" %}
🚨 Upgrade required: Message limit exceeded
{% elsif data.plan_type == "starter" %}
Heads up: Your account has moved to pay-per-message billing
{% endif %}
Output
🚨 Upgrade required: Message limit exceeded

That means the same email template dynamically adapts to the recipient's information, saving us from having to create three separate templates.

Step 4: Consistent branding with a usage partial

To make these messages feel cohesive with the rest of the product experience, we also created a new usage-based partial with Knock.

A partial is a reusable piece of content you can use across any message template. They can be enabled as "blocks" for use in Knock’s drag-and-drop email editor. Using HTML code allows the content to be dynamic and ensures there are no rendering issues in email clients.

We designed the usage partial to mimic the look and layout of our billing page, using the same visual design patterns:

  • A progress bar shows how much of the limit is used.
  • Text displays “X / Y messages sent.”
  • A red, destructive state shows when the limit has been exceeded.

In this case, we pass data from the webhook event into the partial as variables that render a personalized graphic for every recipient.

Two variants of the same partial, one in an empty state and one at the 100% messages sent threshold.

The usage-based HTML partial in an empty state (left) vs populated for a recipient at 100% of their messages sent threshold (right).

Embedding this partial in the email keeps our branding consistent and makes the transition from inbox to billing page seamless and familiar.

It’s a small detail, but it reinforces continuity. A customer should feel like every touchpoint, whether in the app, in their inbox, or on a billing screen, is part of a single cohesive system. Knock’s partials make that possible by letting us create and reuse design blocks across workflows.

Step 5: Testing and iteration

Before turning this workflow on, we ran the automation through several test cycles using a sandbox email account to confirm a few key things:

  • Orb events were firing correctly at each threshold.
  • The payload data mapped cleanly to the expected Knock variables.
  • Workflow filtering ensured only relevant users (owners/admins) were included.
  • Emails rendered correctly across clients with dynamic partials loaded.

With Knock’s detailed logs and observability, it was easy to confirm who was sent which message variant, preview messages to ensure the dynamic content was rendering correctly, and troubleshoot any send errors.

Once those checks passed, we updated our sending email account…and the system was live.

Now, every time an account crosses a usage threshold, the workflow automatically runs, populating all variables and delivering the message instantly. It’s fully event-driven, which means there’s no scheduled job or batch sync involved. Everything happens in real time, with clear data provenance from Orb → Knock → User.

No manual tracking, no spreadsheet exports — just a clean feedback loop between product usage, billing, and customer communication.

Early results

As soon as we flipped the switch, this automation started producing a measurable lift in upgrades, all without us having to lift a finger. This past quarter, we more than doubled the previous record for number of Developer -> Starter upgrades.

Free accounts that receive the 90% or 100% message now convert at a meaningfully higher rate than those that didn’t receive the message previously. And to our surprise, we’re even seeing the low-urgency, informational emails at 75% converting free users to paid.

Why does it work so well? The email improves awareness and, in turn, sentiment. Customers are less confused about limits, appreciate the visibility, and are more likely to upgrade proactively.

And because everything is centralized in Knock, there’s zero risk of multiple systems sending duplicate or conflicting messages.

Lessons for other teams

This project might look small on the surface, but it’s a strong example of how product notifications can double as growth levers when implemented thoughtfully.

If you’re managing a usage-based SaaS product and don’t have a similar workflow in place to nudge users to upgrade at certain usage thresholds, you should treat it as a top priority.

Here’s what we learned:

  1. Timing is everything. Instead of sending reminders on arbitrary schedules, send relevant messages when your users need them to turn moments of friction into revenue.
  2. Transparency drives trust. Customers appreciate knowing where they stand. These messages prevent surprises and create a sense of partnership rather than policing.
  3. Product-led growth needs great messaging infrastructure. In usage-based SaaS models, communication is part of the product experience. Knock allows teams to treat these notifications with the same care as any other customer-facing feature.
  4. Centralize messaging logic. Keeping your data, workflow logic, and templates inside one system (Knock) means fewer moving parts and easier iteration.
  5. Use design partials for continuity. Brand consistency across product and messaging surfaces creates trust and recognition and is easier to maintain than duplicating code or HTML.

Automate lifecycle messaging with Knock

Our “Usage-based billing upgrade nudge” workflow shows how lifecycle marketing doesn’t always need a big investment or campaign calendar — sometimes, you just need to leverage powerful tools to build a process that reaches your users at the right moment.

By connecting Orb’s real-time usage data to Knock’s event-driven workflows, we built a self-sustaining system that:

  • Detects key usage milestones.
  • Notifies the right people instantly.
  • Delivers personalized, branded messages.
  • Encourages upgrades without any manual intervention.

It’s automation that feels human, proactive, and trustworthy — exactly how we want every Knock-powered experience to feel.

Whether you want to build your own usage-based upgrade nudge workflow or power other lifecycle marketing use cases, Knock can help. If you'd like to try it out, you can sign up for a free account or chat with our team. 👋