A full breakdown of revenue, cost, and margin across recurring, T&M, block hours, and fixed price contracts. Generated by AI via Proxuma Power BI MCP server.
A full breakdown of revenue, cost, and margin across recurring, T&M, block hours, and fixed price contracts. Generated by AI via Proxuma Power BI MCP server.
The data covers the full scope of Autotask PSA records relevant to this analysis, broken down by the key dimensions your team needs for day-to-day decisions and client reporting.
Who should use this: MSP owners, finance leads, and operations managers tracking profitability
How often: Monthly for financial reviews, quarterly for strategic planning, on-demand for pricing decisions
A full breakdown of revenue, cost, and margin across recurring, T&M, block hours, and fixed price contracts. Generated by AI via Proxuma Power BI MCP server.
EVALUATE
ROW(
"RecurringRevenue", SUMX(FILTER(BI_Autotask_Billing_Items, BI_Autotask_Billing_Items[contract_id] IN SELECTCOLUMNS(FILTER(BI_Autotask_Contracts, BI_Autotask_Contracts[contract_type_name] = "Recurring Service"), "cid", BI_Autotask_Contracts[contract_id])), BI_Autotask_Billing_Items[total_amount]),
"TMRevenue", SUMX(FILTER(BI_Autotask_Billing_Items, BI_Autotask_Billing_Items[contract_id] IN SELECTCOLUMNS(FILTER(BI_Autotask_Contracts, BI_Autotask_Contracts[contract_type_name] = "Time & Materials"), "cid", BI_Autotask_Contracts[contract_id])), BI_Autotask_Billing_Items[total_amount]),
"BlockRevenue", SUMX(FILTER(BI_Autotask_Billing_Items, BI_Autotask_Billing_Items[contract_id] IN SELECTCOLUMNS(FILTER(BI_Autotask_Contracts, BI_Autotask_Contracts[contract_type_name] = "Block Hours"), "cid", BI_Autotask_Contracts[contract_id])), BI_Autotask_Billing_Items[total_amount])
)
Total revenue, cost, and margin for each contract type, ranked by revenue
| # | Contract Type | Contracts | Revenue | % of Total |
|---|---|---|---|---|
| 1 | Recurring Service | 1,207 | $15,724,070 | 89.3% |
| 2 | Time & Materials | 504 | $1,840,111 | 10.5% |
| 3 | Block Hours | 173 | $7,502 | 0.0% |
| 4 | Fixed Price | 5 | $17,210 | 0.1% |
| 5 | Unassigned / Other | — | $17,876 | 0.1% |
EVALUATE VAR RecurringIds = CALCULATETABLE(VALUES('BI_Autotask_Contracts'[contract_id]), 'BI_Autotask_Contracts'[contract_type_name] = "Recurring Service") VAR TMIds = CALCULATETABLE(VALUES('BI_Autotask_Contracts'[contract_id]), 'BI_Autotask_Contracts'[contract_type_name] = "Time & Materials") VAR BlockIds = CALCULATETABLE(VALUES('BI_Autotask_Contracts'[contract_id]), 'BI_Autotask_Contracts'[contract_type_name] = "Block Hours") VAR FixedIds = CALCULATETABLE(VALUES('BI_Autotask_Contracts'[contract_id]), 'BI_Autotask_Contracts'[contract_type_name] = "Fixed Price") RETURN ROW("Recurring", CALCULATE(SUM('BI_Autotask_Billing_Items'[total_amount]), TREATAS(RecurringIds, 'BI_Autotask_Billing_Items'[contract_id])), "TimeMaterials", CALCULATE(SUM('BI_Autotask_Billing_Items'[total_amount]), TREATAS(TMIds, 'BI_Autotask_Billing_Items'[contract_id])), "BlockHours", CALCULATE(SUM('BI_Autotask_Billing_Items'[total_amount]), TREATAS(BlockIds, 'BI_Autotask_Billing_Items'[contract_id])), "FixedPrice", CALCULATE(SUM('BI_Autotask_Billing_Items'[total_amount]), TREATAS(FixedIds, 'BI_Autotask_Billing_Items'[contract_id])), "Total", SUM('BI_Autotask_Billing_Items'[total_amount]))
Number of contracts per type and how many are currently active. Inactive contracts may represent churn or completed projects.
| Contract Type | Total Contracts | Active | Inactive | Active Rate | Status |
|---|---|---|---|---|---|
| Recurring Service | 1,207 | 932 | 275 | 77.2% | Healthy |
| Time & Materials | 504 | 287 | 217 | 56.9% | Watch |
| Block Hours | 173 | 158 | 15 | 91.3% | Healthy |
| Fixed Price | 5 | 0 | 5 | 0% | All Closed |
EVALUATE
ADDCOLUMNS(
VALUES(BI_Autotask_Contracts[contract_type_name]),
"Contracts", CALCULATE(DISTINCTCOUNT(BI_Autotask_Contracts[contract_id])),
"Active", CALCULATE(
DISTINCTCOUNT(BI_Autotask_Contracts[contract_id]),
BI_Autotask_Contracts[contract_status_name] = "Active"
)
)
Billing items grouped by sub-type. This shows what you are actually billing for within each contract: recurring fees, milestones, materials, or time entries.
| Billing Sub-Type | Revenue | Cost | Margin | Share of Total |
|---|---|---|---|---|
| Recurring Service | $9,577,503 | $4,025,063 | 58.0% | |
| Milestone | $3,845,490 | $0 | 100% | |
| Product / Material | $2,644,523 | $2,483,170 | 6.1% | |
| Block Hours Deduction | $917,546 | $453,912 | 50.5% | |
| Time Entry | $273,878 | $1,207,179 | -341% | |
| Expense | $225,026 | $173,409 | 23.0% |
EVALUATE
ADDCOLUMNS(
VALUES(BI_Autotask_Billing_Items[sub_type]),
"Revenue", CALCULATE(SUM(BI_Autotask_Billing_Items[total_amount])),
"Cost", CALCULATE(SUM(BI_Autotask_Billing_Items[internal_cost]))
)
ORDER BY [Revenue] DESC
Gross margin percentage for each contract type. Higher margins indicate better profitability per dollar of revenue.
The revenue mix is heavily weighted toward recurring contracts. 89.3% of total revenue ($15.72M) comes from Recurring Service agreements. That is a strong foundation for predictable cash flow and business valuation. The 55% margin on recurring revenue is solid for an MSP of this size.
Time and Materials brings in $1.84M (10.5%), but at a lower margin of 36.7%. With 504 total T&M contracts and only 287 active, there is significant churn or project completion in this category. The 43% inactive rate on T&M contracts suggests either one-off projects that completed or clients who moved away from hourly billing.
The billing sub-type data reveals an important detail: Time Entry billing items show a negative margin of -341%. Revenue from time entries is $273K against $1.21M in cost. This means labor logged under time entries is being delivered at a severe loss. That cost is likely absorbed by the margin on recurring and milestone billing, but it deserves attention. Either time entry rates need to increase, or the hours being logged under this sub-type are miscategorized.
Product and Material billing brings in $2.64M but carries only a 6.1% margin. At $2.48M in cost against $2.64M in revenue, hardware and product resale is close to break-even. That is typical for MSPs who pass through hardware costs, but it means this $2.6M in revenue contributes almost nothing to profit.
Milestone billing at $3.85M with zero cost allocated is either project-based work with costs tracked elsewhere, or implementation fees that represent pure margin. Either way, it is the second-largest revenue category and worth understanding what drives it.
Block Hours generates minimal revenue ($7.5K) despite 173 contracts and 158 active. This suggests most block hour contracts are either very small or that the billing method is being phased out in favor of recurring agreements. The 91.3% active rate is the highest of any contract type.
5 priorities based on the findings above
Time Entry sub-type shows $273K in revenue against $1.21M in cost. That is a $933K loss on one billing category. Pull the specific contracts and billing items tagged as Time Entry. Check if the hourly rates are set correctly, if the wrong cost codes are being applied, or if technicians are logging hours to the wrong billing type. This is the single biggest margin leak in the data.
T&M contracts carry a 36.7% margin vs. 55% on recurring. With 287 active T&M contracts, identify the ones with consistent monthly billing over the last 6 months. Clients who spend predictable amounts on T&M are prime candidates for a recurring agreement. Converting even 10% of T&M revenue to recurring would add $184K to annual revenue at a higher margin.
At 6.1% margin on $2.64M in revenue, your hardware and product resale is barely above cost. Industry standard for MSPs is 15-25% markup on hardware. Check your pricing sheets and procurement processes. Even a 5-point margin improvement on this category would add $132K in annual profit.
$3.85M with zero allocated cost is either a data gap or a very profitable category. Determine whether this represents project implementation fees, setup charges, or one-time contract milestones. If costs are tracked in a different system, link them. If this truly is zero-cost revenue, make sure the pricing model that generates it is applied consistently across new client onboarding.
An 89.3% recurring revenue share is well above the MSP benchmark of 70-80%. This gives you strong cash flow predictability and a higher business valuation multiple. As you grow, keep this ratio above 85% by ensuring new clients start on recurring agreements and by actively converting T&M relationships to managed contracts.
Revenue data comes from the BI_Autotask_Billing_Items table in Proxuma Power BI, which syncs with your Autotask PSA billing records. Each billing item is linked to a contract via contract_id, and the contract's type (Recurring, T&M, Block Hours, Fixed Price) comes from the BI_Autotask_Contracts table. The AI joins these tables using DAX queries to calculate revenue per contract type.
Contract type is the high-level classification in Autotask: Recurring Service, Time & Materials, Block Hours, or Fixed Price. Billing sub-type describes what specifically is being billed within that contract: recurring service fees, milestone payments, product/material charges, time entries, or expenses. A single Recurring Service contract can generate billing items across multiple sub-types.
Cost data in Autotask billing items depends on how your PSA is configured. Fixed Price contracts may show zero cost if internal costs are tracked in a different system or not allocated to billing items. Milestone sub-types often show zero cost because implementation labor is tracked separately. Check your Autotask cost allocation settings if you expect costs to appear.
Industry benchmarks suggest that well-run MSPs derive 70-80% of revenue from recurring contracts. Above 85% is considered excellent and typically commands a higher valuation multiple (6-8x EBITDA vs. 4-5x for MSPs with heavy T&M revenue). The 89.3% in this report is well above the benchmark.
Yes. Add a date filter to the DAX queries using the billing item date column. For example, filter on BI_Autotask_Billing_Items[item_date] to restrict results to a specific quarter or fiscal year. This is useful for tracking how your revenue mix changes over time.
Yes. Connect Proxuma Power BI to your Autotask PSA, add an AI tool (Claude, ChatGPT, or Copilot) via MCP, and ask the same question. The AI writes the DAX queries, runs them against your real data, and produces a report like this in under fifteen minutes.
Connect Proxuma Power BI to your PSA, RMM, and M365 environment, use an MCP-compatible AI to ask questions, and generate custom reports - in minutes, not days.
See more reports Get started