What is time to hire, and how do you measure it in Metabase?
Time to hire is an HR and recruiting metric you can track in Metabase once ATS or HRIS data is synced into a database. Time to hire measures how long a candidate takes to move from entering your recruiting process to accepting an offer. It is a candidate or application lifecycle metric, not a requisition lifecycle metric.
What does a time to hire chart look like in Metabase?
Track the median days from application to accepted offer for each month's accepted offers — the median, because a few long searches skew any average. The steady decline reflects a tightening process, while a spike like Mar 2026's usually means a batch of senior searches concluded at once, not that recruiting suddenly slowed.
How is time to hire defined?
- Typical definition: application_created_at to offer_accepted_at.
- Alternative definition: first candidate contact to offer accepted, if sourcing starts before application.
- Report median and p90 because hiring duration is right-skewed.
- Segment by role family, seniority, department, source, recruiter, and location when safe.
What data does it need?
- Applications with candidate, job, source, recruiter, and application_created_at.
- Offers with offer_extended_at and offer_accepted_at.
- Stage history when you want to break time to hire into process steps.
- Role attributes such as department, location, level, and hiring manager.
SQL pattern
SELECT
date_trunc('month', offer_accepted_at) AS month,
COUNT(*) AS accepted_offers,
percentile_cont(0.5) WITHIN GROUP (
ORDER BY EXTRACT(EPOCH FROM (offer_accepted_at - application_created_at)) / 86400.0
) AS median_time_to_hire_days,
percentile_cont(0.9) WITHIN GROUP (
ORDER BY EXTRACT(EPOCH FROM (offer_accepted_at - application_created_at)) / 86400.0
) AS p90_time_to_hire_days
FROM modeled_applications
WHERE offer_accepted_at IS NOT NULL
GROUP BY 1
ORDER BY 1;