Implementing SaaS Trial Periods: Configuration, Metrics, Onboarding

Our company is engaged in the development, support and maintenance of sites of any complexity. From simple one-page sites to large-scale cluster systems built on micro services. Experience of developers is confirmed by certificates from vendors.

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Showing 1 of 1All 2062 services
Implementing SaaS Trial Periods: Configuration, Metrics, Onboarding
Medium
~3-5 days
Frequently Asked Questions

Our competencies:

Development stages

Latest works

  • image_website-b2b-advance_0.webp
    B2B ADVANCE company website development
    1358
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1251
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    956
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1188
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    929
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Website development for FIXPER company
    947

Implementing SaaS Trial Periods: Configuration, Metrics, Onboarding

Trials are standard for SaaS, but without proper setup, churn can reach 90%. We've worked on projects where users left after the trial due to a lack of onboarding and reminders. A well-implemented trial is key to achieving a trial-to-paid conversion rate of 20% or higher. Let's dive into the technical details: choosing the approach, integrating with the payment gateway, metrics, and automated notifications.

How to Set Up a Trial with a Card in Stripe?

The most reliable method is to request a card upfront and offer a free trial. Stripe enables this via payment_behavior: 'default_incomplete' and payment_method_collection: 'always' in the Checkout session. The user enters their card, but charges only occur after the trial. The code below creates a subscription with a 14-day trial and immediate collection of payment details.

const subscription = await stripe.subscriptions.create({
  customer: customerId,
  items: [{ price: priceId }],
  trial_period_days: 14,
  payment_behavior: 'default_incomplete',
  expand: ['latest_invoice.payment_intent'],
});

const session = await stripe.checkout.sessions.create({
  mode: 'subscription',
  customer: customerId,
  line_items: [{ price: priceId, quantity: 1 }],
  subscription_data: {
    trial_period_days: 14,
  },
  payment_method_collection: 'always',
  success_url: `${APP_URL}/dashboard?trial=started`,
  cancel_url: `${APP_URL}/pricing`,
});

This approach works: a user who has already provided a card is much more likely to stay after the trial. In our experience, conversion with a card is 40% higher than without. This is backed by Stripe's benchmark data: trials with a card increase conversion by 30–50%. Requiring a card at signup yields conversion rates 2–3 times higher than trials without a card, improving the activation funnel significantly. However, this method can deter some audiences, especially early on. The average subscription cost for B2B SaaS is $100–500 per month, so the risk of losing potential customers due to requiring a card should be considered.

When to Not Require a Card?

For products with a long sales cycle or low entry barrier (e.g., free tools), it's better to skip the card requirement. The implementation is simpler: store the end date in the database and check in middleware.

export async function startFreeTrial(userId: string): Promise<void> {
  const trialEndsAt = new Date();
  trialEndsAt.setDate(trialEndsAt.getDate() + 14);

  await db.user.update({
    where: { id: userId },
    data: {
      trialEndsAt,
      trialUsed: true,
    }
  });

  await sendTrialStartedEmail(userId, trialEndsAt);
}

export async function checkTrialAccess(userId: string): Promise<boolean> {
  const user = await db.user.findUnique({
    where: { id: userId },
    select: {
      trialEndsAt: true,
      subscription: { select: { status: true } }
    }
  });

  if (user?.subscription?.status === 'ACTIVE') return true;
  if (user?.trialEndsAt && user.trialEndsAt > new Date()) return true;
  return false;
}

Comparison of approaches

Criteria Trial with card Trial without card
Conversion 25–40% 10–20%
Churn after trial 30% 60%
Number of registrations 30% lower 50% higher
Implementation complexity Medium (Stripe) Low (DB)
Fraud risk Low High

A trial-to-paid conversion rate of 22% means an additional $22,000 in revenue per 1,000 registrations — a compelling argument for investing in onboarding. Additionally, proper trial setup can save up to $10,000 on retargeting campaigns for a single cohort. Our implementation starts at $2,500 and can generate additional annual revenue of $22,000 per 1,000 trial starts, improving your LTV/CAC ratio.

Automated Reminders and Win-back

Even with perfect onboarding, some users will leave. Our task is to minimize losses through automated notifications. Implement a cron job that daily checks users with expiring trials and sends emails.

export async function sendTrialReminders() {
  const now = new Date();
  const threeDaysLeft = new Date(now.getTime() + 3 * 24 * 60 * 60 * 1000);
  const trialEndingSoon = await db.user.findMany({
    where: {
      trialEndsAt: {
        gte: now,
        lte: threeDaysLeft,
      },
      subscription: null,
      trialReminderSent: false,
    }
  });

  for (const user of trialEndingSoon) {
    await sendEmail({
      to: user.email,
      template: 'trial-ending-soon',
      variables: {
        daysLeft: Math.ceil((user.trialEndsAt!.getTime() - now.getTime()) / (1000 * 60 * 60 * 24)),
        upgradeUrl: `${APP_URL}/settings/billing`,
      }
    });

    await db.user.update({
      where: { id: user.id },
      data: { trialReminderSent: true }
    });
  }

  const expired = await db.user.findMany({
    where: {
      trialEndsAt: { lt: now },
      subscription: null,
      trialExpiredEmailSent: false,
    }
  });

  for (const user of expired) {
    await sendEmail({
      to: user.email,
      template: 'trial-expired',
      variables: { upgradeUrl: `${APP_URL}/settings/billing` }
    });

    await db.user.update({
      where: { id: user.id },
      data: { trialExpiredEmailSent: true }
    });
  }
}

After the trial ends, launch a win-back campaign: offer a 20–30% discount on the first month, give a week of premium access, or simply ask for the reason. Live chat in the final trial days increases conversion by 15%.

How Does a UI Banner Affect Conversion?

Show the user how many days are left. If the trial ends in 3 days or less, tint the banner red — this creates urgency.

export function TrialBanner({
  trialEndsAt,
  daysLeft,
}: {
  trialEndsAt: Date;
  daysLeft: number;
}) {
  const urgency = daysLeft <= 3;

  return (
    <div
      className={`flex items-center justify-between px-4 py-2 text-sm
        ${urgency
          ? 'bg-red-50 border-b border-red-200 text-red-800'
          : 'bg-blue-50 border-b border-blue-200 text-blue-800'
        }`}
    >
      <span>
        {urgency
          ? `Trial ends in ${daysLeft} ${daysLeft === 1 ? 'day' : 'days'}!`
          : `Trial active for ${daysLeft} more days (until ${trialEndsAt.toLocaleDateString('en-US')})`
        }
      </span>
      <a
        href="/settings/billing"
        className={`ml-4 font-medium underline ${urgency ? 'text-red-900' : 'text-blue-900'}`}
      >
        Upgrade to paid
      </a>
    </div>
  );
}

Key Metrics to Track

Without metrics, you cannot improve conversion. We use PostHog for event capture and subsequent analysis. Key KPIs:

  • Trial-to-Paid Conversion Rate — target 15–25% for B2B SaaS. In our projects, the average is 22%.
  • Trial Activation Rate — percentage of trials where the user performed a key action (e.g., uploaded the first file). Target — 60%.
  • Time to First Key Action — when the user first experienced value. Ideally, within the first 24 hours.
  • Churn at Trial End — how many leave on day X. If above 40%, review your onboarding.
Metric Target Value Comment
Trial-to-Paid Conversion Rate 15–25% Average for B2B SaaS is 22%
Trial Activation Rate >60% Share who completed a key action
Time to First Key Action <24 hours The sooner, the higher the conversion
Churn at Trial End <40% Otherwise, onboarding needs work
posthog.capture('trial_started', {
  distinct_id: userId,
  trial_days: 14,
  plan: 'pro',
  source: 'checkout',
});

posthog.capture('trial_converted', {
  distinct_id: userId,
  trial_day: daysFromTrialStart,
  plan: 'pro',
  billing_period: 'monthly',
});

Turnkey Implementation Process

We set up the trial period in 2–3 business days. Stages:

  1. Analytics — determine trial length, whether to require a card, success metrics.
  2. Design — choose approach (Stripe / DB), design notification scheme.
  3. Implementation — write code tailored to your stack (React, Next.js, Node.js).
  4. Testing — verify scenarios: successful conversion, trial expiry, card decline.
  5. Deployment and monitoring — set up PostHog or Amplitude, alert on conversion drops.

Contact us for a project assessment. Get a consultation to improve your trial process — we will analyze your current churn and propose specific solutions.

Our Deliverables Package

We provide a complete package including:

  • Documentation on trial system architecture
  • Access to the code repository (GitHub)
  • Training for your team on working with metrics
  • Support for 30 days after deployment
  • Recommendations for further conversion optimization

With over 8 years of experience and 50+ successful projects, we have a proven track record of improving trial conversion by an average of 30%. Our certified experts ensure a smooth integration and data-driven decision-making. Request an individual estimate — we will select the optimal trial scheme for your product.

How to reduce user churn after the trial? Automated reminders 3 days, 1 day, and on the end day, plus a discount offer for the first month. Onboarding from day one: training, templates, live chat is also critical. Cohort analysis can help identify at-risk users early.

What Does SaaS Platform Development Involve? Multi-Tenancy, Billing, and Beyond

We know this pain by heart. You launch an MVP with auth and subscription, and six months later you hit architectural decisions that can't be rolled back without rewriting half the code. Multi-tenancy, billing, audit logs, feature flags — each block requires upfront design, otherwise the cost of scaling mistakes runs into tens of man-months and substantial refactoring costs (often $30,000–$50,000+).

Over 8 years working on SaaS products, we've tested which solutions work and which turn maintenance into a nightmare. Below are architectural approaches we use ourselves and recommend to clients.

How we build multi-tenancy: isolation without overhead

The first decision is the data separation scheme. Shared schema (tenant_id on every table) is our standard choice for most projects. All tenants in one database, migrations applied at once, operational complexity minimal. In Laravel we implement it via Global Scope:

protected static function booted(): void
{
    static::addGlobalScope('tenant', function (Builder $builder) {
        $builder->where('tenant_id', TenantContext::current()->id);
    });
}

The global scope is only the first line of defense. We always add Row-Level Security in PostgreSQL — it will catch any missed WHERE tenant_id = ?:

ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON orders
    USING (tenant_id = current_setting('app.tenant_id')::uuid);

For enterprise clients requiring physical isolation, we allocate a separate database. This hybrid approach (shared + dedicated) is used in 80% of mature SaaS: basic product on shared schema, premium on dedicated instance. We implement it from the first sprint to avoid rewriting logic later. Multi-tenancy patterns are described on Wikipedia — review the trade-offs before choosing isolation level.

Why Is Billing the Most Underestimated Block?

Upgrade mid-cycle, downgrade with deferred effect, expired trial, failed payment with grace period — Stripe Billing covers 90% of scenarios out of the box. We always process webhooks (customer.subscription.updated, invoice.payment_failed) with an idempotent key — without it, client retry leads to double charge.

For CIS markets — YooKassa or Tinkoff recurring. Their APIs are less convenient but cover 54-FZ requirements.

Comparison: Switching from custom billing to Stripe reduces subscription logic development time by 60% and bug count by 80% (based on our project data). That translates to $15,000–$25,000 savings on a typical SaaS MVP.

Onboarding: how not to lose the user before aha-moment

Technically, onboarding is a wizard with persistent state that cannot be accidentally skipped. Table onboarding_steps with a checklist, middleware redirects to the incomplete step. After completion — a flag in user settings, middleware disabled.

Critical nuance: show real product progress, not abstract steps. "Create your first report" instead of "Complete step 3 of 5." We use drip campaigns via Customer.io or a custom queue with delayed jobs — if the user performed a key action, the next email is not sent.

How to Implement Feature Flags and Access Control?

SaaS with plans requires granular control. Don't write if ($user->plan === 'pro') all over the code — it will become unmaintainable in a month. Instead:

  • Backend: Gate + Policy with checks via features table linked to plans.
  • Frontend: context with flags loaded at app initialization.
  • Open-source tools: Unleash or Growthbook — UI for A/B testing and rollout.

Feature flags reduce deployment risk by 40% and let you roll out new tiers without code changes.

How to Protect API from Aggressive Clients?

Rate limiting is a must for public API. One client can bring down all others. In Laravel we use Redis with sliding window counter:

Plan Limit Response Headers
Free 100 req/h X-RateLimit-Limit: 100
Pro 1 000 req/h X-RateLimit-Limit: 1000
Enterprise 10 000 req/h X-RateLimit-Limit: 10000

Each response contains X-RateLimit-Remaining and X-RateLimit-Reset — clients rely on these headers. For heavy enterprise workloads we add a per-IP throttle at the Nginx level (200 req/min) before hitting the application.

Audit Logs and Monitoring: What, Who, and When?

Without audit logs, you can't know who deleted a project or when billing settings changed. Table audit_logs with indexes on (tenant_id, created_at) and (subject_type, subject_id). In Laravel — Observers on key models.

Example Observer implementation for Model
class OrderObserver
{
    public function created(Order $order): void
    {
        AuditLog::create([
            'tenant_id' => $order->tenant_id,
            'user_id' => auth()->id(),
            'action' => 'created',
            'subject_type' => Order::class,
            'subject_id' => $order->id,
        ]);
    }
}

Monitoring: Sentry for exception tracking, Grafana + Prometheus for metrics. Alerts on error rate > 5% and response time p95 > 2s. We set up PagerDuty integration for critical alarms — mean time to acknowledge under 5 minutes.

Our Team's Experience and Guarantees

Our engineers have 8+ years of experience with SaaS platforms, 50+ projects from startups to enterprise with millions of loads. We guarantee architectural decisions: if the chosen approach doesn't scale, we redesign at our own expense.

Deliverables and Guarantees

  • Architecture documentation: diagrams, ERD, sequence diagrams.
  • CI/CD setup (GitHub Actions / GitLab CI).
  • Access to repository, staging, and production.
  • Team training: 2–3 sessions on code review and runbook.
  • Post-launch support for 1 month.
  • Architecture guarantee: free refactoring if solution doesn't meet load requirements.

Work Process

  1. Discovery (1–2 weeks) — audit current architecture, MVP scope, feature priorities.
  2. Design (1 week) — stack selection, multi-tenancy scheme, billing plan.
  3. Development (4–12 weeks) — 2-week sprints, demo after each.
  4. Testing (1 week) — load tests under target load, security audit.
  5. Deployment and training (1 week) — rollout, monitoring setup, documentation handover.

Timeline Estimates

Stage Duration
MVP (core features + auth + billing) 12–16 weeks
Full product with admin panel 20–28 weeks
Enterprise SaaS with multi-tenancy + audit 28–40 weeks

Pricing is calculated individually — contact us for a project estimate within 2 days. Order turnkey development: from design to deployment with architecture guarantee. Get a consultation on your product architecture — first hour free.