Skip to content

docs(guides): restructure the hot-upgrade guide and correct the runtime.exs rule - #304

Merged
thiagoesteves merged 1 commit into
mainfrom
thiagoesteves/docs-hot-upgrade-guide
Aug 14, 2026
Merged

docs(guides): restructure the hot-upgrade guide and correct the runtime.exs rule#304
thiagoesteves merged 1 commit into
mainfrom
thiagoesteves/docs-hot-upgrade-guide

Conversation

@thiagoesteves

Copy link
Copy Markdown
Owner

What changed

The hot-upgrade guide is restructured so it can be handed to someone who has never applied one, and the runtime.exs rule is corrected.

Structure. The page had a heading that started at h3 before any h2, a second h1 in the middle, two sections sharing the title When a hot upgrade fails, and the capabilities section arriving after two sections that already assumed it. The same statement about Erlang/OTP being the runtime rather than a library appeared three times. It now follows the decision a reader is making: what can be hot-upgraded, when not to, how one works, how to prepare a project, how to check a release, how to apply one, what happens when it fails, and how to go back.

New sections, all of which the guide previously assumed:

  • How a hot upgrade works - appup, relup and release_handler, the steps run over RPC, and why the boundary at install_release/2 is what every failure message is really reporting
  • Old and current code - purging, and why a hand written receive loop has to re-enter through the module while an OTP behaviour does not
  • Adding or removing a process in the supervision tree - {update, Module, supervisor} starts nothing and stops nothing, the generated appup cannot see a child specification inside init/1, and the apply instructions that close the gap
  • Boundary compatibility, native code, and going back - there is no hot downgrade
  • Glossary - the release statuses and the terms that appear in the log messages

The runtime.exs correction

The guide listed a changed runtime.exs as a reason not to hot-upgrade, three paragraphs above a bullet stating that the change is applied. The second one matches the implementation: the new version's file is resolved and applied through the relup hook during the install.

It comes off the list. The condition that actually matters is stated instead - the file is evaluated by the code the running node has loaded, so it must not reach for something only the new release provides. Config providers stay on the list, since the provider modules genuinely do run in the old version.

This was verified against a running node, not inferred. A monitored application was hot-upgraded between two versions whose runtime.exs, build time configuration and modules all differed:

probe before after
value set only in runtime.exs old version's value new version's value
value set only in build time config old version's value new version's value
key present in the old runtime.exs, deleted in the new one present gone
module function old version's value new version's value

Same OS process throughout, code_change/3 ran, and release_handler:which_releases/0 afterwards showed the new version permanent and the previous one old. The value the new runtime.exs sets appears in no build time configuration, so the new file is the only place it could have come from.

Risk assessment

  • Impact: documentation only. Readers get a correct rule for runtime.exs and an explanation of the supervision tree case that was not covered anywhere before.
  • Blast radius: one guide file. No application code, configuration, test or workflow is touched. The guide is published as an ExDoc extra, so the only build effect is the rendered page.
  • Regression risk: low. Nothing executable changes. Heading levels and every internal anchor were checked after the reorder, and the one broken link in the file, which pointed at a repository that does not exist, now points at the right one.
  • Rollback: plain commit revert.

Checklist

  • Title follows docs(scope): short description
  • Diff is small and focused on one change
  • Description summarizes what changed and why
  • No leftover debug output or comments
  • Risk assessment included

Formatting and test checks were not run, as no Elixir source is touched by this change.

🤖 Generated with Claude Code (Claude Opus 5)

…me.exs rule

The guide had grown by accretion: a heading level that started at h3 before
any h2, a second h1 in the middle of the page, "Erlang/OTP is the runtime,
not a library" repeated in three sections, two sections sharing the title
"When a hot upgrade fails", and the capabilities section arriving after two
sections that already assumed it.

Reordered it to follow the decision a reader is making, from what can be
hot-upgraded through when not to, how it works, how to prepare a project,
how to check a release, how to apply one, and what happens when it fails.
Each duplicated statement is now made once and referenced.

Added the material the guide assumed rather than explained:

 * How a hot upgrade works: appup, relup and release_handler, the steps run
   over RPC, and why the boundary at install_release is what every failure
   message reports
 * Old and current code, purging, and why a hand written receive loop needs
   to re-enter through the module while an OTP behaviour does not
 * Adding or removing a process in the supervision tree, which the generated
   appup cannot express, with the apply instructions that do
 * Keeping the two versions compatible at their boundaries, native code, and
   going back, which is a full deployment rather than a hot downgrade
 * A glossary of the release statuses and the terms the log messages use

Corrected the configuration rules. A changed runtime.exs was listed as a
reason not to hot-upgrade, while the section below it said the change is
applied, which is what the code does: the new version's file is resolved
and applied through the relup hook during the install. It comes off the
list, with the condition that matters stated instead, that the file is
evaluated by the code the running node has loaded. Config providers stay on
the list, since the provider modules do run in the old version.

Verified against a running node rather than from reading: a monitored
application was hot-upgraded between two versions whose runtime.exs, build
time configuration and modules all differed. After the upgrade, with the
same OS process and code_change having run, the application held the new
version's runtime values, a key deleted in the new version was gone, and
the value the new runtime.exs sets appears in no build time configuration,
so it could only have come from that file.

Risk assessment:

Impact: documentation only. Readers of the hot-upgrade guide get a correct
rule for runtime.exs and an explanation of the supervision tree case that
previously was not covered anywhere.
Blast radius: one guide file. No application code, configuration, test or
workflow is touched, and the guide is published as an ExDoc extra, so the
only build effect is the rendered page.
Regression risk: low. Nothing executable changes. Heading levels and every
internal anchor were checked after the reorder, and the one broken link in
the file, which pointed at a repository that does not exist, now points at
the right one.
Rollback: plain commit revert.
@thiagoesteves thiagoesteves self-assigned this Aug 14, 2026
@thiagoesteves
thiagoesteves merged commit bd44bed into main Aug 14, 2026
3 checks passed
@thiagoesteves
thiagoesteves deleted the thiagoesteves/docs-hot-upgrade-guide branch August 14, 2026 14:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant