# RFC: A new versioning strategy for Discourse

**URL:** https://meta.discourse.org/t/rfc-a-new-versioning-strategy-for-discourse/383536
**Category:** Development
**Tags:** dev-news
**Created:** [September 23, 2025, 7:55am UTC](https://meta.discourse.org/t/rfc-a-new-versioning-strategy-for-discourse/383536 "2025-09-23T07:55:33Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)
#### Post date: [September 23, 2025, 7:55am UTC](https://meta.discourse.org/t/rfc-a-new-versioning-strategy-for-discourse/383536/1 "2025-09-23T07:55:33Z")

</div>

We’re planning to introduce a new versioning system for Discourse. Our goal is to provide more choice & predictability for community administrators, while maintaining our development velocity. We’re also adjusting some terminology to align better with other software.

This document will evolve as we receive comments, begin to implement the system, and then expand use of the new release streams.

If you have any comments/suggestions at this stage, please let us know by replying to this topic!

* * *

## Goals

1. Introduce more regular ‘releases’ for Discourse, which provide a balance between speed-of-development and stability

2. Continue to provide approx. 6-monthly releases which are supported for an extended period

3. Provide overlapping support for regular & extended-support releases, so that administrators have more flexibility over update timing, while continuing to receive critical security updates

4. Keep ceremony around ‘releases’ to a bare minimum. As much as possible should be automated, and should not slow down the core developer experience. ESR releases are just the same as any other release.

5. Naming & procedure should match industry standards, so that it’s easier to explain to developers & end-users

## High-level Overview

- Cut approximately one release per month. The ‘major’ version is the current year, and the ‘minor’ version increments with each release. The patch version number will be incremented for any backported fixes

- Approximately every 6 months, declare one of those releases as an Extended Support Release (ESR). ESR versions remain supported for 2 releases after the next ESR is declared.

- Provide critical fixes for `latest`, the most recent release, the previous release, and any active ESR versions.

- Rename the `tests-passed` branch to `latest`

Example graph of support periods over a year:

```mermaid
gantt
    title Discourse Releases and Support Periods (Jan 2026 – Jan 2027)
    dateFormat YYYY-MM-DD
    axisFormat %b %Y

    2026.0 (ESR) :active, 2026-01-27, 2026-09-29
    2026.1 :done, 2026-02-24, 2026-04-28
    2026.2 :done, 2026-03-31, 2026-05-26
    2026.3 :done, 2026-04-28, 2026-06-30
    2026.4 :done, 2026-05-26, 2026-07-28
    2026.5 :done, 2026-06-30, 2026-08-25
    2026.6 (ESR) :active, 2026-07-28, 2027-01-26
    2026.7 :done, 2026-08-25, 2026-10-27
    2026.8 :done, 2026-09-29, 2026-11-24
    2026.9 :done, 2026-10-27, 2026-12-29
    2026.10 :done, 2026-11-24, 2027-01-26
    2026.11 :done, 2026-12-29, 2027-01-26

```

## Implementation

- Each release will have a branch cut from `latest`. These will be namespaced, and preserved indefinitely. For example, `v2026.1` would have a branch named `release/2026.1`

- Each patch release will be tagged. e.g. `v2026.1.0`, `v2026.1.1`, etc.

- The latest release will be tagged `release`. The latest ESR will be tagged `esr`.

- Previous release will be tagged `release-previous`. Previous active ESR (if any) will be tagged `esr-previous`.

- For backwards compatibility, tags matching the existing release streams will be aliased to the closest new equivalent. `stable` → `esr`. `beta` → `release`. `tests-passed` → `latest`.

- On `latest`, the version number will be the currently-in-development version, suffixed with `-latest`. e.g. `2026.3.0-latest`

## Automated Release Process

Each month, a GitHub action will open a new PR containing a single commit which bumps the `version.rb` on `main` to the next `-latest` version.

Once a human has merged the PR, another GitHub action will detect `main` moving to the next `-latest` and cut a branch for the completed release. Essentially, this branch becomes a ‘release candidate’. Another automated PR will be opened against the release branch with an update to remove the `-latest` suffix from `version.rb`, and thereby ‘release’ it.

Usually, we’ll merge these two PRs in quick succession. But having separate PRs for creating and finalizing the release gives us the option to address any issues in the branch prior to finalizing.

```mermaid
    %%{init: { 'logLevel': 'debug', 'gitGraph': {'showBranches': true, 'showCommitLabel':true,'mainBranchOrder': 2}} }%%
    gitGraph
       checkout main
       commit id:'version v2026.1-latest'
       commit id:'...'
       commit id:'....'
       branch 'release/2026.1'
       commit id:'version 2026.1'
       checkout 'main'
       commit id:'version v2026.2-latest'

```

Separately, another GitHub actions workflow will watch for any backported commits to release branches. When any are found, a new PR will be generated to bump the patch version on that branch. A human can decide when to merge those PRs.

All these automations will automatically keep various tags (`release`, `release-previous`, `esr`, `esr-previous`, plus backwards-compatibility aliases) up-to-date.

## Security Fixes

Security fix workflow remains largely the same, except that we now need to make the fixes in two of these three new places:

- `latest`

- `esr`

- `esr-previous` 🆕

- `release` 🆕

- `release-previous` 🆕

(Remember, per the earlier illustration, it’s only two of the three because `esr-previous` is supported, the new `esr` is the same as `release` or `release-previous`, and we drop support for `esr-previous` when that’s no longer true).

When introducing a security fix to `latest`, a `latest-security-fix` tag will automatically be moved to that commit. docker\_manager will be updated to monitor that tag and prompt admins to update. This allows us to release and notify about security fixes without needing to expedite a version bump.

## Translations

At the moment, the `stable` and `tests-passed` branches can be translated in CrowdIn, and the results are regularly integrated. In the new system, we initially plan for `latest` and `release` to be translatable in CrowdIn.

Ideally, by the time `release` becomes `release-previous` or `esr`, translations will have settled. If there is demand for continuous translations of those versions, then that’s something which could be considered in future.

## Plugin/Theme Compatibility

Increasing the use of non-`latest` streams of Discourse will increase our dependence on the `discourse-compatibility` system. So we need some improvements to the compat system.

Instead of using a `.discourse-compatibility` file on `main`, we could instead support implicit compatibility based on specially-named branches/tags. This should be much easier than juggling commit hashes manually. For example, a plugin could have branches like

- `d-compat/v2026.1`
- `d-compat/v2026.2`
- `d-compat/v2026.3`
- `main` (used for any Discourse version which doesn’t have its own branch)

When installing a plugin, Discourse can check for a branch matching the current version. If it exists, check that out. Otherwise, check the `.discourse-compatibility` file. Otherwise, check out the default branch.

We can create a public GitHub action which runs on each theme/plugin daily, checks for new Discourse releases, and automatically creates these branches. Each theme/plugin could choose to use this auto-pinning action, or they could go for a more ‘floating’ strategy.

## `discourse.org` hosting

Initially, our hosted offering will continue to run the `latest` version of Discourse. In the future, we’ll be exploring options for our enterprise-tier customers to select a ‘release’ version.

## [Standard install](https://meta.discourse.org/t/142537?silent=true) defaults

Initially, the default will remain `latest`. Admins will be able to opt-in to the new release stream in the same way that they opt-in to stable at the moment. We may explore easier switches between release streams in future, once the system is more mature.

---

<div class="post-metadata">

### Author: ![NateDhaliwal](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/natedhaliwal/32/313494_2.png) [@NateDhaliwal](https://meta.discourse.org/u/NateDhaliwal)
#### Post date: [September 23, 2025, 8:18am UTC](https://meta.discourse.org/t/rfc-a-new-versioning-strategy-for-discourse/383536/3 "2025-09-23T08:18:38Z")

</div>

> [@david](#):
>
> `beta` → `release`

> [@david](#):
>
> For example, `v2026.1` would have a branch named `release/2026.1`

I’m a bit confused. So the `tests-passed` aka `latest` (which I assume is the default) is going to be the most up-to-date (getting the most frequent updates; no change there), but the current `beta` branch, now the `release` branch will still behave like it is now, i.e. a “group” of commits/updates, then the ESR (aka `stable`) branch will be a bigger “group” of `beta`/`release` updates?

> [@david](#):
>
> The latest release will be tagged `release`. The latest ESR will be tagged `esr`.

Does this mean that `release` now becomes the default option, or when you say ‘latest release’ you’re referring to 'latest update _on the `release` branch_? Would there then be a difference between that and `latest`?

Thanks!

---

<div class="post-metadata">

### Author: ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)
#### Post date: [September 23, 2025, 8:29am UTC](https://meta.discourse.org/t/rfc-a-new-versioning-strategy-for-discourse/383536/4 "2025-09-23T08:29:47Z")

</div>

> [@NateDhaliwal](#):
>
> but the current `beta` branch, now the `release` branch will still behave like it is now

`beta` is currently a tag, and does not receive any backported fixes.

With this proposal, each versioned release will have its own branch, and will receive security fixes as long as its “supported”. People could choose to point their install at the specific version number, and keep using it after another release is made. That isn’t possible with the current `beta` or `stable`.

`release` will be a tag which follows the latest release (inc. patch releases) for security fixes.

> [@NateDhaliwal](#):
>
> Does this mean that `release` now becomes the default option

No:

> [@david](#):
>
> Initially, the default will remain `latest`. Admins will be able to opt-in to the new release stream in the same way that they opt-in to stable at the moment. We may explore easier switches between release streams in future, once the system is more mature.

> [@NateDhaliwal](#):
>
> when you say ‘latest release’ you’re referring to 'latest update _on the `release` branch_? Would there then be a difference between that and `latest`?

‘latest release’ (or just ‘release’)= the most recent commit on the most recent release branch

‘latest’ = the new name for tests-passed

---

<div class="post-metadata">

### Author: ![NateDhaliwal](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/natedhaliwal/32/313494_2.png) [@NateDhaliwal](https://meta.discourse.org/u/NateDhaliwal)
#### Post date: [September 23, 2025, 8:33am UTC](https://meta.discourse.org/t/rfc-a-new-versioning-strategy-for-discourse/383536/5 "2025-09-23T08:33:24Z")

</div>

Thanks, that clears it up!

---

<div class="post-metadata">

### Author: ![Ed\_S](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/ed_s/32/134015_2.png) [@Ed\_S](https://meta.discourse.org/u/Ed_S)
#### Post date: [September 23, 2025, 12:08pm UTC](https://meta.discourse.org/t/rfc-a-new-versioning-strategy-for-discourse/383536/6 "2025-09-23T12:08:35Z")

</div>

This looks like a positive development!

Will there be any specific testing of upgrades from esr-previous to esr at the time that esr is labelled? Such upgrades, I would argue, should be arranged to be smooth upgrades, or to have good descriptions of how to perform them as smoothly as possible.

---

<div class="post-metadata">

### Author: ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)
#### Post date: [September 23, 2025, 12:15pm UTC](https://meta.discourse.org/t/rfc-a-new-versioning-strategy-for-discourse/383536/7 "2025-09-23T12:15:48Z")

</div>

Yup, upgrades between ESR versions (or indeed, any supported version) will continue to be seamless.

---

<div class="post-metadata">

### Author: ![itsbhanusharma](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/itsbhanusharma/32/180717_2.png) [@itsbhanusharma](https://meta.discourse.org/u/itsbhanusharma)
#### Post date: [September 23, 2025, 12:59pm UTC](https://meta.discourse.org/t/rfc-a-new-versioning-strategy-for-discourse/383536/8 "2025-09-23T12:59:35Z")

</div>

Only a small request for the sake of convenience, could the pointer (e.g. 2026.0) be rather tied to the month a release is pushed? (i.e. 2026.01 for January, 2026.02 for February etc.)

---

<div class="post-metadata">

### Author: ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)
#### Post date: [September 23, 2025, 1:06pm UTC](https://meta.discourse.org/t/rfc-a-new-versioning-strategy-for-discourse/383536/9 "2025-09-23T13:06:35Z")

</div>

The problem with explicitly tying things to a month is that we’ll be unable to skip a month, or release two versions in a month. That’s why we’re planning to keep it as a simple incrementing number.

---

<div class="post-metadata">

### Author: ![itsbhanusharma](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/itsbhanusharma/32/180717_2.png) [@itsbhanusharma](https://meta.discourse.org/u/itsbhanusharma)
#### Post date: [September 23, 2025, 1:15pm UTC](https://meta.discourse.org/t/rfc-a-new-versioning-strategy-for-discourse/383536/10 "2025-09-23T13:15:05Z")

</div>

A project I use heavily (mailcow) does skip the month when there is no significant change to core.

And counting from 0 would be really odd. It makes perfect sense for programmers but not a lot of sense for non-technical people.

Edit:

You should be able to 2026.02.x for multiple releases in a month and easily skip from 02 to 04. So long as it stays incremental?

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [September 23, 2025, 2:46pm UTC](https://meta.discourse.org/t/rfc-a-new-versioning-strategy-for-discourse/383536/11 "2025-09-23T14:46:13Z")

</div>

I was wondering about the x.0 release mentioned. I really like tying it to the month so you can tell right away when a release was released. But maybe it doesn’t matter if xx.8 was released in September, December, or June. I can hardly remember what release we’re on now, though, so being able to tell right away if someone is talking about a bug from last week or some months ago without having to go look at the commit like I do now, would really be nice.

> [@david](#):
>
> The problem with explicitly tying things to a month is that we’ll be unable to skip a month

Ubuntu has YY.04 and YY.10. It’s worked for twenty years. Skipping months doesn’t seem hard.

> [@david](#):
>
> or release two versions in a month

That seems like more of a problem, though you could do something like 22.1a or 22.01a if you did have to have two releases in a month.

---

<div class="post-metadata">

### Author: ![tvavrda](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/tvavrda/32/480674_2.png) [@tvavrda](https://meta.discourse.org/u/tvavrda)
#### Post date: [September 23, 2025, 3:28pm UTC](https://meta.discourse.org/t/rfc-a-new-versioning-strategy-for-discourse/383536/12 "2025-09-23T15:28:06Z")

</div>

Some time ago we also started to use this strategy for our platform. Exactly the same including the branching and patching. I can recommend it.

We use monthly releases. So there are 1–12. The rhythm helps everyone. There is always something to release (hello, dependabot) and nobody wants to cut the branch twice a month anyway. Also when I say “I use 2025.6” everybody knows it’s the one from before the summer holidays.

That said, I was quite happy with the current process 🙂

---

<div class="post-metadata">

### Author: ![RGJ](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/rgj/32/523185_2.png) [@RGJ](https://meta.discourse.org/u/RGJ)
#### Post date: [September 23, 2025, 4:17pm UTC](https://meta.discourse.org/t/rfc-a-new-versioning-strategy-for-discourse/383536/13 "2025-09-23T16:17:23Z")

</div>

First of all, 🚀 this is a great step!

After giving this some thought, I have two minor remarks.

1. `git branch` and many other tools do not understand versioning and will sort alphabetically or numerically. In both cases, 2026.10 will end up between 2026.1 and 2026.2. Inspired by Ubuntu, I propose to introduce a leading zero for releases and patch releases when they are only one digit, so we’d have v2026.01, v2026.02 and v2026.10 and then the universe is happy again.

2. the new plugin compatibility method seems overly complex and very fragile

> [@david](#):
>
> we could instead support implicit compatibility based on specially-named branches/tags. This should be much easier than juggling commit hashes manually. For example, a plugin could have branches like
> 
> - `d-compat/v2026.1`
> - `d-compat/v2026.2`
> - `d-compat/v2026.3`
> - `main` (used for any Discourse version which doesn’t have its own branch)
> 
> When installing a plugin, Discourse can check for a branch matching the current version. If it exists, check that out. Otherwise, check the `.discourse-compatibility` file. Otherwise, check out the default branch.

So if I build a new feature in my plugin that needs v2026.3, I create a branch and put my new functionality in there. Now that the feature has been built and my client is happy, I can take some rest and enjoy my vacation 🌴 🍷 . However, after my third glass of wine, you decide to release v2026.4 and my client decides to update. And poof, there is no v2026.4 branch in my plugin and the functionality disappears 😭

So I would never use this and I would keep using `.discourse-compatibility` instead.

---

<div class="post-metadata">

### Author: ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)
#### Post date: [September 23, 2025, 4:26pm UTC](https://meta.discourse.org/t/rfc-a-new-versioning-strategy-for-discourse/383536/14 "2025-09-23T16:26:53Z")

</div>

> [@RGJ](#):
>
> So if I build a new feature in my plugin that needs v2026.3, I create a branch and put my new functionality in there. Now that the feature has been built and my client is happy, I can take some rest and enjoy my vacation 🌴 🍷 . However, after my third glass of wine, you decide to release v2026.4 and my client decides to update. And poof, there is no v2026.4 branch in my plugin and the functionality disappears 😭

The intention is the reverse. The compat branches are only for ‘released’ branches of Discourse. Discourse `latest` will always use `main` of your plugin. That’s where you’ll develop new features.

So the story would be:

Discourse releases `v2026.2`. GitHub actions on your plugin automatically detects this and cuts a `d-compat/v2026.2` branch. Now, anyone using Discourse `v2026.2` will be using the `d-compat/v2026.2` version of your plugin.

You release a new feature on `main` of your plugin. You don’t need to think about backwards-compatibility, because the `main` branch is only used by people running Discourse `latest`.

Then, while you’re sipping your third glass of wine 🍷, Discourse cuts `v2026.3`. Initially there is no plugin branch for this version, so `main` will be used. Stuff keeps working as it did for people on `latest`.

Within hours, your github action detects the new version and freezes `d-compat/v2026.3`, ready for your next plugin feature to land on `main` with no backwards-compatibility concerns.

This is essentially the workflow we use at CDCK to handle stable compatibility of themes/plugins. After each stable release, we have a script to run through our hundreds of themes/plugins and freeze them via `.discourse-compatibility`. This branch-based proposal aims to be a lighter-weight version of that workflow.

---

<div class="post-metadata">

### Author: ![RGJ](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/rgj/32/523185_2.png) [@RGJ](https://meta.discourse.org/u/RGJ)
#### Post date: [September 23, 2025, 4:28pm UTC](https://meta.discourse.org/t/rfc-a-new-versioning-strategy-for-discourse/383536/15 "2025-09-23T16:28:47Z")

</div>

That is awesome, thank you for the detailed explanation.

Sounds like I can have a fourth glass of wine 😉

---

<div class="post-metadata">

### Author: ![schneeland](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/schneeland/32/275391_2.png) [@schneeland](https://meta.discourse.org/u/schneeland)
#### Post date: [September 24, 2025, 8:25pm UTC](https://meta.discourse.org/t/rfc-a-new-versioning-strategy-for-discourse/383536/16 "2025-09-24T20:25:12Z")

</div>

Seconding what others have said, I like the direction of the proposed changes. And I think the proposed branch names are a lot more intuitive than the old ones 👍

What’s not quite clear to me yet is how the upgrade process will work for the `release` and `esr` branches (`latest` seems straight-forward). You mention that, at each point in time, both the current release (let’s call it `n`) and the previous release (`n-1`) will be supported, and that, as an admin, I will have a choice on when to upgrade.

Now based on my experience with other software that, when a new release version (`n+1`) arrives, I would be notified about the availability of version `n+1`. And that I could then decide to do a major upgrade (equivalent to e.g. `apt dist-upgrade` on Linux) or do a minor/standard update (equivalent to e.g. `apt upgrade` on Linux) and stay on version `n`. Is that something that will be worked into the Discourse launcher script?

Also, I do understand the desire to keep release ceremony/process to a minimum, but my intuition would be that both normal and esr releases receive at least a bit of extra testing, before they are released. That might be shaped by working too long in enterprise IT, though 😄

Lastly, I am wondering if monthly releases are actually “too fast”. Now that’s admittedly also subjective, but judging from my own experience in managing IT stuff on the side as a volunteer, I might not have time to bigger updates each month. And starting from that, I was wondering if you could potentially also keep your lives as developers of Discourse a bit easier by simply releasing quarterly, and having no separate `esr` branches, but only `release` branches.

---

<div class="post-metadata">

### Author: ![RGJ](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/rgj/32/523185_2.png) [@RGJ](https://meta.discourse.org/u/RGJ)
#### Post date: [September 24, 2025, 8:41pm UTC](https://meta.discourse.org/t/rfc-a-new-versioning-strategy-for-discourse/383536/17 "2025-09-24T20:41:27Z")

</div>

> [@schneeland](#):
>
> if you could potentially also keep your lives as developers of Discourse a bit easier by simply releasing quarterly, and having no separate `esr` branches, but only `release` branches

That will make the life of developers of themes and plugins harder, because in that (this) situation you have a time pressure to update your themes and plugins, and otherwise you won’t have any security updates. An ESR version will take that pressure off.

---

<div class="post-metadata">

### Author: ![schneeland](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/schneeland/32/275391_2.png) [@schneeland](https://meta.discourse.org/u/schneeland)
#### Post date: [September 24, 2025, 8:58pm UTC](https://meta.discourse.org/t/rfc-a-new-versioning-strategy-for-discourse/383536/18 "2025-09-24T20:58:39Z")

</div>

> [@RGJ](#):
>
> That will make the life of developers of themes and plugins harder, because in that (this) situation you have a time pressure to update your themes and plugins, and otherwise you won’t have any security updates. An ESR version will take that pressure off.

I’m not sure if I completely follow. My understanding based on the previous posts was that the creation of a release version branch would automatically trigger the creation of a plugin branch for that version. So my assumption would be that merging `release` and `esr` into one would also reduce effort for plugin and theme builders, because any time you need to push a fix, it would need to be pushed to less branches (three instead of five). But maybe I’m missing something?

---

<div class="post-metadata">

### Author: ![RGJ](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/rgj/32/523185_2.png) [@RGJ](https://meta.discourse.org/u/RGJ)
#### Post date: [September 24, 2025, 10:19pm UTC](https://meta.discourse.org/t/rfc-a-new-versioning-strategy-for-discourse/383536/19 "2025-09-24T22:19:21Z")

</div>

It’s not about when the theme/plugin author pushes a fix, it’s about when Discourse core has a security fix.

Per

> [@david](#):
>
> Approximately every 6 months, declare one of those releases as an Extended Support Release (ESR). ESR versions remain supported for 2 releases after the next ESR is declared.

the only difference between `release` and `esr` is that `esr` gets security fixes for 6 + 2 = 8 months.

---

<div class="post-metadata">

### Author: ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)
#### Post date: [September 24, 2025, 10:28pm UTC](https://meta.discourse.org/t/rfc-a-new-versioning-strategy-for-discourse/383536/20 "2025-09-24T22:28:46Z")

</div>

> [@schneeland](#):
>
> What’s not quite clear to me yet is how the upgrade process will work for the `release` and `esr` branches (`latest` seems straight-forward).

With the current launcher tooling, and this new branch structure, you could have control over upgrade timing by doing something like:

1. v2026.02 released
2. You set `version: release/v2026.02` in your app.yml file
3. v2026.03 released
4. You run a rebuild. You still get 2026.02, with any recent security fixes
5. When ready, you switch to `version: release/v2026.03` in app.yml

But manually editing that `app.yml` every month is really not ideal, so hopefully we’ll be able to design a system which makes the process more user friendly.

> [@schneeland](#):
>
> my intuition would be that both normal and esr releases receive at least a bit of extra testing

The process in the OP does allow us to treat the branches as ‘release candidates’ before actually marking them as a release. I’m not sure exactly if/how we’ll use that capability at this stage - I think it’s something that will evolve as we get used to the new system.

> [@schneeland](#):
>
> Lastly, I am wondering if monthly releases are actually “too fast”.

We’re trying to strike a balance here between the velocity of Discourse development, and the stability for people with extensive customizations. Having a 3+ month delay on getting features into the hands of our customers isn’t an option. If anything, monthly is on the slow side for us. At the moment we still intend to use `latest` for the majority of our hosting.

But of course, for people hosting Discourse themselves, I understand the desire to have less frequent change. So that’s where the ESR releases come in.

---

<div class="post-metadata">

### Author: ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)
#### Post date: [September 24, 2025, 10:31pm UTC](https://meta.discourse.org/t/rfc-a-new-versioning-strategy-for-discourse/383536/21 "2025-09-24T22:31:58Z")

</div>

> [@schneeland](#):
>
> My understanding based on the previous posts was that the creation of a release version branch would automatically trigger the creation of a plugin branch for that version

It’s up to the plugin/theme author here. Either they can continue with the current strategy, where the `main` branch of the plugin needs to work with all ‘released’ versions of Discourse. Or they can use the automatic branching strategy, which makes compatibility easier, but also means you may need to do a lot of ‘backporting’ in your plugin in case of any critical bug/security fixes.

At any given time, there are three “supported” versions of Discourse, plus `latest`. So critical fixes will need to be applied in up-to 4 branches.

[Next page](https://meta.discourse.org/t/rfc-a-new-versioning-strategy-for-discourse/383536.md?page=2)
