CLI

Overview

Read your Reserved Instance, Savings Plan and Committed Use Discount position from the terminal: coverage, utilization, what expires, and what to buy next.

l4 commitments reads what your organization has already committed to, and what that commitment is earning. It answers the questions the Commitments page answers, plus one it cannot: whether a term is about to lapse, as an exit code a pipeline can act on.

cmt is an alias, so l4 cmt list and l4 commitments list are the same command.

Every subcommand is read-only. Nothing here buys, cancels or exchanges a commitment.

Subcommands

CommandPurposeScope
summaryCoverage, utilization and what the commitments are earningread
listEvery commitment held, soonest to expire firstread
expiringWhat lapses soon, with an exit code for CIread
viewEverything known about one commitmentread
renewalWhat to repurchase when a term ends, and when to buyread
utilizationHow much of what was bought is being usedread
coverageHow much of the eligible bill is covered, weightedread
planThe uncovered on-demand base, and what buying would cover itread
contractsMarketplace floors that bill like a commitmentread

l4 export commitments writes the same ledger as CSV or JSON.

Which providers answer

AWS, Google Cloud and Azure all report. They do not report the same things, because the three clouds expose different data.

CommandAWSGoogle CloudAzure
summaryfullcoverage and utilization, no savings ratecoverage, utilization and expiry, no savings rate
listfullno expiryfull
viewfullno term or expiryfull
coveragefulla rate, but no covered spendone row per instrument, no per-service rows
exportfullno expiryfull
expiringfullnot measuredfull
renewalfullnot measuredsized from Azure's utilization
utilizationfullone entry, resource-based discounts onlyfull
planfullnot measuredAzure's own recommendations, priced on your bill
contractsfullnone collectednone collected

Azure sells the same two instruments as AWS, and the tables name them as Azure does: Reservation and Savings plan. --kind ri and --kind sp select them.

contracts lists the whole organization's floors, whichever provider the command resolves, so --provider only picks the page --web opens. DigitalOcean's reserved products appear there too, because they bill as a contract: what they charge is the floor, and the rest of the bill is the metered leg.

Google Cloud has no public on-demand equivalent to divide by, so there is no effective savings rate to compute. Committed Use Discount term and expiry come from an export that Google ships separately, and until it is enabled a Committed Use Discount has no end date on any surface.

Where a command cannot answer for the resolved provider it says so in one line and exits 0:

$ l4 commitments expiring --provider gcp
Commitment expiry is not measured for Google Cloud: the commitment lifecycle export is not enabled. Nothing checked.

It does not print an empty table. An empty table reads as "you hold none of these", which is a different and wrong claim.

not measured is not zero

Where a figure was never measured, these commands print not measured rather than 0. The distinction is load-bearing in five places:

  • A Savings Plan has no coverage. Cost Explorer cannot filter coverage by plan type, so what one plan covers is unanswerable. The column reads not measured. A 0.0% there would claim the plan covers none of your eligible usage.
  • Google Cloud has no savings rate, for the reason above. summary prints not measured, never a rate derived from coverage.
  • Google Cloud's expiring count is unmeasurable, not zero. A 0 would read as reassurance.
  • An Azure commitment's utilization can be unmeasured, early in a month before Azure reports it. list, view and summary print not measured, and export leaves the cell empty. A 0.0% would read as a commitment nobody used.
  • Totals come from the API, never from summing a column. The monthly commitment amount is not populated on every term, so a client-side total would quietly understate the portfolio.

Picking a provider

Every command reports on one provider. Without --provider, the CLI resolves the first provider it can answer commitments for rather than the first one connected, so a Google Cloud organization with another provider connected first still lands on its own data. A named --provider is always honoured, whatever it is, because asking about one provider deserves an answer about that provider rather than a silent redirect.

summary

l4 commitments summary [flags]

Coverage, the commitment count, how many expire soon, and on AWS the effective savings rate split into the part a negotiated agreement earns and the part commitments earn. Then one row per service, with each instrument measured on its own.

The headline coverage figure is the same spend-weighted one l4 commitments coverage prints, from the same source, so the two commands cannot report different coverage for one estate.

Flags

FlagDescription
--provider <id>aws, gcp or azure (resolved if omitted)
--period <YYYY-MM>Month to measure the rate over. The latest complete month if omitted
--scope <s>eligible (default: usage a commitment could cover) or all

Global flags apply. See CLI overview.

Examples

l4 commitments summary
l4 commitments summary --provider gcp
l4 commitments summary --period 2026-08 --scope all
l4 commitments summary --jq '.esr.data.totals.total_rate_pct'

The rate is reported alongside the share of spend it could be measured over. Where that share is below 100%, the command says so rather than presenting a rate for the whole bill.

list

l4 commitments list [flags]

One row per commitment across every account, soonest to expire first, with what a renewal protects and what right-sizing would recover kept in separate columns. They are different amounts and are never added: one is the loss avoided by renewing, the other is the saving from buying less.

Flags

FlagDescription
--provider <id>aws, gcp or azure (resolved if omitted)
--basis <b>net (default, after your agreement) or list
--kind <k>ri, sp, cud, spend
--status <s>active, expiring, expired, cancelled
--expiring-within <w>Only terms ending inside a window, for example 90d

A kind belonging to another provider is refused rather than sent. --kind cud --provider aws is a valid request that returns nothing, and nothing is exactly what reads as "you hold none of these".

Examples

l4 commitments list
l4 commitments list --basis list
l4 commitments list --kind ri --expiring-within 90d
l4 commitments list --provider gcp
l4 commitments list --jq '.data.rows[] | {id, expires: .expires_in_seconds}'
--kind, --status and --expiring-within shape the table, not the payload. Under --json, --jq or --template the command prints what the API returned, unfiltered, and says on stderr which flags it left out. Narrow the payload with --jq instead.

Every provider's rows arrive under .data.rows[], so one --jq expression reads them all.

view

l4 commitments view <id>

The full record for one commitment: kind, term, payment option, dates, state, utilization, coverage, the accounts consuming it, and any recommendations attached to it.

A Savings Plan id is an ARN, so it contains colons and a slash. Quote it.

l4 commitments view ri-0a1b2c3d
l4 commitments view "arn:aws:savingsplans::111122223333:savingsplan/abc"
l4 commitments view ri-0a1b2c3d --json
l4 commitments view ri-0a1b2c3d --web

utilization

l4 commitments utilization [flags]

Utilization is commitment hours used over commitment hours purchased: am I getting value from what I bought. It is not coverage, which is eligible usage on a commitment over all eligible usage: how exposed am I to on-demand rates.

The two have different denominators and are never averaged together. The valuable reading is the mismatch. Full utilization alongside low coverage means the commitment is undersized, not that it is performing well: every eligible dollar above it is paying the on-demand rate.

Each service is measured on its own. EC2 and RDS contract in vCPU while Redshift, ElastiCache, OpenSearch and MemoryDB contract in nodes, so a figure averaged across them would describe none of them.

Flags

FlagDescription
--instrument <i>ri (default) or sp
--start <YYYY-MM-DD> / --end <YYYY-MM-DD>Window to measure
--granularity <g>daily (default) or monthly
--service <s>Restrict to one service, which also prints its day-by-day series

Examples

l4 commitments utilization
l4 commitments utilization --instrument sp
l4 commitments utilization --granularity monthly --start 2026-01-01
l4 commitments utilization --service ec2

A plan's day series carries no coverage column at all, for the reason in not measured is not zero.

plan

l4 commitments plan [flags]

On-demand spend no commitment covers, split by platform and volatility, beside the purchases that would cover it.

Each slice is sized against its hourly floor rather than its average. Sizing against the average of a volatile base commits to more than the base can sustain, which strands part of the commitment for its whole term.

On Azure, plan lists the reservations and savings plans Azure recommends instead. LevelFour prices each saving by applying Azure's discount to what the covered usage cost on demand on your bill over the last 30 days.

FlagDescription
--provider <id>aws or azure
--format <f>table (default) or csv
l4 commitments plan
l4 commitments plan --format csv > purchase-plan.csv

Buying is a savings recommendation, not a commitments command. On AWS, plan names the recommendation ids, and l4 rec accept acts on one. On Azure, the ID column holds the key LevelFour stores each Azure recommendation under: its kind, scope, SKU, region and term. Once someone raises a proposal as a purchase in the dashboard, the Raised column names its BUY- recommendation, and l4 rec accept acts on that.

contracts

l4 commitments contracts

Marketplace and private-pricing relationships that bill like a commitment and appear in no provider commitment view, with the contracted floor separated from the metered leg that bills on top of it. You pay the floor whether or not you use it. The list covers every connected provider at once. On DigitalOcean, what reserved products charge is the floor.

Availability

These commands need an API release that serves the commitments routes. Against an organization whose API does not yet, every one of them reports that and exits 0 rather than failing:

Commitments are not yet available for your account.

On this page

Ask the FinOps Agent about your cloud spend