Expand description
§Cost and Unit Economics of Engineering
Engineering cost has at least three distinct components with different drivers and different levers: people cost (salaries and benefits, largely fixed in the short term), infrastructure cost (cloud spend, largely variable with usage), and tooling and licensing cost (often fixed per-seat or per-usage-tier). Tracking them separately, rather than as one blended total, matters because a rising total driven by infrastructure scaling with genuine growth calls for a very different response than the same rise driven by unmanaged tooling sprawl. Dividing the total by a genuine unit of value delivered — cost per customer served, per transaction, per deployment — turns that total into a trackable, comparable trend.
§Formula
Total engineering cost = people cost + infrastructure cost + tooling cost
Unit cost = total cost / units delivered§Why it matters
Selecting a unit that genuinely tracks business or mission value, rather than an easily inflated, internal, largely discretionary count, is what keeps a unit-cost ratio honest. A single unit-cost snapshot is also less useful than its trend: falling unit cost as the platform matures signals genuine efficiency gains, while rising unit cost is often a direct, measurable consequence of accumulated technical debt or complexity hotspots elsewhere in the codebase.
§Example
use software_engineering::unit_economics::{total_engineering_cost, unit_cost};
// $500k people cost, $120k infrastructure, $30k tooling, serving 10,000
// customers.
let total = total_engineering_cost(500_000.0, 120_000.0, 30_000.0);
assert_eq!(total, 650_000.0);
let cost_per_customer = unit_cost(total, 10_000.0).unwrap();
assert_eq!(cost_per_customer, 65.0);§Money
total_engineering_cost and unit_cost take plain f64 amounts.
For currency-checked accounting, use rusty_money::Money directly
rather than through a wrapper this crate provides — its own add/div
already return Result, rejecting cost components quoted in different
currencies instead of silently treating them as the same unit:
use rusty_money::{Money, iso};
use software_engineering::unit_economics::unit_cost;
let people = Money::from_major(500_000, iso::USD);
let infrastructure = Money::from_major(120_000, iso::USD);
let tooling = Money::from_major(30_000, iso::USD);
let total = people.add(infrastructure).unwrap().add(tooling).unwrap();
assert_eq!(total, Money::from_major(650_000, iso::USD));
let cost_per_customer = unit_cost(total.to_f64_lossy(), 10_000.0).unwrap();
assert!((cost_per_customer - 65.0).abs() < 1e-9);
// Dividing by zero units is rejected rather than producing infinity.
assert!(total.div(0).is_err());§Pitfalls
- Choosing an easily inflated denominator that does not correspond to any genuine external unit of value delivered — flatters the ratio without informing anyone.
- Tracking one blended cost total instead of separating people, infrastructure, and tooling cost — hides which lever actually needs pulling when the total rises.
- Reporting a unit-cost snapshot with no trend — a single number says nothing about whether efficiency is improving or degrading.
- Never connecting rising unit cost back to technical debt or complexity metrics — misses a measurable, quantifiable case for debt remediation investment.
§Sources
- Chapter 5.4, Cost and unit economics of engineering.
FinOpsFoundation,FinOpsFramework.
Topic doc: software-engineering-metrics/locales/en-001/chapters/05-04-cost-and-unit-economics-of-engineering.md
Functions§
- total_
engineering_ cost - The sum of engineering’s three distinct cost components.
- unit_
cost - Cost per genuine unit of value delivered, such as cost per customer served, per transaction, or per deployment.