
Pricing & Monetization
Full playbook: How to architect billing systems to power usage-based pricing
Finn Lobsien • 9 min read
May 22, 2023
/5 min read

Time zones suck. There’s a litany of posts advocating for the “end of Time zones”. There are pros and cons but the net is they won’t go anywhere.
The most fascinating thing about this is that there’s a lot of literature on “how to work across time zones” but so little on “how to build a product that has to handle timezones”.
We’ve come across this tweet from Peer at Cal.com, and the meme by Daniel that is just on point.
So here is how we approached time zones at Lago (we build open-source metering and usage-based billing) and why you might need to think about time zones for your own product too, if you’re addressing a global customer base.
Yes. Your timezone may not match your customer's. This could lead to discrepancies in usage ingestion, subscriptions, and invoicing, which may not occur on the date you anticipated.
If your customer doesn’t understand what they’re billed for, it erodes trust and will incur “billing disputes”.
The most telling example is how time zones impact expiry dates.
Expiry dates can be set for contracts, coupons, or wallets that hold prepaid credits to cover future usage.
If you’re a company based in Paris, France, and have a customer in San Francisco, USA, with a coupon expiring on `2023-02-01T00:00UTC` (February 1st, 2023 at midnight). Your customer might expect to be able to use their prepaid credits until the end January 31st, 2023, their time: Pacific Standard Time.
With this day finishing nine hours earlier in the French time zone, that might trigger a “bad surprise” for the user. That kind of discrepancies can also impact subscriptions (when they start or end) and gaps in your customers’ financial records.
Then comes more tedious edge cases that can have considerable impact on billing and the end user’s experience.
Managing the boundaries of a billing period when a customer or an organization changes their timezone is one of them. For example, let’s say a customer had an active subscription, whose timezone is UTC, and for which the billing frequency is “monthly”. In February, we must take into account all the events that can impact their billing (e.g., additional consumption) that occurred between February 1, 2023, at 00:00:00 UTC and February 28, 2023, at 23:59:59 UTC.
If on February 15, this customer changes their time zone to Tokyo time (UTC+9) within our product, the "new billing period" that will be calculated will run from January 31, 2023, at 14:00:00 UTC to February 28, 2023, at 13:59:59 UTC.
The risk is that events received between January 31, 2023, at 14:00:00 UTC and February 1, 2023, at 00:00:00 UTC will be charged twice, once for January UTC and again for February UTC+9.
Therefore, we need to "realign" the start of the period to February 1, 2023, at 00:00:00 UTC.
If, instead of changing to Tokyo time, the customer switches to Los Angeles time (UTC-8), the "new billing period" will run from February 1, 2023, at 08:00:00 UTC to March 1, 2023, at 07:59:59 UTC.
In that case, we need to "realign" the start of the period to January 31, 2023, at 13:59:59 UTC.
Vincent in our team was the lead on this feature, here are his own words:
In general, it is considered best practice to store dates in a unified and comparable format from one record to another. That's why we decided to store dates in UTC (in the ISO 8601 format) because it provides a unique reference and is not sensitive to changes in time or modifications to the organization's or customer's timezone. Dates are only converted to the user's format at the last moment for display. We had considered storing dates in the database along with timezone information, but ultimately it made the recording process much more complicated, raised questions about updates, and introduced significant complexity in date comparisons because the organization's and customer's time zones may not be the same.
To be honest, I’ve scrolled the web to learn as many things as I could, I think Stackoverflow was the best source of info, for instance:
This is not the first time I have had to deal with this challenge, so I relied heavily on my personal experience and the path was "fairly clear" for me. However, we iterated on the "edge cases" which are numerous with this kind of problem, and making things understandable for the end-user is a constant challenge.
If I had to summarize our approach:
By default, Lago is ingesting usage and invoicing customers based on the system-wide UTC. However, you can decide to change the value at your organization level to make sure that every single customer is billed based on your timezone.

In addition to this, you can decide to overwrite this value per customer. The entire billing engine will then follow the exact time zone sets at a customer level. Usage ingestion, expiry dates and invoicing will be triggered based on the timezone of your customer.

This translates the entire billing logic to follow your customer’s timezone.
If this seems very simple within Lago, it’s on purpose: we worked hard to abstract the time zone logic, so that you don’t even have to think about it!
Et voilà !