Skip to content

Define custom metrics

A custom metric is a column you create yourself with a small formula over any metric field. ROAS by platform, cost per customer and CPM are common examples.

6-min read, last updated 31 October 2026

What custom metrics are

Crowflow ships with four base metrics (impressions, clicks, conversions, spend) and four derived ones (CTR, CR, CPC, CPA) on every row. Custom metrics let you add your own derived columns by writing a formula.

Custom metrics are available on Starter, Pro and Agency. The built-in derived columns (CTR, CR, CPC, CPA) are on every plan, including Free.

Manage them at /app/settings/metrics. Each metric has a name (the column header), a formula, an output format, and an optional description.

Fields you can use

Any metric field. Built-in metrics by name: impressions, clicks, conversions, spend, ctr, cr, cpc, cpa, leads, costPerLead, deals, revenue, leadRevenue, roas, leadRoas. Everything else in square brackets, using the field key shown in the editor: a lifecycle stage such as [stage:customer], or a HubSpot property column such as [hsprop:contacts:hs_lead_status=NEW]. Custom metrics cannot reference other custom metrics.

Note:
Legacy alias: results still works as a variable name and refers to the same value as conversions. Older formulas you wrote when the column was called Results keep working untouched. Use either name in new formulas.

Operators & syntax

Five operators plus parentheses for grouping:

  • + addition
  • - subtraction (and unary negation)
  • * multiplication
  • / division
  • ( ) grouping

You can also use numeric literals (integers and decimals):

(spend / impressions) * 1000

No function calls (min(), max(), if()), no string operations. For conditional logic see Conditions below.

Conditions

Add where after a field to count only part of the data: spend where platform = "Google Ads". Dimensions: platform, account, campaign. Operators: =, != and contains. Matching ignores case. Platforms match by name (Google Ads) or key (GOOGLE_ADS).

A condition binds to the field just before it; wrap a group in parentheses to apply one condition to all of it: (spend / clicks) where platform = "Meta Ads". Conditions are computed from the rows inside each period, so a conditional CPC is spend on that platform divided by clicks on that platform, never an average.

CRM figures attribute to a platform and a campaign, not to an account, so leads where account = "Acme" is 0 and leads where account != "Acme" counts every lead.

Output formats

Pick how the computed value renders in the dashboard:

  • Number: a plain decimal. e.g. 3.45. Sensible for ratios like ROAS, view-through rates, etc.
  • Percentage: appends a % suffix. e.g. 2.34%. Use for any rate-style metric.
  • Currency: prefixes the row’s currency symbol. e.g. £12.34. Use for spend-derived metrics like CPM.
Note:
The dashboard uses each row’s own currency when rendering CURRENCY-format metrics. A USD row and a GBP row in the same table show their custom metric prefixed correctly per row.

Examples to copy

The Settings Custom metrics page has six quick-start examples you can apply with one click. Here they are with context:

Cost per conversion
spend / conversions
Format: Currency
Spend divided by the number of conversions: your cost per acquisition. (Identical to the built-in CPA column; defining it as a custom metric lets you give it a different name or format.)
CPM
(spend / impressions) * 1000
Format: Currency
Cost per thousand impressions.
Estimated ROAS
(conversions * 25) / spend
Format: Number
Return on ad spend assuming each conversion is worth £25 to your business. Edit the 25 to your actual average order value.
Cost per 100 conversions
(spend / conversions) * 100
Format: Currency
Useful when conversions are cheap and the per-unit number is hard to read.
Google Ads CPA
spend where platform = "Google Ads" / conversions where platform = "Google Ads"
Format: Currency
Cost per conversion on Google Ads only: both sides of the division are filtered to the same platform, so the ratio is Google's own, not an average across platforms.
Customers from leads
[stage:customer] / leads * 100
Format: Percent
Of the leads acquired in the period, the share who are customers now. Offered in the editor when HubSpot is connected and a contact has reached that stage.
Note:
A note on ROAS. True ROAS is revenue / spend. With HubSpot connected on Pro or Agency, Crowflow has deal revenue: the built-in ROAS and Lead ROAS columns use it, and so does revenue in a formula. Without a CRM connection the ad platforms report only the count of conversions. If your conversions have a consistent value (£25/lead, £80/purchase), multiply conversions by that value to get estimated revenue, then divide by spend. If your values vary a lot, ROAS computed this way will be wrong; consider tracking revenue in your Sheet manually.

Note: Conversion rate ((conversions / clicks) × 100) is now a built-in column called CR; you don’t need to define it as a custom metric.

Other ideas worth defining:

Clicks per impression (raw)
clicks / impressions
Format: Number
Same as CTR but expressed as a 0 to 1 ratio rather than a percentage.
CPC goal delta
spend - (clicks * 0.50)
Format: Currency
How far over (positive) or under (negative) you ran vs a £0.50 CPC target.
Estimated profit at target margin
(conversions * 25) - spend
Format: Currency
Same assumption as Estimated ROAS: gross profit if each conversion is worth £25.

Using them in the dashboard

Every custom metric appears as a column in the dashboard table, alongside the built-in columns. It’s:

  • Sortable: click the column header.
  • Toggleable: show or hide via the Columns dropdown.
  • Re-computed for every Group by: daily grain, weekly, monthly, yearly. The math is correct at each level (see Rollup below).

The Columns dropdown groups custom metrics under their own “Custom metrics” sub-heading. There’s also a “+ Custom metric” shortcut in the dropdown so you can jump straight to Settings to add a new one.

Using them in Sheet exports

Custom metrics work in the customise export UI too. In Customise export, type the metric's name into Add a field and it joins the end of the column list; the arrows on its chip move it.

If you delete a custom metric that’s still referenced by a destination’s export, the column header in the Sheet reads “(deleted metric)” and the cells render empty. Open Customise export and untick the stale reference to clean up.

How rollups work

Custom metrics roll up the same way the built-in rate metrics do: derived from the summed base totals, not averaged from per-row rates.

For Cost per conversion at the dashboard’s totals strip:

Cost_per_conversion_total = sum(spend) / sum(conversions)
NOT average of per-row cost-per-conversion values

If you switch Group by from Day to Month, your custom column shows the metric for each month (sum of spend in the month divided by sum of conversions, etc.), not the average of the 30 daily values.

Common formula errors

The Create / Edit form shows a live “ Valid” or “Invalid: <reason>” under the formula field as you type. Common reasons a formula is rejected:

  • “unknown field”: you typed a name that is not a built-in metric. Check spelling (names are case-insensitive), or put a field key in square brackets.
  • “unknown dimension”: the word after where must be platform, account or campaign.
  • “expected a quoted value”: the value in a condition goes in double quotes, like "Google Ads".
  • “is not available in this workspace”: the field exists but your plan or connections do not include it, for example a CRM field without a connected HubSpot account.
  • “expected closing ‘)’”: unbalanced parentheses.
  • “unexpected end of formula”: you stopped mid-expression, e.g. spend /
  • “extra tokens after end of expression”: usually a stray ) or punctuation after a valid sub-expression.
  • “formula is empty”: you cleared the field. Save is blocked.
  • “a metric named X already exists”: names are unique per workspace; pick a different one.
Note:
Division by zero returns 0. If your formula divides by a variable that happens to be zero for some rows (e.g. a campaign with no clicks dividing by clicks), the cell shows 0 rather than NaN or ∞. Same rule the built-in CPC and CPA use.

What the parser does & doesn’t allow

The formula engine is a small recursive-descent parser written specifically for Crowflow. It has no JavaScript interop, no eval(), no function calls. The only things it can do are:

  • Read any metric field
  • Filter by platform, account or campaign
  • Add, subtract, multiply, divide
  • Group with parentheses
  • Use numeric literals

A malformed or malicious input throws a FormulaError at parse time; it never executes. If you have a use case that needs more (date functions, conditional logic), email hello@crowflow.io and we’ll talk through whether a different feature is the right shape.

Related help