Did you ever wonder what business objectives your changes target? Wouldn't it be great if you could track their successes and failures? Metronome aims to bring business awareness to your engineering discussions and the business context to your commits.
- Introduction
- Tracking Business Metrics
- Linking Commits to Metrics via Expectations
- Performing Analysis
Metronome is a development workflow in three parts. Firstly, it changes the place where teams store and consult their business KPIs. Secondly, it changes how teams write their commits. And lastly, it provides an analytical capability to review successes and failures in moving KPIs in the right direction. The expected result is an increased measurement awareness within the development team and the reinforced link between code changes and their inevitable business impacts.
-
Put KPIs into a
kpis/latest.prod.json
file under your repository. List the metrics your team is focusing on there with their current readings:{ "daily_revenue": 500.0, "conversion_rate": 2.3 }
-
Update the readings file separately from every other file in the repository. Make sure you include
[meter-readings:prod]
text in the commit body, like so:Refresh readings [meter-readings:prod]
-
Use read-meters-action to simplify regular refresh of readings.
Business metrics, KPIs (Key Performance Indicators) or OKRs (Objectives and Key Results) are all tangible ways of measuring the success of your product improvement efforts. Some of them might be familiar to a development team in form of "non-functional" requirements. Some are historically isolated within the domain of business management.
Some examples of valid business metrics include:
monthy_revenue
conversion_rate
net_promoter_score
frontend_error_rate
number_of_support_requests
team_mood
- etc.
Traditionally, business KPIs (or OKRs) are tracked via some sort of a business dashboard. That limits awareness and breaks the connection between the work being done and its impact. Instead, we suggest that a rightful place for the product KPIs is with the product itself - inside the repository.
Place KPI readings inside a JSON
file under your repository. This way, your engineering team
can track the impact of their work. Using JSON
would allow you to create convenient tooling
around your measurements (Metronome CLI is one such tool). You have full
control over the name of said file and its place, but if you need ideas, we suggest starting with
kpis/latest.prod.json
, where prod
is the name of the tracked environment. Here's an example of
such readings file:
{
"daily_revenue": 500.0,
"conversion_rate": 2.3
}
In order for tooling (including Metronome CLI) to identify both the KPIs
and their changes, make sure you commit changes to the readings file (e.g.
kpis/latest.prod.json
) separately from other changes and that you mark it with
[meter-readings:prod]
text anywhere in the commit body (prod
is the name of the environment
your readings are for). Metronome does not care about the file name as it purely relies on the
commit messages and attached changesets in order to read metrics. An example of a commit message
would be something like this:
Refresh readings
[meter-readings:prod]
Note that only the
[meter-readings:prod]
part is considered by the tooling. You have complete freedom in the rest of the message (both subject and body).
We can easily envision a situation where your team might want to have different readings per
environment. To avoid painful merge conflicts and resolutions in such cases, we suggest giving
every environment its own metric file. Hence the suggestion above of kpis/latest.prod.json
for
a readings file name and a prod
part in the [meter-readings:prod]
commit mark. This allows
you to have kpis/latest.dev.json
, kpis/latest.staging.json
, or others.
We also support a case where you would like to have multiple environments, but populate them with the same readings. In cases like that, you could tag commits to a single readings file with multiple
[meter-readings:...]
marks (e.g.[meter-readings:prod] [meter-readings:test]
). All marked environments would be assumed to have the same readings at that point.
To simplify maintenance and refresh of your meters and their readings, you can use a read-meters GitHub action within your repository. It would help you establish an automated routine to always keep your metrics up-to-date.
-
Mark commits that you expect to impact metrics with
[meter-expect: <your expectation>]
text in their bodies, like so:Remove extra screen in the checkout [meter-expect: conversion_rate will increase by 20% in 2 weeks]
-
Use Metronome CLI's expectation validation command to check that
<your expectation>
is parseable and produces expected result.
After you have put your business KPIs into the repository, it is time to start linking your code changes to the changes in readings.
As you probably know, there is no direct link between code change and a business impact. Instead, these two are linked via hypotheses. Or as we call them - expectations. Expectations (or hypotheses) are timed, constrained KPI assessments about the future.
Some examples of expectations include:
monthly_revenue will increase by 10% in 2 months
conversion_rate increases to 3.2 in 1 week
net_promoter_score will increase to 8 in 4 weeks
frontend_error_rate decreases by 20% in 1 month
team_mood will become 'happy' in 2 weeks
All expectations have four things in common:
- METER - links expectations directly to a particular KPI (e.g.
monthly_revenue
) - DIRECTION - indicates direction of change (e.g.
increase to
,decrease by
,become
, etc.) - MEASURE - states expected target value or delta (e.g.
10%
,3.2
,'happy'
, etc.) - TIMELINE - sets the length of the feedback loop (e.g.
in 2 months
,in 1 week
, etc.)
In order for tooling (including Metronome CLI) to identify commits linked
to expectations, make sure you mark commits in question with the
[meter-expect: <your-expectation>]
text anywhere in the commit message. For Metronome to
understand and be able to analyse expectations, they have to be in the following format:
- number (`25.0`)
- percent (`5%`, `5 percent`)
- boolean (`true`, `false`)
- string (`'str'`)
completely
optional MEASURE
| |
v v
---- ----
monthly_revenue will increase to 25.0 in 1 month
--------------- ----------- ----------
^ ^ ^
| | |
METER DIRECTION TIMELINE
name of direction of natural sentece
the metric change in the future tense
(as per `latest.prod.json`) - increase to - within a week
- increase by - in 1 month
- decrease to - next week
- decrease by - on 2020-07-15
- become
Due to the complexity with escaping, string measures should always be wrapped into single quotes (
'...'
) or backticks (`...`
) and never double quotes ("..."
).
Here's an example of an expectation already embedded into the commit message:
Remove extra screen in the checkout
[meter-expect: conversion_rate will increase by 20% in 2 weeks]
Note that only the
[meter-expect: ...]
part is considered by the tooling. You have complete freedom in the rest of the message (both subject and body).
By default,
[meter-expect: ...]
will create an expectation for all environments. If you want to make an expectation for a particular environment instead, you can use an optional extended notation:[meter-expect:<env>: <expectation>]
. For example:[meter-expect:dev: team_mood will become 'happy' in a week]
.
As it is very expensive to correct mistakes in past commit messages, Metronome CLI comes with a built-in command to validate expectation strings and see their parsed meaning. It will basically tell you if Metronome would be able to parse and analyse your expectation later. We strongly suggest checking your expectation strings with that command, until you get a hang of the language.
In a nutshell, Metronome CLI is an analysis tool for your commits expectations, against your repository's KPI readings. It can plot your KPI changes over time. It can also scan and validate your commit expectations against the KPI changes. Lastly, it can help you write commit expectations in a way that is parseable by the automation tooling (including Metronome CLI itself).
You can install Metronome CLI into your project using yarn
:
yarn add --dev @everzet/metronome-cli
Or npm
:
npm install --save-dev @everzet/metronome-cli
You then can check available commands and options with:
metronome-cli --help
If you don't want to add dependencies to your project, you can always run Metronome CLI with
npx
:
npx -p @everzet/metronome-cli metronome-cli --help
The first step in making a meaningful change isn't to form a hypothesis - it is to establish the
right measurement framework. You can easily set up custom meters and start refreshing your
kpis/latest.prod.json
file regularly with the help of read-meters
GitHub action. But how do
you see all your metrics, with their historic data at a glance?
You can always utilise existing git and GitHub diff and blame tooling, but Metronome CLI makes it even easier.
You can see all your metrics and their readings at a glance by running meters
command with your
metronome-cli
locally:
metronome-cli meters
Or via npx:
npx -p @everzet/metronome-cli metronome-cli meters
By default, command will assume that the current folder is the target repository. You can provide an explicit path to the repository to analse instead:
metronome-cli meters /path/to/repo
By default, you would see readings for the prod
environment. You can specify different
environment to test with the --env ...
flag:
metronome-cli meters --env dev
You can tell Metronome to only search for readings between set revisions (commit shas) with
--from <sha>
and --to <sha>
flags.
After you've configured your KPIs and made a change with expectation linked, it is time to start tracking the prograss towards your goal.
You can see all your active expectations and their linked commits at a glance with test
command:
metronome-cli test
Or via npx:
npx -p @everzet/metronome-cli metronome-cli test
By default, command will assume that the current folder is the target repository. You can provide an explicit path to the repository to analse instead:
metronome-cli test /path/to/repo
By default, you would see readings and expectations for the prod
environment. You can specify
different environment to test with the --env ...
flag:
metronome-cli test --env dev
Environment parameter is optional for expectations (
[meter-expect: ...]
vs[meter-expect:dev: ...]
). So when testing particular environment, you would always get a combination of expectations explicitly set for that environment and expectations without environment specified.
You can tell Metronome to only search for readings and expectations between set revisions (commit
shas) with --from <sha>
and --to <sha>
flags.
By default, tester will use the pretty
formatter. You can use a more compact version instead
with --format basic
flag.
Writing parseable expectation strings at first might be a bit tricky. So we provide a tool to help you quickly validate if a string means what you think it means in Metronome's parsing algorithm.
Just pass your expectation string to the expect
command and see the result:
metronome-cli expect "nps will increase to 8 in 3 days"
Or via npx:
npx -p @everzet/metronome-cli metronome-cli expect "nps will increase to 8 in 3 days"
If your expectation is valid, you would see a breakdown of meter, direction, measure and example
timelines. If your expectation is invalid, you would see an error and the command will return
non-zero response (1
).