Changelog examples
Last updated 20 August 2026.
Five entries, each in a different situation, with a note on what makes it work. They are written in the format from keepachangelog.com, which is the closest thing this space has to a standard, but the thing worth copying is the wording rather than the headings.
1. A routine SaaS release
The common case: a handful of user-visible changes, no migration, no drama. It is short because the release was small, and resisting the urge to pad it is most of the skill.
## 20 August 2026
### New
- Saved views on the inbox. Pin a filter once and reuse it
from the sidebar.
### Improved
- The export job now reports progress instead of appearing
to hang on large accounts.
### Fixed
- Invited members no longer see an empty dashboard before
their first sign-in.
What works: every line is an outcome a user could notice. There is no version number because the product is continuously deployed, so the date is the only thing a reader can match against their own experience.
2. An API release with a deprecation
The reader of an API changelog is looking for one thing: whether their integration is about to break, and how long they have. Put that at the top and give it a date.
## Acme API 4.2 - 20 August 2026
### Breaking changes
- `?page=` is removed on all list endpoints. Use the
`nextCursor` value from the previous response.
`?page=` returns 400 after 1 October 2026.
Migration steps: acme.example/docs/pagination
### New
- Webhooks can be scoped to a single project.
### Improved
- List endpoints answer about four times faster on
accounts over 10,000 records.
What works: the deprecation names the exact parameter, the replacement, the failure mode after the cutoff, and the date. A reader can decide in one line whether this affects them.
3. A mobile release
App stores show a truncated what-is-new field, and review can hold a build for days. Both facts shape the entry.
## iOS 3.4.0 - 20 August 2026
Offline mode. Open, read and draft without a connection;
everything syncs when you are back online.
### Also in this release
- Faster launch on older devices.
- Fixed a crash when opening a shared link from Mail.
What works: one sentence carries the release, because that is all the store listing will show. The date is the release date rather than the merge date, so it matches when users could actually get it.
4. A security fix
The one entry where saying less is correct. Users need to know they should update; nobody else needs a description precise enough to attack the version they have not updated yet.
## 20 August 2026
### Security
- Hardened how session tokens are validated. Accounts on
self-hosted installs should update to 4.2.1 or later.
Reported responsibly; no evidence of exploitation.
Details: acme.example/security/2026-08
What works: it tells the reader whether to act without naming the endpoint, the parameter or the technique. The detail belongs in a security advisory on its own schedule, after people have had time to update.
5. What a bad one looks like
Every line here is real in shape, and every line is a mistake:
## v2.3.7
- Merged PR #482 from feature/inbox-refactor
- Bump lodash 4.17.20 -> 4.17.21
- Fixed race condition in MembershipCache.resolve()
- Various bug fixes and improvements
- Refactored SavedView model (thanks Dave!)
What goes wrong: the pull request number and branch mean nothing outside the repository. The dependency bump and the refactor have no user-visible effect and should not appear at all. The race condition names a class instead of the symptom the user saw. "Various bug fixes and improvements" is the phrase people cite when they say changelogs are useless. The thanks belongs in the commit.
What the good ones have in common
- They describe an outcome, not an implementation. A reader who has never seen the codebase can still tell whether the entry affects them.
- They leave things out. Dependency bumps, refactors, CI changes and internal renames are absent, and that absence is what keeps the rest readable.
- They put the costly thing first. If something breaks, it is the first heading, with a date.
- They are dated in a way the reader can use: a version number where users can see versions, a date where they cannot.
- They are boring on purpose. No exclamation marks, no marketing adjectives, no "we are excited to announce". The people reading a changelog are looking for information and will resent anything in the way of it.
Common questions
What format should a changelog use?
keepachangelog.com is the closest thing to a standard and its section names (Added, Changed, Deprecated, Removed, Fixed, Security) are widely recognised. It matters much less than the wording inside the sections. A consistent format with vague entries is worse than a loose format with specific ones.
How often should we publish?
On whatever rhythm matches your releases, and consistently. Publishing per release is the simplest rule. Batching a month of releases into one post makes each individual change harder to find later, which is when most people actually read a changelog.
Should the changelog live on our site or on a third-party page?
On your site if you can, because that is where the traffic and the search value accrue, and because a changelog on someone else's domain is a link away from your product rather than part of it. That is the case for serving it as a feed you render yourself rather than as a hosted page you link to.
Do users actually read changelogs?
A small fraction read them regularly and a much larger fraction search them at the moment something changes underneath them. That second group is the reason to write the symptom rather than the cause: they are searching for what happened to them, in their words.
Further reading: changelog vs release notes, and Keep a Changelog, actually implemented.
Entries in this shape, drafted for you
Changeloop reads the title and description of each merged pull request and writes an entry like the ones above, filters out the dependency bumps and refactors, and holds it for you to edit before anything goes out. Free for one repository, no card.
Start free