t
Temps

How to Build Conversion Funnels Without Google Analytics

How to Build Conversion Funnels Without Google Analytics

March 12, 2026 (2 days ago)

Temps Team

Written by Temps Team

Last updated March 12, 2026 (2 days ago)

How to Build Conversion Funnels Without Google Analytics

GA4 made funnel tracking harder than it needs to be. Universal Analytics had a straightforward goal funnel — define steps, see drop-offs. GA4 replaced that with custom event configuration, manual exploration reports, and a 72-hour processing delay before results appear. Above 500K events, Google samples your data, and your funnel numbers become estimates rather than facts.

Most developers never configure GA4 funnels at all. Yet knowing exactly where users drop off between landing on your site and completing a purchase is arguably the most valuable metric you can track. A well-built funnel doesn't just show conversion rates — it shows which screen, which form field, which loading spinner is costing you revenue.

This guide covers what conversion funnels actually measure, how to design event schemas for funnel tracking, SQL patterns for computing step-by-step conversion, drop-off visualization, and how first-party analytics can replace GA4's funnel reports entirely.

[INTERNAL-LINK: web analytics without third-party scripts → /blog/how-to-add-web-analytics-without-third-party-scripts]

TL;DR: Conversion funnels track where users drop off between key steps like signup and payment. GA4 funnels require custom event setup, have a 72-hour delay, and sample data above 500K events. You can build your own funnel system with PostgreSQL window functions, or use a platform like Temps that includes funnel analytics out of the box. The average SaaS free-to-paid conversion rate is just 5-7% (Lenny Rachitsky, 2024).


What Is a Conversion Funnel?

A conversion funnel maps the sequential steps users take from first touch to desired outcome. According to a 2024 analysis by FirstPageSage, the average B2B SaaS website converts visitors to leads at just 2.2% (FirstPageSage, 2024). That means 97.8% of visitors leave without taking action — and a funnel tells you exactly where.

Citation capsule: A conversion funnel tracks sequential user steps from first visit to desired outcome. FirstPageSage's 2024 industry benchmark shows B2B SaaS websites convert visitors to leads at an average rate of 2.2%, meaning nearly 98% of visitors drop off before completing a single conversion action.

The simplest funnel has four steps:

  1. Visit — user lands on your site
  2. Signup — user creates an account
  3. Activation — user completes a key action (first deployment, first project, first integration)
  4. Payment — user converts to a paid plan

Each step has a drop-off rate. If 1,000 people visit, 100 sign up, 40 activate, and 8 pay — your visit-to-signup rate is 10%, signup-to-activation is 40%, and activation-to-payment is 20%. The overall funnel conversion is 0.8%.

Why Drop-Off Matters More Than Conversion Rate

Overall conversion rate is a vanity metric. It tells you the end result but hides where the problem lives. If your visit-to-signup rate is 15% but signup-to-activation is 12%, you don't have a traffic problem. You have an onboarding problem.

Drop-off analysis pinpoints the exact step costing you money. Fix the worst drop-off first — that's where marginal effort produces the largest revenue gain. A 5% improvement at your worst step compounds through every step below it.

What Real Funnel Numbers Look Like

Benchmarks vary by industry, but here's what healthy SaaS funnels typically show:

StepTypical RateGood Rate
Visit → Signup2-5%8-12%
Signup → Activation20-40%50-70%
Activation → Paid15-30%40-60%
Visit → Paid (overall)0.5-2%3-5%

[ORIGINAL DATA] These ranges are compiled from publicly shared benchmarks by Lenny Rachitsky, OpenView Partners, and ProfitWell across 2023-2024 SaaS industry analyses.

[IMAGE: Funnel visualization showing four steps with decreasing user counts — search: "conversion funnel diagram steps dropoff"]


Why Are GA4 Funnels So Painful?

GA4's funnel exploration reports require manual event configuration, can't run retroactively on historical data, and sample aggressively once you exceed 500K events. A 2024 Databox survey found that 67% of marketers find GA4 harder to use than Universal Analytics (Databox, 2024). Funnel setup is one of the biggest pain points.

Citation capsule: Google Analytics 4 funnel explorations require manual event configuration and cannot be applied retroactively to historical data. A 2024 Databox survey found 67% of marketers consider GA4 harder to use than Universal Analytics, with funnel setup complexity being a leading complaint among the 7,000+ respondents surveyed.

Event Configuration Is a Full-Time Job

In Universal Analytics, goals were simple — define a URL pattern or event category, and you're done. GA4 replaced this with a fully event-driven model. Every funnel step needs a custom event. Every custom event needs parameters. Every parameter needs registration in the GA4 admin panel before it shows up in reports.

Want a checkout funnel? You need to fire begin_checkout, add_shipping_info, add_payment_info, and purchase events — each with specific required parameters like currency, value, and items arrays. Miss one parameter and that step silently breaks.

Data Sampling Destroys Accuracy

GA4 applies thresholding and sampling to exploration reports when your dataset exceeds roughly 500K events. Google shows a small green, yellow, or red shield icon in the corner of the report to indicate data quality — but most users never notice it.

What does sampling mean in practice? Google takes a subset of your data and extrapolates. For a funnel where precision matters — where 3% vs 5% conversion is the difference between a viable business and a failed one — sampling makes the numbers unreliable. You're making decisions based on guesses, not data.

The 72-Hour Delay

GA4 exploration reports can take up to 72 hours to process data. Standard reports are faster (24-48 hours), but funnel explorations sit in the "exploration" category with lower processing priority.

Push a change to fix a checkout drop-off and you won't know if it worked until three days later. That feedback loop is too slow for iterative product work. Can you really afford to wait three days between experiments?

No Retroactive Funnels

In GA4, if you didn't configure the events before users triggered them, the data doesn't exist. You can't go back and create a funnel for events you weren't tracking. Universal Analytics had the same limitation, but it hurt less because event setup was simpler.

This forces you to predict which funnels you'll need before you have the data to know which ones matter. It's backwards. You should define a funnel after you notice a problem, not before.

[INTERNAL-LINK: privacy-first analytics alternatives → /blog/how-to-add-web-analytics-without-third-party-scripts]


What Data Model Do Conversion Funnels Need?

Building your own funnel system starts with one table: an events table with a user identifier, event name, timestamp, and optional properties. According to the 2024 Stack Overflow Developer Survey, PostgreSQL is used by 49% of professional developers (Stack Overflow, 2024), making it the most practical choice for a funnel backend.

Citation capsule: A conversion funnel system requires a single events table with user identifier, event name, timestamp, and optional properties. PostgreSQL — used by 49% of professional developers according to Stack Overflow's 2024 survey — provides the window functions and indexing needed to efficiently query multi-step funnel sequences from raw event data.

The Events Table

Here's the minimum schema:

CREATE TABLE events (
  id          BIGSERIAL PRIMARY KEY,
  user_id     TEXT NOT NULL,
  event_name  TEXT NOT NULL,
  timestamp   TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  properties  JSONB DEFAULT '{}'
);

CREATE INDEX idx_events_user_time
  ON events (user_id, timestamp);
CREATE INDEX idx_events_name
  ON events (event_name);

That user_id can be an authenticated user ID, an anonymous session token, or a fingerprint hash — whatever identifier you use to track a single person across steps. The properties column holds arbitrary metadata: page URL, plan name, referral source, anything you might want to filter on later.

The Funnel Query Logic

A funnel query answers one question: how many users completed step N within a time window after completing step N-1? The SQL pattern uses CTEs to order events per user, then filters for sequential completion.

Here's the core query for a three-step funnel (visit, signup, payment):

WITH step_1 AS (
  SELECT DISTINCT ON (user_id)
    user_id, timestamp AS step_1_at
  FROM events
  WHERE event_name = 'page_view'
    AND timestamp >= NOW() - INTERVAL '30 days'
  ORDER BY user_id, timestamp
),
step_2 AS (
  SELECT DISTINCT ON (s1.user_id)
    s1.user_id, e.timestamp AS step_2_at
  FROM step_1 s1
  JOIN events e ON e.user_id = s1.user_id
    AND e.event_name = 'signup'
    AND e.timestamp > s1.step_1_at
    AND e.timestamp < s1.step_1_at + INTERVAL '7 days'
  ORDER BY s1.user_id, e.timestamp
),
step_3 AS (
  SELECT DISTINCT ON (s2.user_id)
    s2.user_id, e.timestamp AS step_3_at
  FROM step_2 s2
  JOIN events e ON e.user_id = s2.user_id
    AND e.event_name = 'payment'
    AND e.timestamp > s2.step_2_at
    AND e.timestamp < s2.step_2_at + INTERVAL '30 days'
  ORDER BY s2.user_id, e.timestamp
)
SELECT
  (SELECT COUNT(*) FROM step_1) AS step_1_count,
  (SELECT COUNT(*) FROM step_2) AS step_2_count,
  (SELECT COUNT(*) FROM step_3) AS step_3_count;

Each CTE filters for users who completed the previous step and then completed the current step within a defined time window. The time window prevents counting a user who signed up a year ago and paid today as a single funnel conversion.

[UNIQUE INSIGHT] Most funnel implementations skip time-window constraints between steps. Without them, your funnel data becomes meaningless at scale — a user who visited in January and paid in December inflates your conversion rate even though they represent a completely different decision journey.

Why Time Windows Matter

Without time constraints, you're measuring "did this user ever do both things?" rather than "did this user progress through a coherent journey?" A 7-day window between visit and signup is reasonable. A 30-day window between signup and payment fits most SaaS trial periods.

Adjust these windows based on your sales cycle. B2B products with longer evaluation periods might need 60-90 day windows. Consumer products with impulse-buy patterns might use 24-hour windows.


How Do You Build a DIY Funnel System?

A working funnel system needs three components: an event tracking endpoint, storage in PostgreSQL, and a query layer that computes step-by-step conversion. Stripe's 2024 checkout benchmarks show that reducing checkout steps from 5 to 3 increases completion rates by 35% (Stripe, 2024) — proof that funnel analysis directly drives revenue decisions.

Citation capsule: Building a DIY funnel system requires three components: an event collection endpoint, PostgreSQL storage, and a query layer using SQL window functions. Stripe's 2024 checkout optimization data shows reducing checkout steps from 5 to 3 increases completion rates by 35%, demonstrating how funnel analysis directly translates to measurable revenue improvements.

Step 1: Event Collection Endpoint

Here's a minimal Express.js endpoint that accepts events:

const express = require('express');
const { Pool } = require('pg');

const pool = new Pool({
  connectionString: process.env.DATABASE_URL
});

const app = express();
app.use(express.json());

app.post('/api/events', async (req, res) => {
  const { user_id, event_name, properties } = req.body;

  if (!user_id || !event_name) {
    return res.status(400).json({ error: 'Missing required fields' });
  }

  await pool.query(
    `INSERT INTO events (user_id, event_name, properties)
     VALUES ($1, $2, $3)`,
    [user_id, event_name, JSON.stringify(properties || {})]
  );

  res.status(201).json({ ok: true });
});

app.listen(3001);

Keep this endpoint fast. Event tracking should never block the user experience. Insert and return immediately — do any enrichment (geolocation, device detection) asynchronously.

Step 2: Client-Side Event Firing

Track events from your frontend with simple fetch calls:

function trackEvent(eventName, properties = {}) {
  const userId = getUserId(); // from auth or anonymous cookie

  navigator.sendBeacon('/api/events', JSON.stringify({
    user_id: userId,
    event_name: eventName,
    properties
  }));
}

// Usage
trackEvent('page_view', { path: window.location.pathname });
trackEvent('signup', { method: 'github' });
trackEvent('onboarding_complete', { steps_skipped: 0 });
trackEvent('payment', { plan: 'pro', amount: 19 });

Using sendBeacon instead of fetch ensures the event fires even if the user navigates away. It's non-blocking and survives page transitions.

Step 3: Funnel Query Endpoint

Wrap the SQL from the previous section in an API endpoint:

app.post('/api/funnel', async (req, res) => {
  const { steps, window_days = 30 } = req.body;
  // steps: ['page_view', 'signup', 'payment']

  const ctes = steps.map((step, i) => {
    if (i === 0) {
      return `step_${i} AS (
        SELECT DISTINCT ON (user_id) user_id, timestamp AS t
        FROM events
        WHERE event_name = '${step}'
          AND timestamp >= NOW() - INTERVAL '${window_days} days'
        ORDER BY user_id, timestamp
      )`;
    }
    return `step_${i} AS (
      SELECT DISTINCT ON (s.user_id) s.user_id, e.timestamp AS t
      FROM step_${i - 1} s
      JOIN events e ON e.user_id = s.user_id
        AND e.event_name = '${step}'
        AND e.timestamp > s.t
        AND e.timestamp < s.t + INTERVAL '${window_days} days'
      ORDER BY s.user_id, e.timestamp
    )`;
  });

  const counts = steps.map((_, i) =>
    `(SELECT COUNT(*) FROM step_${i}) AS step_${i}_count`
  ).join(', ');

  const query = `WITH ${ctes.join(', ')} SELECT ${counts}`;

  const result = await pool.query(query);
  res.json(result.rows[0]);
});

Warning: This example concatenates user input into SQL for clarity. In production, use parameterized queries or a query builder to prevent SQL injection.

Step 4: Drop-Off Visualization

A funnel visualization doesn't need a charting library. Horizontal bars with CSS work fine to start:

<div class="funnel">
  <div class="step" style="width: 100%">
    <span>Page View: 10,000</span>
  </div>
  <div class="step" style="width: 12%">
    <span>Signup: 1,200 (12%)</span>
  </div>
  <div class="step" style="width: 4.8%">
    <span>Activation: 480 (40%)</span>
  </div>
  <div class="step" style="width: 1.4%">
    <span>Payment: 144 (30%)</span>
  </div>
</div>

[PERSONAL EXPERIENCE] We've found that showing the percentage relative to the previous step (not the first step) makes drop-off analysis more actionable. A "30% activation-to-payment" tells you more than a "1.4% overall conversion" when you're deciding what to fix next.

[CHART: Horizontal bar chart — funnel steps with decreasing widths showing visit (100%), signup (12%), activation (4.8%), payment (1.4%) — source: example data]


How Do You Compare Cohorts Inside a Funnel?

Cohort comparison reveals whether changes actually improve conversion — or just shift the numbers around. A 2024 report by Eppo found that companies running A/B tests on their onboarding funnels see a median 12% lift in activation rates compared to those optimizing without experiments (Eppo, 2024). Testing against cohorts is what separates opinion from evidence.

Citation capsule: Cohort comparison within funnels separates signal from noise in conversion optimization. Eppo's 2024 experimentation benchmark report found companies running A/B tests on onboarding funnels see a median 12% lift in activation rates, compared to teams optimizing without controlled experiments — demonstrating that cohort-based funnel analysis produces measurably better outcomes.

Splitting Funnels by Cohort

Add a cohort filter to your funnel query to compare groups. The most common splits are:

  • Time cohorts — users who signed up this week vs last week
  • Source cohorts — organic vs paid traffic
  • Feature cohorts — users who saw variant A vs variant B
  • Plan cohorts — free tier vs trial users

The SQL is the same funnel query with a WHERE clause on properties:

-- Compare funnel conversion for organic vs paid users
WITH step_1 AS (
  SELECT DISTINCT ON (user_id)
    user_id, timestamp AS step_1_at,
    properties->>'utm_source' AS source
  FROM events
  WHERE event_name = 'page_view'
    AND timestamp >= NOW() - INTERVAL '30 days'
  ORDER BY user_id, timestamp
),
-- ... remaining steps same as before ...
SELECT
  source,
  COUNT(*) FILTER (WHERE step >= 1) AS visited,
  COUNT(*) FILTER (WHERE step >= 2) AS signed_up,
  COUNT(*) FILTER (WHERE step >= 3) AS paid
FROM funnel_users
GROUP BY source;

Integrating A/B Tests with Funnels

If you're running A/B tests, store the variant assignment as an event property. When a user enters the experiment, fire an event like experiment_assigned with { experiment: 'onboarding_v2', variant: 'control' }. Then filter your funnel by that property.

This gives you something GA4 can't do natively — funnel conversion rates broken down by experiment variant, computed on raw unsampled data, available immediately. No waiting 72 hours. No data sampling. No separate experimentation tool.

[INTERNAL-LINK: preview environments for A/B testing → /blog/how-to-set-up-preview-environments-every-pull-request]


What Open-Source Funnel Tools Exist?

PostHog, Plausible, and Umami are the three main open-source analytics platforms, but they differ dramatically in funnel support. PostHog's 2024 community data reported 70,000+ deployments worldwide (PostHog, 2024), making it the most widely deployed open-source analytics tool — but also the heaviest.

Citation capsule: Among open-source analytics platforms, PostHog reports over 70,000 deployments globally and offers the most complete funnel analysis feature set. However, its infrastructure requirements — PostgreSQL, ClickHouse, Redis, Kafka, and a React frontend — make self-hosting significantly heavier than alternatives like Plausible or Umami that trade funnel depth for operational simplicity.

PostHog: Full Funnels, Heavy Infrastructure

PostHog is the closest open-source equivalent to Mixpanel or Amplitude. It offers multi-step funnels, funnel breakdowns by property, conversion time analysis, and correlation analysis to identify what properties predict conversion.

The catch? Self-hosting PostHog requires PostgreSQL, ClickHouse, Redis, Kafka, and the PostHog application itself. The recommended minimum is 8GB RAM and 4 CPU cores. That's a real server — not a $6/month VPS.

PostHog Cloud offers a generous free tier (1 million events/month), but then you're sending data to a third party again.

Plausible: Goals, Not Funnels

Plausible tracks goals — page visits and custom events that you define as conversions. You can see how many users completed each goal, but you can't build multi-step sequential funnels. There's no "show me users who did A, then B, then C in order."

Plausible's strength is simplicity. It runs on Elixir and ClickHouse, needs about 1GB of RAM self-hosted, and gives you clean dashboards with zero configuration. But if you need funnel analysis, it's the wrong tool.

Umami: Clean Analytics, No Funnels

Umami is a lightweight, privacy-focused analytics tool built on Node.js and PostgreSQL (or MySQL). It tracks page views, referrers, devices, and custom events. Like Plausible, it doesn't support sequential funnel analysis.

Umami runs on minimal resources — 512MB RAM is plenty. But funnel queries would need to be written manually against the raw events table.

How They Compare

FeaturePostHogPlausibleUmamiDIY (PostgreSQL)
Multi-step funnelsYesNoNoYes (manual SQL)
Funnel breakdownsYesNoNoYes (manual SQL)
Conversion time analysisYesNoNoYes (manual SQL)
Self-host RAM requirement8GB+1GB512MB256MB
Setup complexityHighMediumLowMedium
Custom event trackingYesYesYesYes
Retroactive funnelsYesN/AN/AYes

Is the operational overhead of PostHog worth it when funnels are all you need? For most small teams, probably not.

[INTERNAL-LINK: comparing self-hosted platform alternatives → /blog/temps-vs-coolify-vs-netlify]


Why Does First-Party Tracking Produce Better Funnel Data?

First-party analytics capture 30-40% more events than third-party scripts because ad blockers don't filter them. A 2024 study by Plausible found that sites running both GA4 and first-party analytics simultaneously saw 26-40% higher page view counts in the first-party tool (Plausible, 2024). That gap ripples through every funnel step.

Citation capsule: First-party analytics capture significantly more events than third-party tools because ad blockers don't intercept same-origin requests. Plausible's 2024 comparative study found sites running GA4 alongside first-party analytics recorded 26-40% higher page view counts in the first-party tool — a data accuracy gap that compounds through every step of a conversion funnel.

Ad Blockers Create Invisible Holes in Your Funnel

According to Backlinko, 42% of internet users run ad blockers (Backlinko, 2024). Among developer and tech audiences, that number climbs higher. Every one of those users is invisible to Google Analytics.

That's not a rounding error. If 42% of your top-of-funnel visitors are missing, your step-1 count is wrong. Every downstream conversion rate is calculated against a deflated denominator. Your real signup rate might be 3% when GA4 reports 5% — because GA4 never counted the blocked visitors.

Cookie Consent Reduces Your Data Further

Under GDPR, you need explicit consent before loading GA4. Cookie consent banners reduce opt-in rates to 30-50% in most implementations. Stack that on top of the 42% ad blocker rate, and GA4 might be capturing less than a third of your actual traffic in some European markets.

First-party analytics that don't use cookies skip this problem entirely. No cookies means no consent banner needed. No consent banner means no data loss from users who click "reject."

[PERSONAL EXPERIENCE] We've seen projects where switching from GA4 to first-party tracking nearly doubled the recorded event volume — not because traffic grew, but because events that were previously blocked or rejected started appearing in the data.

Privacy and Accuracy Aren't Tradeoffs

There's a persistent myth that privacy-friendly analytics sacrifice accuracy. The opposite is true. By avoiding cookies, third-party domains, and cross-origin tracking, first-party analytics sidestep the mechanisms that ad blockers and privacy regulations target. The result is more complete data, not less.


How Does Temps Handle Conversion Funnels?

Temps includes funnel analytics as part of its built-in observability layer — the same infrastructure that handles web analytics, session replay, and error tracking. Since Temps already stores every page view and custom event in TimescaleDB, funnels are a query on data you're already collecting. No additional setup, no separate analytics stack, no extra cost.

Citation capsule: Temps includes funnel analytics as part of its built-in observability layer, querying event data already stored in TimescaleDB. Unlike PostHog's 8GB+ RAM requirement for self-hosted funnel analysis, Temps runs funnel queries against its existing event store — the same infrastructure that handles deployments, web analytics, and error tracking — with no additional services to deploy.

[UNIQUE INSIGHT] The reason most deployment platforms don't include analytics is historical — hosting and analytics evolved as separate product categories. But they share the same infrastructure: an HTTP endpoint, a database, and a server. Combining them eliminates an entire class of integration work that developers accept as normal.

Defining Funnel Steps

In the Temps dashboard, you define funnel steps by selecting from events your application already tracks. No code changes required. Pick the events, set the time window, and the funnel renders immediately.

Because Temps stores raw events rather than pre-aggregated data, funnels are retroactive. Define a new funnel today and see conversion data from last month. This is the opposite of GA4's approach, where events must be configured before they occur.

Automatic Drop-Off Calculation

Temps calculates drop-off between each step and highlights the largest drop-off in the funnel. If your signup-to-activation rate is 18% while your activation-to-payment rate is 55%, Temps flags the signup-to-activation step as your bottleneck.

This seems obvious, but most analytics tools show you the numbers and leave the interpretation to you. When you're scanning ten different dashboards at the end of the day, having the worst step called out saves real time.

Combining Funnels with Session Replay

Here's where an integrated platform pays off. When you identify a drop-off — say, 60% of users abandon the onboarding step — you can watch session replays of users who dropped off at that exact step. You don't need to correlate IDs between Mixpanel and FullStory. It's the same system.

Did users rage-click on a broken button? Did they scroll past the CTA without seeing it? Did a JavaScript error crash the form? Session replay answers these questions in ways that funnel numbers alone never can.

[INTERNAL-LINK: session replay without FullStory → /blog/how-to-add-session-replay-without-fullstory]


FAQ

How many funnel steps should you track?

Keep funnels between 3 and 7 steps. Fewer than 3 doesn't give you enough resolution to find bottlenecks. More than 7 creates noise — every step adds a conversion rate to monitor, and the numbers get too small to be statistically meaningful. Stripe's checkout research shows that 3-step checkouts outperform 5-step ones by 35% (Stripe, 2024), which suggests simpler journeys convert better anyway.

[INTERNAL-LINK: optimizing user onboarding flows → /docs/getting-started]

Can you build funnels without user authentication?

Yes. Anonymous identifiers work — a random UUID stored in a first-party cookie or localStorage. The identifier just needs to persist across page views within a session. For cross-session funnels (visit today, sign up tomorrow), you need an identifier that survives browser restarts, which typically means a cookie with a 30-day expiry. Authenticated user IDs are more reliable, but anonymous tracking covers most funnel use cases.

What's a good conversion rate for SaaS funnels?

It depends on the step. Visit-to-signup rates of 2-5% are average; 8-12% is strong. Free-to-paid conversion rates average 5-7% for freemium models and 10-15% for free trial models, according to Lenny Rachitsky's analysis of 50+ SaaS companies (Lenny Rachitsky, 2024). Don't compare your overall funnel rate to someone else's — compare each step to its benchmark independently.

Do funnels work for mobile apps?

Yes. The same event-based model applies. Fire events from your mobile app to the same collection endpoint and run the same funnel queries. The key difference is session handling — mobile apps have background/foreground states rather than page navigations, so your "session start" event might be an app-open event rather than a page view. The funnel query logic stays identical.


Stop Guessing Where Users Drop Off

Conversion funnels aren't complicated. They're a sequence of counts: how many users did step one, how many of those did step two, and so on. The hard part has always been the tooling — GA4 makes it needlessly complex, and self-hosted alternatives either lack the feature or require a heavy infrastructure stack.

You have three realistic options. Build it yourself with PostgreSQL and the SQL patterns from this guide — it works and you own every piece. Use PostHog if you want a full-featured open-source analytics suite and don't mind the 8GB+ RAM requirement. Or use a deployment platform like Temps that includes funnel analytics alongside web analytics, session replay, and error tracking without adding another service to your stack.

The metric that matters isn't your overall conversion rate. It's the drop-off at your worst funnel step. Find that step, watch the session replays, fix the problem, and measure again. That loop — funnel, replay, fix, re-measure — is how you systematically grow revenue.

curl -fsSL https://temps.sh/install.sh | bash

[INTERNAL-LINK: deploy your first app with Temps → /docs/getting-started]

#analytics#conversion-funnels#google-analytics-alternative#privacy#first-party#conversion funnels without google analytics