Buildern: Attribution, data models & account health scoring

Buildern had growth it couldn't explain. Datalyze rebuilt attribution and product tracking in PostHog, modelled their BigQuery data with dbt, and added a company-level health score, so the team can see which channels convert, what activation means, and which accounts are drifting toward churn.

Share

Buildern, a construction management platform for residential and commercial builders, could see its growth but not what was causing it. Datalyze rebuilt attribution and product tracking in PostHog, modelled their BigQuery data with dbt, and built a company-level health score that flags accounts drifting toward churn.


About Buildern

Buildern is a construction management platform for residential and commercial builders. It covers the full project lifecycle: pre-sales and lead tracking, estimating and takeoff, scheduling, budgets, invoicing, and a client portal that keeps homeowners in the loop. Builders run their whole operation inside it, from the first lead to the final invoice.

Challenge 1: Real growth, no view into what was driving it

Buildern came to us with a healthy business. Plenty of users, plenty of revenue, and a product people were paying for every month.

What they didn't have was any way to answer the questions that come next:

  • How are people actually using the product?
  • Where are they dropping off?
  • What should we fix first?
  • Which landing pages are bringing in users who convert?

There was no product analytics setup to answer any of it. There was no attribution either, which was the bigger problem. Almost every session was landing in Direct, because nothing carried campaign parameters. The blog, the marketing site, email sequences, in-app links, bids and invoices shared with homeowners: all of it arrived looking identical.

You can see the growth happening. You just can't see what is causing it, so you can't do more of it on purpose.

Solution: analytics and attribution rebuilt in PostHog

1. Set up PostHog end to end

We mapped the product before writing a single event. Then we built the instrumentation on top of that map:

  • A structured event taxonomy covering the real user journeys, not a list of clicks
  • Consistent properties across every event so segmentation actually works
  • Tracking across signup, activation, engagement, and the paths that matter to the business
  • Identity handled properly, so a user's actions tie together across sessions and surfaces

2. Built an attribution layer the team could maintain

The convention came first. Which source, medium, campaign, and content values are allowed, and how each one maps to a channel.

But a UTM convention that people have to remember is a convention people stop following. Within a few months the tagging drifts, and you end up with something that looks precise and is quietly wrong.

So we built a model that generates the parameters instead. You tell it where the link is going, an email sequence, a webview inside the app, a partner site, a paid campaign, and it hands back the correctly tagged URL. Nobody on the marketing team has to make a judgement call. The tagging stays consistent because consistency is not left to memory.

3. Separated real direct traffic from untagged traffic

We set up session stitching and first-touch attribution so a genuinely direct visit looks different from a mistagged campaign click, and so a user who finds Buildern through search and converts later on a different visit is credited correctly.

Result: every channel is now traceable to signup

Buildern can now see:

  • Which channels bring users who sign up, not just users who show up
  • Which landing pages pull people who go on to do something, and which ones pull people who leave
  • How traffic arriving on deep product surfaces behaves differently from traffic arriving on content

That last one matters more than it sounds. Product surfaces are a real entry point for a platform like Buildern, and until attribution was fixed those visits were invisible inside the Direct bucket.

On top of this, we gave the team a structure for running experiments and validating them properly. The measurement was the missing piece. Once the landing pages had honest numbers behind them, the team could test changes and read the result instead of guessing.


Challenge 2: A rich database nobody could ask a question of

Buildern's product generates a lot of data. Projects, bids, invoices, files, users, companies, all of it accumulating in BigQuery.

The problem was the shape. Raw application tables are built for running a product, not for answering questions about one. Every analysis meant reconstructing the same joins from scratch, and getting a slightly different answer each time.

Two things were missing. There was no clean company grain, which matters because Buildern is a B2B product where the account is the unit that pays and the unit that churns. And there was no clean picture of what a user actually does after they register.

Solution: dbt models over the BigQuery data

1. Modelled the raw data with dbt

We built a dbt layer on top of the warehouse, with models at both grains that mattered:

  • Company level. One row per account, carrying the activity, subscription state, and usage signals that describe how that company is doing.
  • User level. One row per user, with their actions rolled up in a way that makes journey and cohort analysis possible.

Defined once, tested, and documented, so every downstream number comes from the same definition.

2. Synced the models into PostHog

The modelled data flows back into PostHog, so the team is not switching between a warehouse and an analytics tool depending on the question. Behavioural data and modelled company data sit in the same place.

3. Analysed the trial period

With that in place we could finally look at the question underneath their conversion rate: what separates trial users who become paying customers from trial users who don't?

Three specific actions came out of it. Users who convert do them during the trial. Users who don't convert do them far less often.

Result: activation now has a definition

Activation now has a definition. That is a meaningful shift. "Improve trial to paid conversion" is a goal nobody can act on. "Get more trial users to do these three things in their first week" is a roadmap.

Onboarding, in-product prompts, and CS touchpoints all have something concrete to aim at.


Challenge 3: Customer success was finding out about churn too late

Knowing an account was in trouble depended on someone noticing. A quiet customer, a support ticket with an edge to it, or a cancellation email. By the time the signal arrived, the decision had usually already been made.

Solution: a company-level health score

We built a company-level health score on top of the dbt models.

It runs on real product activity rather than on a single proxy like login recency. Bids created, files added, invoices raised, and the other core actions that indicate a builder is running live work inside the platform, weighted and combined into one score per account.

The score is dynamic. It moves as a company's behaviour changes, so an account that goes quiet this month drops without anyone updating a spreadsheet. It also works in both directions: an account climbing the range is a candidate for expansion, not just a non-problem.

Result: customer success works from a ranked list

Customer success works from a ranked list instead of a hunch. Accounts drifting toward risk surface while there is still time to do something about it, and the team can prioritise by who actually needs attention rather than by who happened to email most recently.


Want this on your own stack?

Datalyze rebuilds your data foundation, then finds the growth it's been hiding — proven across 150+ startups.

Book a free analytics audit →