Engineering

Lessons from 4 years of weekly changelogs

Writing a meaningful update for customers every week has been held sacred at incident.io since we started the company. We've written over 200 of them in the past 4 years, and we recently celebrated going 2 years straight without missing a single a single week 🚀

The numbers themselves are not the goal, but the consistency of this habit and what it represents for our customers and our team is very real, and special to me.

It's something I get asked about surprisingly often by founders and product leaders at early stage companies especially, so I thought it'd share some insights into why we do this and how over the years our team have turned writing changelogs into a simple, quick and well oiled process.

Apply some principles

I know, I know, this sounds like an overly philosophical starting point, but “Having a changelog” is just step one. You need to know why you’re doing it, what you care about and how you’re going to ensure it doesn’t die on the vine and becomes baked into your team DNA.

Below are the three principles I put in place early on for our changelog, which haven’t changed all that much through the years.

1. We write an update every week. No exceptions.

If you speak to the team here, this is likely the thing they will probably tell you I care about most when it comes to the changelog, and they’d be absolutely right.

We published the first update the week after we launched, and the goal has been to ship at least one a week ever since. Our changelog represents the thousands of hours of effort everyone here has put into our product, the value we’re delivering to our customers. We frequently start off the week by asking the question, what will customers be able to do by Friday, that they cannot do today? Changelogs are a great way to see if we achieved that!

Especially as an early stage startup, it felt really important to Stephen, Chris and I when we started out, that when we were telling potential customers, “We’re small, but you should bet on us, we ship super quickly and listen to feedback” we have a track record to prove it. 4 years later, this feels no less important.

Sometimes (less so these days!) we have a week where it feels like there was nothing “big”. My default answer is simple: then we just talk about the small things, and perhaps it’s time for some reflection on why that is and if we’re ok with it. It still goes out. No exceptions.

A few times i the early days, one of us would ponder “do we even have enough to justify a changelog this week?” but usually with some light prompting, and a dig through Linear and GitHub, we’d realize we’d actually shipped quite a lot, we just forgot about it amidst in the chaos.

So far, we’ve never had a week where we had nothing to share. I hope you never do either. After all, if nobody has shipped any value to customers all week, what the hell have we been doing?

2. It must be written by a human

It’s not long before, especially with smaller updates, it becomes tempting to copy and paste a list of tickets, or “auto-generate” a summary of updates for the week. Especially as an engineer, the “long list” starts to feel a lot like the commit logs or technical changelogs we’re all used to.

It sometimes feels like the sort of thing you could automate somehow. Fight the urge! It isn’t, and it shouldn’t be.

Writing it and manually reviewing everything that goes into it is a part of the process it forces you to think hard about how you would frame the value of the change to the customer, vs often tickets or bugs being more clearly “what to fix”.

3. We scope updates to last week only

This includes “big things” like new features and announcements, as well as small things like visual improvements and bug fixes. We start with “everything” by default and then remove anything that’s sensitive (i.e., a customer-specific change), or highly specific and technical (i.e., infra or config changes).

We’ve got to the point where we ship so many changes now (thousands a month!) that we also tend to omit some smaller technical or visual fixes that are harder to describe or don’t make sense without a lot of context.

We try not to roll things over to the next week’s changelog. Each week should snapshot one particular week of progress.

Some weeks we’ll have a ton of things to cover and we can’t fit it all in without it feeling overly lengthly, we’ll write what we call a “bonus changelog”. Bonus changelog weeks are, inevitably, pretty awesome ones 💪

Start Simple

Back then, I was allowed to use puns in the titles — sensible adults later made me stop, suggesting that “explaining what we actually shipped” was more important 🙄

When we started, everything was deliberately very manual. I explored the idea of changelog sites, fancy products tools but in the end, I literally copied and pasted our blog codebase, renamed it and called it the changelog.

We'd create one markdown file each week, pick a “big thing” and then write up all the smaller tickets we’d shipped that week, by reviewing a filtered view in Linear for everything that had been closed the previous week.

This lasted for years. Eventually though, we moved our blog to a CMS and brought this along with it.

Sweat the small stuff

Every week, we have a bot which pulls a list of issues from Linear that were completed in the past week, and it tags the people who were assigned. We group them by who shipped the change, essentially giving everyone a clear “mini todo list”.

Everyone responds in the thread with an articulation of their change that they think would make most sense for customers. If they don’t think any of their issues warrants adding to the changelog, they just say that.

We’re explicit either way, which helps the person writing the changelog to know once everyone has taken a look, then they're good to go. We also add relevant emoji indicators, such as:

  • 🆕 New feature!
  • 💅 Polished a rough edge
  • 👷‍♂️ Investment / something non-customer-facing
  • 🐛 Fixed a bug

Since our changelog is often written by an engineers who have a tonne of context, this is also a great way to remind ourselves that the goal is not to write these smaller updates in the same way we’d write a commit message, issue summary, or something more technical intended for internal audiences.

Instead, we try and make our changelog updates as customer centric and user-friendly as we can, focussing on what users can do now that they couldn’t before, and how we’d explain this to a customer if we were speaking face-to-face (which we often are!).

Here are a few examples:

Before 🤖After ✨
Improve cache expiry approach for public status page updatesWe’ve sped up the time it takes from when you publishing a status page update, to when it’s visible on your public page
Allow setting boolean or numeric values in catalog importerThe catalog importer now handles boolean and numeric values correctly, rather than treating them as strings.
Make workflow expressions work well with Microsoft TeamsYou can now create workflow expressions that reference Microsoft Teams Channels, so you can send messages to them.

A lot of this was inspired by our experiences at Monzo, where everyone underwent an onboarding session called “Writing Slightly Betterly” with Harry Ashbridge. Their tone of voice guide captures a lot of great principles. We’ve also written about how this has influenced our product copywriting, too.

Keep process light

We draft all our changelogs in a big Notion database, before copying them over to our website. This gives us a chance to review them, add comments and share internally first.

We handle everything in a single channel internally. Unsurprisingly, this is simply called #changelogs.

Where we know what’s likely to ship in advance, we’ll propose titles / topics and have authors lined up in advance, so folks know that they’ll be owning the changelog for a given week.

This also ensures we can spot early on in the case any weeks look a bit light, or we’ve accidentally pencilled someone to post while they’re on holiday.

Otherwise, the overall process is incredibly simple, very much by design.

It looks like this (I pretty much just copied this over from the internal Notion page):

  1. Draft the content of the changelog in the Notion Database
  2. By 10am Tuesday, tag someone from design to help create a good hero image and revie any product screenshots. Default to whoever was involved in designing the “big “thing” for this week
  3. (Optional) Get an initial review from the team in #changelogs while it’s in a draft state
  4. Move the post into our CMS. Shoutout to the folks at Sanity, who power this — big fans!
  5. Share the post preview in #changelog for a final review. We have a rota of Product Managers for this (powered by our on-call schedule <> Slack sync functionality.
  6. Check the social cards look good via socialsharepreview.com
  7. Hit publish!

To help avoid any last minute rush, we also have an automated Slack reminder in our #changelogs channel to ensure we’ll have any design assets / images ready in time.

Track it, at least for fun!

I’m a data nerd, so naturally I have a nerdy little spreadsheet where I track everything and record out all the changelogs we publish by week, along with how delayed it was and whether we included bonus changelogs, too.

For the first few years, we grew super fast and we did have a few weeks where we were super busy and just forgot, but back in 2022 we got serious about it, wrote up a little process and never looked back!

For the first few years, we grew super fast and we did have a few weeks where we were super busy and just forgot, but back in 2022 we got serious about it, wrote up a little process and never looked back!

If you’re interested, I’ve made a copy of the spreadsheet here with all it’s crazy formulas and formatting ready to go for those who want to start their own.

I also wrote a little script that pulls the RSS feed for the changelog to make updating it easier, so it only takes a few seconds. If you’re technically inclined, it’s probably fairly easy to adapt to your own changelog if you have one.

curl https://incident.io/changelog.xml | xq | jq -r '.rss.channel.item | map({title,link,description, pubDate} | .pubDate |= gsub(" GMT";"") | .pubDate |= strptime("%a, %d %b %Y %H:%M:%S") | .pubDate |= mktime | .pubDate |= todate | .pubDate |= fromdateiso8601 | .pubDate |= strftime("%Y-%m-%d")) | sort_by(.pubDate) | reverse | .[] | [.title, .link, .pubDate, .description] | @tsv' | pbcop

Close the loop with customers

We do a large proportion of our customer support in Slack. We started out by subscribing every channel to our changelog's RSS feed so each week, when we published, all customers got a post in their channel.

Over time, we realized every week was a little noisy for some, so we moved to writing less frequent "Customer Changelogs" covering a few weeks at a time, as well as referencing more general company updates like SEV0, the conference we ran earlier this year.

We’ve created some automation so that any emoji reactions or replies to changelog posts in customer channels get piped into #changelogs-pulse and it’s always fun getting the dopamine hit from hundreds of customers reacting and getting excited for the latest updates ❤️

We also found that whilst we were generally good at remembering to circle back with customers who gave feedback, we sometimes missed a few and we had no reliable way to also let their Account Exec and Customer Success manager know, putting them on the backfoot.

We now tag all customers against issues in Linear with labels, and automatically connect this with our customer CRM so we can send super tailored messages when a change ships, like the one reported by the Netflix team below. It’s pretty awesome and means our Product and Commercial teams are always in lock-step on what we’re shipping for our customers!

Just start!

This is one of the pieces of advice I’ve given over the years to early stage founders looking for tips on getting their teams shipping quickly and keeping up momentum each week. It’s an incredible motivator and an easy way to hold yourself and your team to account with colleagues and customers alike.

I often find companies are already doing something similar internally in all-hands, or perhaps weekly updates in Slack. Making it public just takes things up a notch and really tests whether you’re proud of the work and if customers think it’s as good as you do.

Good luck

Whatever your changelog situation or aspirations, I hope some of the above was helpful and perhaps prompts some productive conversations in your team.

For my part, I’m extremely proud of our team for keeping this up for so long. We haven't dropped the ball once for over 2 years and we've written 57 changelogs this year alone, meaning we'll potentially end with close to 70 - the most we've ever published in a year.

With only 7 to go for the rest of the year, we plan to make them count! 💪

Picture of Pete Hamilton
Pete Hamilton
Co-Founder & CTO

Move fast when you break things