Free resource
Free FOCUS analysis exercise: dataset, SQL and findings memo
A downloadable synthetic multi-cloud FOCUS dataset, five SQL questions with explained solutions you can run in DuckDB, and an example findings memo. No email required.
By Adam Morad · Reviewed October 1, 2026 · Dataset uses FOCUS 1.2 column names · SQL dialect: DuckDB (run on v1.5.3)
Key points
- ✓A free, synthetic FOCUS dataset (4,433 rows, AWS, Azure and Google Cloud, Q3 2026) with DuckDB SQL for five analysis questions and explained solutions. No email required. Details
- ✓It practises commitment reconciliation, anomaly detection with a trailing baseline, and cost per 1,000 orders on EffectiveCost. Details
- ✓Comparing provider totals shows where money goes, not which provider is cheaper. Details
- ✓The SQL ends with 20 self-checks that assert FOCUS rules hold in the data. Details
Download (no email needed)
A 1.8 MB CSV of 4,433 synthetic FOCUS rows for a fictional company, a daily orders file, the SQL with solutions and 20 self-checks, and a README covering provenance, assumptions and limitations. License: CC BY 4.0.
What is in the data
Northwind Analytics is a fictional company. Every row was generated by a script in this site’s repository; nothing comes from a real bill or a real customer. It covers July 1 to September 30, 2026, on three providers, written to follow FOCUS rules so the numbers reconcile exactly:
- AWS: a one-year, all-upfront Savings Plan bought on July 1, a fleet that is partly retired on August 15, and a five-day cost spike hidden in September.
- Microsoft: a no-upfront reservation billed as a monthly Purchase row, plus on-demand usage.
- Google Cloud: no Purchase rows and no CommitmentDiscountStatus, with committed-use discounts in
x_Credits, as Google’s FOCUS export documents. In this file Google’s BilledCost is shown before credits so the credit is visible; that is a simplification, so check Google’s documentation before relying on it for a real export.
To run it: install DuckDB, unzip, and run duckdb < exercise.sql in that folder. Try each question yourself before reading the solution.
Q1. Does BilledCost or EffectiveCost describe the quarter?
-- Q1. Sanity check: BilledCost vs EffectiveCost by ChargeCategory for the quarter
-- Why they differ:
-- * Purchase: BilledCost is the cash invoiced for commitments (the AWS
-- all-upfront Savings Plan and the monthly Azure reservation payments).
-- EffectiveCost is 0 on these rows because FOCUS spreads that cost onto
-- the usage the commitment covers.
-- * Usage: covered usage has BilledCost 0 and EffectiveCost = the amortized
-- commitment amount, and Unused commitment rows add EffectiveCost with no
-- BilledCost, so Usage EffectiveCost is higher than Usage BilledCost.
-- Google rows go the other way in this dataset: BilledCost is gross and
-- EffectiveCost nets the negative x_Credits.
-- * Tax, Credit, Adjustment: EffectiveCost equals BilledCost.
-- * Over the quarter BilledCost is higher overall because the AWS upfront
-- payment covers 365 days but only 92 days have been recognized.
-- @result Q1
SELECT ChargeCategory, row_count, billed_cost, effective_cost, billed_minus_effective
FROM (
SELECT
0 AS sort_key,
ChargeCategory,
count(*) AS row_count,
sum(BilledCost) AS billed_cost,
sum(EffectiveCost) AS effective_cost,
sum(BilledCost) - sum(EffectiveCost) AS billed_minus_effective
FROM focus
GROUP BY ChargeCategory
UNION ALL
SELECT 1, 'TOTAL', count(*), sum(BilledCost), sum(EffectiveCost), sum(BilledCost) - sum(EffectiveCost)
FROM focus
)
ORDER BY sort_key, ChargeCategory;| ChargeCategory | row_count | billed_cost | effective_cost | billed_minus_effective |
|---|---|---|---|---|
| Adjustment | 1 | -312.40 | -312.40 | 0.00 |
| Credit | 1 | -2500.00 | -2500.00 | 0.00 |
| Purchase | 4 | 152719.00 | 0.00 | 152719.00 |
| Tax | 9 | 19165.74 | 19165.74 | 0.00 |
| Usage | 4418 | 163606.49 | 197534.13 | -33927.64 |
| TOTAL | 4433 | 332678.83 | 213887.47 | 118791.36 |
Billed exceeds effective by $118,791.36 for the quarter. Purchase rows open a $152,719.00 gap: their BilledCost is the cash paid for commitments, and their EffectiveCost is 0 because that cost is recognized on usage rows instead. Usage rows close $33,927.64 of it in the other direction, because covered usage carries amortized commitment cost that was billed as a Purchase. The rest of the upfront payment will be recognized in later quarters. Tax, Credit and Adjustment rows agree on both columns, as FOCUS requires.
Q2. Is the Savings Plan being used?
-- Q2. Commitment reconciliation for the AWS Savings Plan
-- Q2a: by month, BilledCost and EffectiveCost split by CommitmentDiscountStatus,
-- with the Purchase row on its own line (its status is NULL by design).
-- @result Q2a
SELECT
strftime(ChargeDate, '%Y-%m') AS month,
ChargeCategory,
coalesce(CommitmentDiscountStatus, '(none)') AS commitment_status,
count(*) AS row_count,
sum(BilledCost) AS billed_cost,
sum(EffectiveCost) AS effective_cost
FROM focus
WHERE ProviderName = 'AWS'
AND CommitmentDiscountId LIKE 'arn:aws:savingsplans::%'
GROUP BY month, ChargeCategory, commitment_status
ORDER BY month, ChargeCategory = 'Purchase' DESC, commitment_status;
-- Q2b: proof that the EffectiveCost recognized against the commitment is the
-- same every day (upfront / 365). Expect min = max = 410.00 over 92 days.
-- @result Q2b
WITH purchase AS (
SELECT sum(BilledCost) AS upfront
FROM focus
WHERE ChargeCategory = 'Purchase' AND CommitmentDiscountId LIKE 'arn:aws:savingsplans::%'
),
daily AS (
SELECT ChargeDate, sum(EffectiveCost) AS recognized
FROM focus
WHERE ChargeCategory = 'Usage' AND CommitmentDiscountId LIKE 'arn:aws:savingsplans::%'
GROUP BY ChargeDate
)
SELECT
(SELECT upfront FROM purchase) AS upfront_billed,
CAST((SELECT upfront FROM purchase) / 365 AS DECIMAL(18, 2)) AS expected_daily,
count(*) AS days,
min(recognized) AS min_daily_recognized,
max(recognized) AS max_daily_recognized,
sum(recognized) AS recognized_in_quarter,
(SELECT upfront FROM purchase) - sum(recognized) AS not_yet_recognized
FROM daily;
-- Q2c: Used vs Unused before and after the fleet was downsized on 2026-08-15.
-- @result Q2c
SELECT
CASE WHEN ChargeDate < DATE '2026-08-15' THEN '1: 2026-07-01 to 2026-08-14'
ELSE '2: 2026-08-15 to 2026-09-30' END AS period,
count(DISTINCT ChargeDate) AS days,
sum(EffectiveCost) AS recognized,
sum(EffectiveCost) FILTER (WHERE CommitmentDiscountStatus = 'Used') AS used,
coalesce(sum(EffectiveCost) FILTER (WHERE CommitmentDiscountStatus = 'Unused'), 0) AS unused,
round(100.0 * coalesce(sum(EffectiveCost) FILTER (WHERE CommitmentDiscountStatus = 'Unused'), 0)
/ sum(EffectiveCost), 1) AS unused_pct,
CAST(coalesce(sum(EffectiveCost) FILTER (WHERE CommitmentDiscountStatus = 'Unused'), 0)
/ count(DISTINCT ChargeDate) AS DECIMAL(18, 2)) AS unused_per_day
FROM focus
WHERE ChargeCategory = 'Usage' AND CommitmentDiscountId LIKE 'arn:aws:savingsplans::%'
GROUP BY ALL
ORDER BY period;| month | ChargeCategory | commitment_status | row_count | billed_cost | effective_cost |
|---|---|---|---|---|---|
| 2026-07 | Purchase | (none) | 1 | 149650.00 | 0.00 |
| 2026-07 | Usage | Used | 356 | 0.00 | 12710.00 |
| 2026-08 | Usage | Unused | 17 | 0.00 | 1439.92 |
| 2026-08 | Usage | Used | 301 | 0.00 | 11270.08 |
| 2026-09 | Usage | Unused | 30 | 0.00 | 2477.08 |
| 2026-09 | Usage | Used | 254 | 0.00 | 9822.92 |
| upfront_billed | expected_daily | days | min_daily_recognized | max_daily_recognized | recognized_in_quarter | not_yet_recognized |
|---|---|---|---|---|---|---|
| 149650.00 | 410.00 | 92 | 410.00 | 410.00 | 37720.00 | 111930.00 |
| period | days | recognized | used | unused | unused_pct | unused_per_day |
|---|---|---|---|---|---|---|
| 1: 2026-07-01 to 2026-08-14 | 45 | 18450.00 | 18450.00 | 0.00 | 0.0 | 0.00 |
| 2: 2026-08-15 to 2026-09-30 | 47 | 19270.00 | 15353.00 | 3917.00 | 20.3 | 83.34 |
The upfront $149,650.00 is recognized at exactly $410.00 a day, every day, whatever the fleet does. After the August 15 downsizing, 20.3% of that daily amount ($83.34 a day, $3,917.00 by September 30) has no usage to cover. Those Unused rows have BilledCost 0 and no ResourceId, which is why they disappear from most per-resource reports.
Q3. Where does the money go, by provider?
-- Q3. Usage spend by provider and ServiceCategory (EffectiveCost)
-- Different totals do NOT show that one provider is cheaper. Northwind runs
-- different workloads on each provider (web and checkout on AWS, reporting on
-- Azure, ML on Google), so these numbers describe where the money goes, not
-- relative prices. A price comparison needs the same workload on each side.
-- @result Q3
SELECT
ProviderName,
ServiceCategory,
sum(EffectiveCost) AS effective_cost,
round(100.0 * sum(EffectiveCost)
/ sum(sum(EffectiveCost)) OVER (PARTITION BY ProviderName), 1) AS pct_of_provider_usage
FROM focus
WHERE ChargeCategory = 'Usage'
GROUP BY ProviderName, ServiceCategory
ORDER BY ProviderName, effective_cost DESC;| ProviderName | ServiceCategory | effective_cost | pct_of_provider_usage |
|---|---|---|---|
| AWS | Compute | 42808.54 | 33.7 |
| AWS | Analytics | 32563.30 | 25.7 |
| AWS | Storage | 27499.39 | 21.7 |
| AWS | Databases | 13982.43 | 11.0 |
| AWS | Networking | 8899.78 | 7.0 |
| AWS | Management and Governance | 1089.56 | 0.9 |
| Google Cloud | Analytics | 14096.92 | 38.9 |
| Google Cloud | Compute | 9615.66 | 26.5 |
| Google Cloud | AI and Machine Learning | 6694.86 | 18.5 |
| Google Cloud | Storage | 3362.56 | 9.3 |
| Google Cloud | Networking | 2453.91 | 6.8 |
| Microsoft | Databases | 13473.96 | 39.1 |
| Microsoft | Analytics | 10565.77 | 30.7 |
| Microsoft | Storage | 4246.21 | 12.3 |
| Microsoft | Compute | 3917.19 | 11.4 |
| Microsoft | Networking | 1463.92 | 4.2 |
| Microsoft | Management and Governance | 688.02 | 2.0 |
| Microsoft | Security | 112.15 | 0.3 |
This shows where Northwind spends, not which provider is cheaper. Each provider runs different workloads, so a larger AWS total says nothing about AWS prices. A price comparison needs the same workload, unit and pricing quantity on each side.
Q4. Find the anomaly and its driver
-- Q4. Anomaly detection: daily Usage EffectiveCost per SubAccountId
-- Baseline = the previous 7 days (the current day is excluded). A day is
-- flagged when z = (cost - baseline_mean) / baseline_stddev >= 3. Only Usage
-- rows are used, so month-start Tax, Purchase, Credit and Adjustment rows do
-- not create false alarms. Days without 7 prior days are not scored.
-- Note: once a spike enters the baseline it inflates the mean and stddev, so
-- a flat multi-day spike is usually flagged only on its first day.
-- @result Q4a
WITH calendar AS (
SELECT DISTINCT ChargeDate FROM focus WHERE ChargeCategory = 'Usage'
),
subs AS (
SELECT DISTINCT ProviderName, SubAccountId FROM focus WHERE ChargeCategory = 'Usage'
),
daily AS (
SELECT s.ProviderName, s.SubAccountId, c.ChargeDate,
coalesce(sum(f.EffectiveCost), 0) AS cost
FROM subs s
CROSS JOIN calendar c
LEFT JOIN focus f
ON f.ChargeCategory = 'Usage'
AND f.SubAccountId = s.SubAccountId
AND f.ChargeDate = c.ChargeDate
GROUP BY ALL
),
scored AS (
SELECT *,
avg(cost) OVER w AS baseline_mean,
stddev_samp(cost) OVER w AS baseline_sd,
count(*) OVER w AS baseline_days
FROM daily
WINDOW w AS (PARTITION BY SubAccountId ORDER BY ChargeDate
ROWS BETWEEN 7 PRECEDING AND 1 PRECEDING)
)
SELECT
ProviderName,
SubAccountId,
ChargeDate,
cost AS effective_cost,
CAST(baseline_mean AS DECIMAL(18, 2)) AS baseline_mean,
round((cost - baseline_mean) / nullif(baseline_sd, 0), 1) AS z_score
FROM scored
WHERE baseline_days = 7
AND (cost - baseline_mean) / nullif(baseline_sd, 0) >= 3
ORDER BY ChargeDate, SubAccountId;
-- Q4b: drill into the flagged sub-account and days by the Tags "team" key,
-- comparing each team's cost on the day with its own previous-7-day average.
-- @result Q4b
WITH calendar AS (
SELECT DISTINCT ChargeDate FROM focus WHERE ChargeCategory = 'Usage'
),
subs AS (
SELECT DISTINCT SubAccountId FROM focus WHERE ChargeCategory = 'Usage'
),
daily AS (
SELECT s.SubAccountId, c.ChargeDate, coalesce(sum(f.EffectiveCost), 0) AS cost
FROM subs s CROSS JOIN calendar c
LEFT JOIN focus f
ON f.ChargeCategory = 'Usage' AND f.SubAccountId = s.SubAccountId AND f.ChargeDate = c.ChargeDate
GROUP BY ALL
),
flagged AS (
SELECT SubAccountId, ChargeDate
FROM (
SELECT *,
avg(cost) OVER w AS m, stddev_samp(cost) OVER w AS sd, count(*) OVER w AS n
FROM daily
WINDOW w AS (PARTITION BY SubAccountId ORDER BY ChargeDate ROWS BETWEEN 7 PRECEDING AND 1 PRECEDING)
)
WHERE n = 7 AND (cost - m) / nullif(sd, 0) >= 3
),
team_daily AS (
SELECT SubAccountId, ChargeDate, team,
coalesce(string_agg(DISTINCT json_extract_string(Tags, '$.job'), ','), '(none)') AS job_tag,
sum(EffectiveCost) AS cost
FROM focus
WHERE ChargeCategory = 'Usage'
GROUP BY ALL
)
SELECT
t.SubAccountId,
t.ChargeDate,
t.team,
t.job_tag,
t.cost AS effective_cost,
CAST(avg(b.cost) AS DECIMAL(18, 2)) AS team_prev_7d_avg,
t.cost - CAST(avg(b.cost) AS DECIMAL(18, 2)) AS increase
FROM team_daily t
JOIN flagged f USING (SubAccountId, ChargeDate)
LEFT JOIN team_daily b
ON b.SubAccountId = t.SubAccountId AND b.team = t.team
AND b.ChargeDate BETWEEN t.ChargeDate - 7 AND t.ChargeDate - 1
GROUP BY t.SubAccountId, t.ChargeDate, t.team, t.job_tag, t.cost
ORDER BY t.ChargeDate, increase DESC;| ProviderName | SubAccountId | ChargeDate | effective_cost | baseline_mean | z_score |
|---|---|---|---|---|---|
| AWS | 100000000102 | 2026-09-14 | 977.21 | 563.83 | 18.8 |
| AWS | 100000000102 | 2026-09-15 | 1257.21 | 621.41 | 4.0 |
| AWS | 100000000102 | 2026-09-16 | 1739.28 | 718.56 | 3.6 |
| AWS | 100000000102 | 2026-09-17 | 2556.17 | 884.79 | 3.6 |
| AWS | 100000000102 | 2026-09-18 | 3887.81 | 1167.61 | 3.6 |
The baseline is the trailing seven days ending the day before, so a spike can’t inflate its own baseline. Only one AWS sub-account is flagged, on five consecutive days. The drill-down by the team tag (in the SQL file) puts the increase on ml-research, in S3 replication tagged job: embedding-backfill: $407.58 on September 14 rising to $3,317.14 on September 18, against a prior seven-day average of $8.59. The spike keeps climbing, which is the only reason a trailing z-score flags all five days; a flat plateau would only be flagged on its first day.
Q5. Unit economics: cost per 1,000 orders
-- Q5. Unit economics: cost per 1,000 orders by month
-- All charge categories are included (Usage, Purchase, Tax, Credit,
-- Adjustment). The EffectiveCost version spreads commitments over the period
-- they cover. The BilledCost version shows the cash view: July carries the
-- whole AWS upfront payment, so July looks far more expensive per order than
-- it was, and August and September look cheaper.
-- The last column uses Usage rows only. It removes one-off items that FOCUS
-- does not amortize: Tax (EffectiveCost = BilledCost, so July's tax on the
-- upfront payment lands in July), the August Credit and the September
-- Adjustment. Use it to read the operational trend.
-- @result Q5
WITH cost AS (
SELECT strftime(ChargeDate, '%Y-%m') AS month,
sum(EffectiveCost) AS effective_cost,
sum(BilledCost) AS billed_cost,
sum(EffectiveCost) FILTER (WHERE ChargeCategory = 'Usage') AS usage_effective_cost
FROM focus
GROUP BY ALL
),
ord AS (
SELECT strftime(order_date, '%Y-%m') AS month, CAST(sum(orders) AS BIGINT) AS orders
FROM orders
GROUP BY ALL
)
SELECT
month,
orders,
effective_cost,
billed_cost,
CAST(effective_cost * 1000 / orders AS DECIMAL(18, 2)) AS effective_cost_per_1k_orders,
CAST(billed_cost * 1000 / orders AS DECIMAL(18, 2)) AS billed_cost_per_1k_orders,
CAST(usage_effective_cost * 1000 / orders AS DECIMAL(18, 2)) AS usage_effective_cost_per_1k_orders
FROM cost JOIN ord USING (month)
ORDER BY month;
-- Reconciliation assertions. Every row must show passed = true.
-- Each check also requires that the rows it tests exist, so a typo in a filter
-- cannot make a check pass on zero rows.| month | orders | effective_cost | billed_cost | effective_cost_per_1k_orders | billed_cost_per_1k_orders | usage_effective_cost_per_1k_orders |
|---|---|---|---|---|---|---|
| 2026-07 | 1397018 | 76605.70 | 215857.68 | 54.84 | 154.51 | 45.84 |
| 2026-08 | 1561361 | 64261.58 | 53863.56 | 41.16 | 34.50 | 40.82 |
| 2026-09 | 1637014 | 73020.19 | 62957.59 | 44.61 | 38.46 | 42.61 |
On EffectiveCost, cost per 1,000 orders is $54.84, $41.16 and $44.61. On BilledCost, July jumps to $154.51 because the whole Savings Plan was paid that month, which is why BilledCost is the wrong basis for unit economics. July’s effective figure is still inflated by tax on the upfront payment (tax is never amortized); the usage-only column removes that.
Self-checks
The end of the SQL file asserts the FOCUS rules the data is meant to follow, such as: Purchase rows have EffectiveCost 0, covered usage has BilledCost 0, Tax rows have equal BilledCost and EffectiveCost, and Google rows have no commitment status. When we ran it, 20 of 20 checks passed. If you change the data and a check fails, that is the point: it tells you which rule you broke.
From queries to a memo
The download includes a one-page example memo to a fictional finance lead, using only the numbers above: the unused commitment, the backfill spike with its owner, the unit-cost trend, and two recommendations with their caveats. Writing that memo is the skill the flagship course spends five weeks on.
