Enter your search

How to track MRR

By
Why tracking MRR over time is essential for any SaaS startup

Monthly recurring revenue at GoSquared

MRR (monthly recurring revenue) is arguably the most important metric for SaaS companies to be tracking. At many growing SaaS companies, including GoSquared, it’s an invaluable KPI (Key Performance Indicator) and allows us to track growth against churn on a monetary level.

Track Everything

Every single change to any member of your userbase should be tracked. Did they change their name? Did they add a site? Did they start tracking?

Knowing what’s happened to a user over their lifetime is essential – and tracking changes to their subscription is necessary for monitoring MRR.

MRR Definition

How you define MRR is important to what value it can provide you as a metric. Many SaaS companies have both monthly and yearly plans, so misleading skews need to be avoided.

You could, for example, just add up the amount of money coming into the bank account each month – but that’s not MRR, that’s just the inbound revenue for that month.

Segmented MRR

MRR is best when segmented into a few different types:

  • New MRR from new customers
  • New MRR from account upgrades
  • Lost MRR from account downgrades
  • Lost MRR from expired subscriptions (lost customers)

The sum of those 4 metrics gives the net MRR, and each of the metrics individually can be very useful when tracked over time.

Yearly Plans

Yearly plans (or non-monthly billing cycles) have their values divided by their monthly length. So if a yearly plan cost $240, the value tracked in MRR should be $240 / 12 = $20.

“But that looks like less money than we actually got”

All we’re doing is spreading the value of the subscription into equal monthly amounts, as if it’s being paid monthly.

MRR is meant to be an indicator of growth and the amount of revenue you can expect to make on a recurring basis. It’s not meant to be an exact figure, and will almost never match up with actual money in.

If you’re looking for a metric to track actual revenue into your bank, use that instead of MRR – but be aware that it can be misleading.

Storage

MySQL is great for tracking internal metrics – it’s easy to query (are your marketing team really going to connect up to MongoDB and know how to use it?) and very reliable.

We have a simple user_events table in MySQL which allows us to do cohort analysis and much more. We have many millions of rows in this table, and we still aren’t quite tracking everything just yet. This table contains user_id, event_type and timestamp columns, as well as an extra column that contains JSON encoded information that could be relevant for the future.

We receive push notifications from Recurly whenever something happens to a subscription, and they’re all stored in the user_events table.

To allow efficient MRR tracking, we exported the subscription change user events and put them into a new plan_changes table, containing user_id, timestamp, type, old_value, new_value, currency and yearly columns. The type column can be any of created, updated or expired. Note: the value columns will need the be SIGNED to allow some of the querying below.

Sample rows

user_id timestamp type old_value new_value currency yearly
19263 2014-03-24 12:56 created 0 50 GBP 0
64 2013-03-24 13:55 updated 120 20 USD 0
5784 2014-03-24 15:02 expired 9 0 USD 1
46784 2014-03-24 16:11 updated 99 240 USD 0

Querying

Querying the data and getting some useful insights is, of course, the most important part. The table structure above allows for some easy querying…

Note: we’re ignoring the currency here, but segmenting by currency and converting those figures into a single currency will make the figures a lot easier to digest (and will also prevent them from being misleading)

Total MRR

SELECT SUM(new_value - old_value) AS MRR FROM plan_changes

Net MRR by Month

SELECT monthname(timestamp), year(timestamp), SUM(new_value - old_value) AS MRR FROM plan_changes GROUP BY month(timestamp), year(timestamp) ORDER BY timestamp DESC

Total Lost MRR by Month

SELECT monthname(timestamp), year(timestamp), SUM(new_value - old_value) AS MRR FROM plan_changes WHERE new_value < old_value GROUP BY month(timestamp), year(timestamp) ORDER BY timestamp DESC

New MRR from Upgrades by Month

SELECT monthname(timestamp), year(timestamp), SUM(new_value - old_value) AS MRR FROM plan_changes WHERE type = 'updated' AND new_value > old_value GROUP BY month(timestamp), year(timestamp) ORDER BY timestamp DESC

Conclusions

Graphing the data can reveal some really interesting trends. Christoph Janz has put together a great dashboard/spreadsheet which will automatically graph many useful metrics once a few data points are inserted.

Remember: track everything.

Written by
Lead developer at GoSquared for integrations, partnerships and the API. Works on pretty much everything.

You May Also Like

Group 5 Created with Sketch. Group 11 Created with Sketch. CLOSE ICON Created with Sketch. icon-microphone Group 9 Created with Sketch. CLOSE ICON Created with Sketch. SEARCH ICON Created with Sketch. Group 4 Created with Sketch. Path Created with Sketch. Group 5 Created with Sketch.