Back to Resources
Reference

Senzo Data Dictionary: How Every Workforce Measure Is Defined

A number a ministry, a board or a union can question line by line has to have a definition that can be produced on request. These are ours.

8 min read

By Rob Howie, Founder & CEO · Senzo · April 2026

Quick Answer

Senzo stores thirteen measures at unit × provider type × period and derives four rates from them after aggregation. Vacancy and vacant FTE are explicit source columns, never computed from positions minus headcount. Point-in-time measures are carried at period end; cumulative measures are summed; rates are always recomputed from components, never averaged.

Key Takeaways

  • Every measure has one definition, one source and one aggregation rule, set once at import and traceable to the source column
  • Vacancy is explicit, never derived; positions, people and FTE are three different numbers and are never used interchangeably
  • Rates are recomputed from summed components after aggregation, which is the only way a combined rate is correct

Health Workforce Canada's 2024 review of provincial modelling found that the first obstacle to comparable workforce planning across jurisdictions is not the models. It is definitions: what counts as a vacancy, what an FTE means, whether a transfer is a departure. Senzo publishes its definitions so that a partner's privacy officer, analyst or auditor can read them before a single extract is shared, and so that any figure on a Senzo screen can be traced back to a column in a source system.

Grain

Every record is one unit, one provider type and one period. Units belong to facilities, facilities to the organization; the hierarchy maps to how a health authority or health system reports upward. Provider types are the occupational groups the system plans by (RN, LPN, care aide, physician, and so on), set per organization. Period types are daily, weekly, monthly, quarterly and annual; the finest period present in an extract sets what can be rolled up.

Measures

MeasureDefinitionTypeUsual source
headcountPeople holding a position in the unit and provider type at period endPoint in timeHRIS position roster
positionsFunded positions in the unit and provider type at period endPoint in timeHRIS position control or budget
filled_fteFull-time equivalents attached to filled positionsPoint in timeHRIS; the extract's total FTE for filled positions
vacant_fteFull-time equivalents attached to vacant positionsPoint in timeHRIS vacancy report; explicit, never derived
total_ftefilled_fte + vacant_fteDerived at storage; cannot be writtenComputed
vacanciesCount of vacant positionsPoint in timeHRIS vacancy report; explicit, never derived
scheduled_hoursHours the roster planned for the periodCumulative over the periodScheduling system
worked_hoursHours worked by employees, excluding overtimeCumulativePayroll or timekeeping
ot_hoursHours worked beyond scheduled or contracted hours, at any premiumCumulativePayroll or timekeeping
agency_hoursHours worked by agency or contract staffCumulativePayroll, agency invoicing or scheduling
absence_hoursUnplanned hours away from scheduled work (sick, unplanned leave); planned vacation excludedCumulativeScheduling or attendance system
inflow_headcount / inflow_ftePeople and FTE arriving in the unit and provider type during the period: new hires, transfers in, returns from leave (subsets held separately)CumulativeHRIS movement or hire report
outflow_headcount / outflow_ftePeople and FTE leaving during the period: attrition, transfers out, going on leave (subsets held separately)CumulativeHRIS movement or termination report

Point in time measures describe the unit at period end and are carried, not summed, when a finer period is rolled up to a coarser one. Cumulative measures describe what happened during the period and are summed. Mixing the two is the most common error in hand-built workforce reports.

Rates

RateFormulaReads as
vacancy_ratevacant_fte ÷ (filled_fte + vacant_fte)Share of funded FTE that is unfilled. Never positions minus headcount.
ot_rateot_hours ÷ (worked_hours + ot_hours)Share of employee hours that were overtime. Agency hours excluded from both sides.
absence_rateabsence_hours ÷ scheduled_hoursShare of planned hours lost to unplanned absence.
agency_rateagency_hours ÷ (worked_hours + ot_hours + agency_hours)Share of all hours delivered by agency staff.

Rates are never stored as inputs and never averaged. They are recomputed from the summed components at whatever grain is being displayed.

What is deliberately not derived

Vacancy. Not positions minus headcount. A position can be filled by someone on leave, held at 0.6 FTE, or frozen. Vacancy and vacant FTE come from the system of record or the panel stays empty.

Turnover. Senzo publishes outflow and its subsets (attrition, transfers out, on leave) rather than a single turnover rate, because whether a transfer is a departure depends on whose question is being asked. A unit manager lost a nurse; the system did not.

Positions from people, or people from FTE. Three numbers, three meanings, never interchanged. Where a source publishes only one, the others are shown as not available rather than estimated.

Frequently asked questions

Why does Senzo not derive vacancy from positions minus headcount?

Because the two are not the same thing and the difference is where planning errors hide. A position can be filled by someone on leave, held by a 0.6 FTE, or frozen by finance. Health systems record vacancy explicitly in their HRIS for exactly this reason, and Senzo takes that figure as the source of truth. If an extract does not carry it, the vacancy panels stay empty rather than showing an invented number.

How are rates aggregated across units or periods?

They are not. Rates are recomputed from their components after the components are aggregated. Averaging a 10% overtime rate on 1,000 hours with a 50% rate on 10 hours gives 30%; the true combined rate is 10.5%. Senzo sums the hours, then divides.

What is the grain of every record?

Unit × provider type × period. Point-in-time measures (headcount, positions, FTE, vacancies) are taken at period end and carried, not summed, when rolling up. Cumulative measures (hours, flows) are summed. Period types are daily, weekly, monthly, quarterly and annual; the finest period present in an extract sets what can be rolled up.

Does Senzo count positions or people?

Both, separately, and never interchangeably. Headcount is people. Positions are funded seats. FTE is contracted time. A unit with 40 people, 44 positions and 36.5 filled FTE is described by all three numbers, and no one of them stands in for another.

How does this relate to CIHI's health workforce data standards?

Senzo's measures are chosen to map onto the categories a Canadian health authority already reports and onto the elements proposed for a pan-Canadian health human resources minimum data set: position, FTE, hours, movement. Where a jurisdiction's definition differs (for example what counts as an internal transfer), the mapping is set once at import and recorded, so a ministry submission can be traced to the source column.

These definitions are the ones a design partner signs up to in the data-sharing agreement, and the ones the programme validates against a partner's own extract before anything is published back.

Where this goes

The problems described here are what Senzo is being built to answer, with three design partners. If your system holds the data and has a live question, the programme is open.

Design partner programme