Metric · HR

What is employee turnover rate, and how do you measure it in Metabase?

Employee turnover rate is departures divided by average headcount per period, usually annualized. It's the retention headline — but the headline is the least useful part; the splits (voluntary vs. involuntary, regrettable vs. not, first-year vs. tenured) carry all the meaning. Measure it in Metabase from HRIS data synced from BambooHR, Workday, or an ATS-adjacent system like Ashby.

TL;DRdepartures ÷ average headcount, annualized. Report voluntary and involuntary on separate lines, flag regrettable exits at offboarding, and segment by tenure — first-year turnover is a hiring problem wearing a retention costume. You need headcount snapshots: current-state HRIS syncs can't rebuild history.

What does an employee turnover rate chart look like in Metabase?

Plot annualized voluntary turnover by quarter — the voluntary line is the one management can act on. The gradual decline is retention work paying off, while a spike like Q2 2025's, landing right after a compensation cycle, points at pay-band gaps rather than a slow cultural slide.

Employee turnover rate in Metabase: a line chart of annualized voluntary turnover by quarter.
Employee turnover rate as a Metabase card, built from HRIS snapshot data. Figures are illustrative.

What turnover rate measures

It measures how fast the organization is losing people, normalized for size so a ten-person team and a thousand-person company can be read on the same scale. Annualizing makes periods comparable: 5% in a quarter is 20% annualized, which is the number leadership and benchmarks speak in.

The blended rate hides more than it shows. Voluntary and involuntary turnover have opposite root causes — one is people choosing to leave, the other is the company choosing — so they belong on separate lines. Within voluntary, regrettable attrition is the signal that matters: the departures you'd have paid to prevent. And segmentation does the diagnostic work — by team (a single manager can drive a company-wide uptick), by level, and by tenure, where a heavy first-year bucket points at hiring and onboarding rather than retention. Benchmark ranges vary so much by industry that the trend against your own history beats any external level.

What data does it need?

  • A headcount_snapshots table — headcount by date (and ideally by team and level), written on a schedule. This is the piece HRIS syncs don't give you: they mirror current state, and history can't be reconstructed later. Start the snapshot job before you need the metric.
  • A departures model with termination_date, termination_type (voluntary/involuntary), an is_regrettable flag captured at offboarding, and hire_date for tenure math.
  • Team, department, and level attributes on both tables, so rates segment cleanly.
  • HRIS or payroll data synced to your warehouse via Airbyte, Fivetran, or dlt.

SQL patterns

Quarterly annualized turnover, voluntary vs. involuntary PostgreSQL
WITH quarterly_headcount AS (
  SELECT
    date_trunc('quarter', snapshot_date) AS quarter,
    AVG(headcount) AS avg_headcount
  FROM headcount_snapshots
  GROUP BY 1
),
quarterly_departures AS (
  SELECT
    date_trunc('quarter', termination_date) AS quarter,
    COUNT(*) FILTER (WHERE termination_type = 'voluntary')
      AS voluntary,
    COUNT(*) FILTER (WHERE termination_type = 'involuntary')
      AS involuntary
  FROM departures
  GROUP BY 1
)
SELECT
  h.quarter,
  ROUND(h.avg_headcount)  AS avg_headcount,
  d.voluntary,
  d.involuntary,
  ROUND(
    400.0 * d.voluntary / NULLIF(h.avg_headcount, 0), 1
  ) AS voluntary_annualized_pct,
  ROUND(
    400.0 * (d.voluntary + d.involuntary)
    / NULLIF(h.avg_headcount, 0), 1
  ) AS total_annualized_pct
FROM quarterly_headcount h
JOIN quarterly_departures d USING (quarter)
ORDER BY h.quarter;
Departures by tenure bucket PostgreSQL
SELECT
  CASE
    WHEN termination_date - hire_date < 365  THEN '< 1 year'
    WHEN termination_date - hire_date < 730  THEN '1-2 years'
    WHEN termination_date - hire_date < 1460 THEN '2-4 years'
    ELSE '4+ years'
  END AS tenure_bucket,
  COUNT(*) AS departures,
  COUNT(*) FILTER (WHERE termination_type = 'voluntary')
    AS voluntary,
  COUNT(*) FILTER (WHERE is_regrettable) AS regrettable
FROM departures
WHERE termination_date >= CURRENT_DATE - INTERVAL '12 months'
GROUP BY 1
ORDER BY MIN(termination_date - hire_date);

Pitfalls

Blending voluntary and involuntary turnover. → A layoff quarter and a resignation-wave quarter can print the same number. They demand opposite responses, so keep them on separate lines and let the voluntary series carry the retention narrative.
Using point-in-time headcount as the denominator. → End-of-period headcount after a layoff inflates the rate; after a hiring spree it deflates it. Average headcount across the period — from snapshots, not from today's employee table.
Chasing industry benchmarks instead of your trend. → Published turnover benchmarks span single digits to over 50% depending on industry, geography, and role mix. The actionable signal is your own trajectory by segment, not distance from a survey average.
Skipping the regrettable flag at offboarding. → Without it, the departure of a top performer and a mutually-agreed exit are indistinguishable forever — the flag can't be backfilled honestly. Make it a required field in the exit workflow, set by the manager.

Where this metric applies

Metrics

Dashboards

FAQ

How do you calculate employee turnover rate?
Departures ÷ average headcount for the period, annualized so quarters are comparable: a quarterly rate times four, or monthly times twelve. Average headcount — not point-in-time — is the denominator, typically the mean of the period's start and end counts or of monthly snapshots. Report voluntary and involuntary separately; a quarter with a layoff and a quarter with a resignation wave produce the same blended number and mean completely different things.
What's a good employee turnover rate?
Benchmark ranges vary wildly by industry — low single digits in some sectors, over 50% annualized in retail and hospitality — so external comparisons mislead more than they inform. Your own trend is the signal: annualized voluntary turnover against your trailing eight quarters, segmented by team and tenure. A stable 18% may be fine; a move from 12% to 18% in two quarters is a fire. Track it on a people analytics dashboard next to headcount.
What is regrettable attrition?
The subset of voluntary departures you would have wanted to keep — strong performers, critical skills, people you'd rehire. It's the number that actually indicts management and compensation, because total turnover mixes it with departures you planned for or even welcomed. It requires an is_regrettable flag set at offboarding (usually by the manager or HRBP), so make that a required exit-process field. Pair it with time to fill to price what each regrettable exit costs in backfill time.
Why does first-year turnover deserve its own line?
Because it points at a different culprit. Someone leaving inside twelve months rarely reflects career growth or market pull — it reflects a hiring miss or an onboarding failure. A high first-year rate sends you back upstream to source quality, candidate conversion, and the onboarding program, not to retention perks. The tenure-bucket query below makes this segmentation a standing view.
How do you track turnover in Metabase?
Sync HRIS data from BambooHR, Workday, or your payroll system into a SQL database via Airbyte, Fivetran, or dlt — Metabase reads the database, not the HRIS API. The catch: most HRIS syncs mirror current state, and you cannot reconstruct last year's headcount from today's table. Start snapshotting headcount now (a scheduled job writing to headcount_snapshots), model departures with type and regrettable flags, and build the quarterly view from those two tables.