Reading a Supervision Tree Like a Map

When I join a BEAM codebase, the first file I open is application.ex. Not the router, not the schema — the supervision tree. It is the only place where the system states, in code, what it thinks should happen when things break.

elixir
def start(_type, _args) do
children = [
Ledgerbeam.Repo,
{Phoenix.PubSub, name: Ledgerbeam.PubSub},
{Finch, name: Ledgerbeam.HTTP},
Ledgerbeam.Inventory.Supervisor,
Ledgerbeam.Ingest.Pipeline,
LedgerbeamWeb.Endpoint
]
Supervisor.start_link(children, strategy: :one_for_one, name: Ledgerbeam.Supervisor)
end

Six lines, and each one is a claim.

What the order tells you

Children start in order and stop in reverse. So this tree claims the endpoint should be the last thing up and the first thing down — traffic only arrives once the repo, the pipeline, and the domain supervisors are ready, and traffic stops before they go away.

That is almost always what you want, and it is worth checking, because the failure mode is subtle: put the endpoint too early and you accept requests against a half-built system for a few hundred milliseconds on every deploy.

What the strategy tells you

:one_for_one says these six things are independent — if the ingest pipeline dies, the endpoint should carry on. Is that true? For us it was: the site stays up and serves reads while ingestion restarts.

But look for a :one_for_all and ask what it is protecting. It says the children share state that cannot survive one of them restarting, which is a real thing, and also a design smell worth a second look.

:rest_for_one is the interesting one: it says there is a dependency order here, and everything after this child needs it. That is a map of your real coupling, drawn by someone who had to think about it.

Where the tree lies

The tree is a set of beliefs, and outages are where the beliefs were wrong. Two that catch people:

A process that restarts fine but reconnects slowly. The supervisor's job is done in microseconds; the connection pool underneath takes eight seconds. The tree looks healthy and the system is not.

restart: :temporary on something that matters. It will not come back, ever, and the supervisor will not tell you. This is correct for a one-shot task and quietly catastrophic on a consumer.

Neither shows up in the diagram. Both show up in :observer, and in the first five minutes of an incident, which is why I read the tree before I read anything else.