{
  "slug": "contractor",
  "label": "Contractor financial & operating benchmarks",
  "publisher": "Level",
  "publisher_url": "https://levelcfo.com",
  "dataset": "The Level Index, contractor financial & operating benchmarks",
  "attribution": "The Level founding team's analysis of 2,200+ contractors representing $13.25B in job revenue and 2.5M invoices, built across operating, private-equity, and CFO roles (financial reviews, operator interviews, and PE due-diligence), spanning HVAC, plumbing, electrical, mechanical, refrigeration, and fire protection, and layered with named public sources.",
  "methodology": "Figures are aggregated and anonymized. Distributions are reported as percentiles (p10/p25/median/p75/p90). No individual company is identified or identifiable. Per-metric sample sizes and definitions are attached to each metric.",
  "segments": [
    "HVAC",
    "plumbing",
    "electrical",
    "mechanical",
    "refrigeration",
    "fire protection"
  ],
  "last_updated": "2026-Q3",
  "date_range": "2022/2026",
  "license": "Free to cite with attribution to Level (levelcfo.com).",
  "metrics": [
    {
      "key": "service_agreement_gross_margin",
      "pillar": "Earnings",
      "label": "Service agreement gross margin",
      "unit": "percent",
      "n": 259,
      "definition": "Gross margin on recurring service-agreement (maintenance) revenue. n=259 companies with at least $10K in SA revenue.",
      "median": 37.9,
      "top_quartile": 53,
      "note": "Contractors below 25% are typically underpricing SAs or not capturing maintenance pull-through.",
      "basis": "contractors analyzed",
      "source": "The Level Index (contractor benchmark research)"
    },
    {
      "key": "collection_rate",
      "pillar": "Cash",
      "label": "Collection rate",
      "unit": "percent",
      "n": 464,
      "definition": "Cash collected as a share of billed revenue.",
      "p10": 38.8,
      "p25": 70.7,
      "median": 85.1,
      "p75": 92.7,
      "p90": 96,
      "target_range": [
        92,
        96
      ],
      "note": "The gap between 85% and 96% is real cash: on $5M of billings, ~$550K sitting uncollected.",
      "basis": "464 contractors analyzed",
      "source": "The Level Index (contractor benchmark research)",
      "external_corroboration": "Directionally consistent with CFMA 2024 Construction Financial Benchmarker (56.6 days in accounts receivable, n=1,290) and Levelset 2022 Construction Cash Flow Report (fewer than 40% of contractors paid within 30 days)."
    },
    {
      "key": "billing_speed_days",
      "pillar": "Cash",
      "label": "Billing speed (days from work complete to invoice)",
      "unit": "days",
      "n": 733,
      "definition": "Days from job completion to invoice issued. Median is 1 day when progress billing is included (~25% of companies); among post-completion invoicers the adjusted median is 7 days.",
      "median": 1,
      "median_post_completion": 7,
      "bottom_decile": 30,
      "lower_is_better": true,
      "source": "The Level Index (contractor benchmark research)"
    },
    {
      "key": "billing_capture",
      "pillar": "Cash",
      "label": "Billing capture rate (hours invoiced / hours logged on jobs)",
      "unit": "percent",
      "n": 963,
      "definition": "Total hours invoiced to customers divided by total hours LOGGED ON JOBS. The denominator is job-assigned hours only, which is why the median is high. This is NOT technician utilization: the industry utilization benchmark (65-80%) divides billable hours by TOTAL PAID hours, including drive time, admin, training, and idle time. Values above 100% occur where overtime hours bill at premium rates. n=963 companies with at least 100 logged hours.",
      "p10": 66.9,
      "p25": 89.2,
      "median": 97.1,
      "p75": 100,
      "p90": 102,
      "note": "State the denominator whenever this is cited. Without it the figure reads implausible, because readers compare it to utilization, which measures something else. First derived 2026-04-07 as 'billable hour ratio' (median 96.7%, n=654) and re-run to 97.1% on the larger n=963 cohort.",
      "basis": "companies with 100+ logged hours",
      "source": "The Level Index (contractor benchmark research)"
    },
    {
      "key": "quote_conversion_decided",
      "pillar": "Accounts",
      "label": "Quote conversion rate (on decided quotes)",
      "unit": "percent",
      "n": 794,
      "definition": "Won divided by (won + lost); excludes still-pending quotes. n=794 companies with at least 20 decided quotes. Distinct from all-quote conversion below.",
      "median": 73.9,
      "top_decile": 92,
      "note": "Quotes that sit >7 days convert at roughly half the rate of quotes sent within 24 hours.",
      "source": "The Level Index (contractor benchmark research)"
    },
    {
      "key": "quote_conversion_all",
      "pillar": "Accounts",
      "label": "Quote conversion rate (all quotes issued)",
      "unit": "percent",
      "n": 794,
      "definition": "Won divided by all quotes issued, including quotes that never reach a decision.",
      "p25": 28,
      "median": 38.1,
      "p75": 47.7,
      "note": "Roughly 62% of total quoting effort produces zero revenue.",
      "basis": "companies with 20+ quotes",
      "source": "The Level Index (contractor benchmark research)"
    },
    {
      "key": "days_to_convert",
      "pillar": "Accounts",
      "label": "Days to convert (winning quotes)",
      "unit": "days",
      "n": 794,
      "definition": "Days from quote sent to accepted, for quotes that convert.",
      "median": 2,
      "lower_is_better": true,
      "note": "Winning quotes close fast; speed-to-decision is the strongest leading indicator.",
      "source": "The Level Index (contractor benchmark research)"
    },
    {
      "key": "days_to_loss",
      "pillar": "Accounts",
      "label": "Days to loss (lost quotes)",
      "unit": "days",
      "n": 794,
      "definition": "Days from quote sent to marked lost, for quotes that do not convert.",
      "median": 29,
      "p90": 165,
      "note": "Half of lost quotes linger past 30 days before anyone marks them dead.",
      "source": "The Level Index (contractor benchmark research)"
    },
    {
      "key": "customer_concentration_top1",
      "pillar": "Risk",
      "label": "Revenue from largest single customer",
      "unit": "percent",
      "n": 959,
      "definition": "Share of total revenue from the top 1 customer. n=959 companies with at least $100K in annual revenue.",
      "p25": 18.5,
      "median": 31,
      "p75": 54.6,
      "p90": 82.4,
      "basis": "companies with >$100K revenue",
      "source": "The Level Index (contractor benchmark research)"
    },
    {
      "key": "job_gross_margin",
      "pillar": "Earnings",
      "label": "Job-level gross margin",
      "unit": "percent",
      "n": 1747089,
      "definition": "Gross margin per completed job (revenue minus actual cost), across all job types. Measured per JOB across 1,747,089 completed jobs from 1,791 companies (Athena verification 2026-07-25). The prior n=430 was another metric’s company count.",
      "p10": 10.8,
      "p25": 28.4,
      "median": 44.3,
      "p75": 60.2,
      "p90": 75.1,
      "pct_negative_margin": 6.2,
      "pct_under_20pct_margin": 16,
      "basis": "completed jobs analyzed",
      "source": "The Level Index (contractor benchmark research)"
    },
    {
      "key": "labor_hours_actual_vs_budget",
      "pillar": "Labor",
      "label": "Labor hours: actual as % of budgeted",
      "unit": "percent",
      "n": 315393,
      "definition": "Actual labor hours ÷ budgeted labor hours per job. 100% = on budget; >100% = over. Measured across 315,393 jobs from 1,391 companies (Athena verification 2026-07-25).",
      "p25": 70.1,
      "median": 99.4,
      "mean": 119,
      "p75": 131.1,
      "pct_over_budget": 40,
      "pct_over_150pct": 18.3,
      "note": "Median job lands on budget (99.4%) but the mean is 119%, dragged up by the ~18% of jobs that exceed 150% of budget. Labor-hour overruns are the single largest margin killer; 40% of jobs exceed their hour budget.",
      "basis": "jobs with both budgeted and actual hours",
      "source": "The Level Index (contractor benchmark research)"
    },
    {
      "key": "revenue_mix_labor_share",
      "pillar": "Labor",
      "label": "Labor share of quoted revenue",
      "unit": "percent",
      "n": null,
      "definition": "Labor as a share of quoted revenue (vs materials, equipment, subs). Median contractor is ~29% labor / ~33% materials, but variance is extreme. NOTE: sample size unverified. The prior n=430 was copied from another metric; this is measured on quoted revenue (quote-line data), not job_stats, so a job-level reproduction does not apply. Do not publish a sample size until re-derived.",
      "p25": 16.7,
      "median": 29.1,
      "p75": 42.2,
      "note": "Labor-heavy contractors run higher margins but hit capacity limits; materials-heavy run lower margins but scale better.",
      "basis": "quote line items (sample size unverified)",
      "source": "The Level Index (contractor benchmark research)"
    },
    {
      "key": "job_closeout_days",
      "pillar": "Cash",
      "label": "Job closeout lag (days)",
      "unit": "days",
      "n": 555,
      "definition": "Days from work complete to job financially closed out. Cash sits on the table while closeout lags.",
      "median": 1.7,
      "p75": 9.6,
      "p90": 35.8,
      "lower_is_better": true,
      "basis": "completed jobs",
      "source": "The Level Index (contractor benchmark research)"
    },
    {
      "key": "seasonality_top3_months",
      "pillar": "Risk",
      "label": "Revenue concentration in top 3 months",
      "unit": "percent",
      "n": 217,
      "definition": "Share of annual revenue earned in the three strongest months.",
      "p25": 38.3,
      "median": 47.4,
      "p75": 66.1,
      "p90": 91.1,
      "note": "The median contractor earns ~47% of annual revenue in just 3 months; Q4 (Dec/Oct) dominates peaks.",
      "basis": "companies with >$500K revenue",
      "source": "The Level Index (contractor benchmark research)"
    },
    {
      "key": "quote_line_margin_by_cost_type",
      "pillar": "Earnings",
      "label": "Quote-line gross margin by cost type",
      "unit": "percent",
      "n": 2200000,
      "definition": "Gross margin on quoted work, split by cost type (labor, materials, equipment, subcontractor), measured across 2.2M+ quote line items. Labor is the highest-margin cost type; subcontractor pass-through is the thinnest.",
      "by_cost_type": {
        "labor": 47.7,
        "materials": 31.5,
        "equipment": 25.5,
        "subcontractor": 23.6
      },
      "note": "Labor carries ~47.7% margin vs ~31.5% on materials, 25.5% on equipment, and 23.6% on subcontracted work. Revenue mix toward labor (service, maintenance) drives higher blended margin than equipment- or sub-heavy work.",
      "basis": "2.2M+ quote line items",
      "source": "The Level Index (contractor benchmark research)"
    },
    {
      "key": "bill_rate_by_role",
      "pillar": "Labor",
      "label": "Bill rate by role (rate-card field)",
      "unit": "usd_per_hour",
      "n": 18000,
      "definition": "Median rate-card rate by field role across 18,000+ tracked employees. The rate-card field is used inconsistently (some enter customer billing rates, others loaded cost or base wage), so read the spread between roles rather than the absolute level. Company-level avg bill rate median is $79/hr (n=1,770).",
      "by_role": {
        "helper": 34,
        "apprentice": 39,
        "technician": 54,
        "journeyman": 76,
        "mechanic": 75
      },
      "note": "The apprentice-to-journeyman jump (about $39 to $76) is the sharpest step in the ladder; journeymen carry the widest spread over loaded wage.",
      "basis": "18,000+ field employees with tracked rate-card data",
      "source": "The Level Index (contractor benchmark research)"
    }
  ],
  "revision_notes": {
    "note": "Forward-looking notes on how each figure below is derived and when its derivation was last sharpened. Every current value lives in metrics[] in this same file, which is the only authority for what a Level number is. This block never restates a superseded figure.",
    "as_of": "2026-07-26",
    "notes": [
      {
        "id": "collection_rate",
        "label": "Collection rate",
        "updated": "2026-07-16",
        "note": "Collection rate is measured as cash collected divided by billed revenue, per company, across 464 contractors. The cohort was widened and the sample frame tightened to companies with at least $100K invoiced and a full year of data. Read it as a point in time snapshot of what is sitting in accounts receivable, not as a permanent loss rate.",
        "metric_key": "collection_rate",
        "in_this_dataset": true
      },
      {
        "id": "billing_capture",
        "label": "Billing capture",
        "updated": "2026-07-26",
        "note": "Billing capture is now carried in the canonical dataset with its denominator stated on the record: hours invoiced divided by hours logged on jobs, across 963 companies with at least 100 logged hours. That denominator is what separates it from industry utilization, which divides by all paid hours including drive time, admin, and training. The two measure different things and are not comparable.",
        "metric_key": "billing_capture",
        "in_this_dataset": true
      },
      {
        "id": "labor_hours_actual_vs_budget",
        "label": "Labor hours against budget",
        "updated": "2026-07-26",
        "note": "Labor variance is measured per job, actual hours divided by budgeted hours, across 315,393 jobs from 1,391 companies, verified against the job level data on 2026-07-25. Jobs carrying no hour budget are excluded rather than assumed on target. The median and the mean are reported separately because they say different things: the median job lands on budget while a long tail runs well past it.",
        "metric_key": "labor_hours_actual_vs_budget",
        "in_this_dataset": true
      },
      {
        "id": "job_size_mix",
        "label": "Job size mix",
        "updated": "2026-07-26",
        "note": "Job size is reported by logged hour bucket across about 1.5M jobs carrying a dollar value, with each bucket's share of job count and its share of revenue stated separately. Reporting the two side by side is what makes the inversion legible: the buckets that fill the schedule are not the buckets that carry the dollars."
      },
      {
        "id": "labor_churn",
        "label": "Workforce churn",
        "updated": "2026-07-26",
        "note": "Workforce churn is measured from Bureau of Labor Statistics Job Openings and Labor Turnover Survey flows for the construction sector, with every series identifier named on the page so any figure can be pulled independently from BLS. BLS reports these flows for the industry and not by occupation, so this is the sector backdrop and the per role numbers to act on are your own."
      }
    ]
  }
}
