🎓 A1Learner
🔍
0 of 46 lessons completed

Elixir Persistent Term

A persistent term is a value stored once in a global store and read from any process. It suits configuration that is read often and written rarely.

Store a setting and read it back

Put a map of settings under one key. Get returns the same map.

:persistent_term.put(:app_settings, %{mode: :fast, retries: 3})
IO.inspect(:persistent_term.get(:app_settings))

A missing key takes a fallback

Get with two arguments returns the fallback for a missing key. Erase removes a key, so a later get takes the fallback too.

:persistent_term.put(:feature_flag, :on)
IO.inspect(:persistent_term.get(:feature_flag, :off))
:persistent_term.erase(:feature_flag)
IO.inspect(:persistent_term.get(:feature_flag, :off))

Every process reads the same stored value

A spawned process reads the stored value and sends it home. The parent prints the value the child read.

:persistent_term.put(:greeting, "hello")
parent = self()
spawn(fn ->
  value = :persistent_term.get(:greeting)
  send(parent, {:read, value})
end)
receive do
  {:read, value} -> IO.inspect(value)
end

Example

:persistent_term.put(:limits, %{max_items: 10, timeout: 30})
:persistent_term.put(:limits, %{max_items: 25, timeout: 30})
parent = self()
spawn(fn ->
  limits = :persistent_term.get(:limits)
  send(parent, {:limits, limits.max_items})
end)
receive do
  {:limits, max_items} -> IO.puts("max_items: #{max_items}")
end
fallback = :persistent_term.get(:missing_limits, %{max_items: 10, timeout: 30})
IO.puts("fallback_max: #{fallback.max_items}")

Key points

  • Persistent term: a global store reached through :persistent_term.
  • Use :persistent_term.put/2 to store a value under a key.
  • Use :persistent_term.get/2 to read a value or take a fallback when the key is missing.
  • Use :persistent_term.erase/1 to remove a key from the store.
  • A stored value is visible to every process in the same runtime.

In this example, the limits map is stored, then stored again with a larger max_items value, so the second put replaces the first. A spawned process reads the stored map and sends its max_items value home, and the parent prints 25. A get for a key that was never stored returns the fallback map, whose max_items value prints as 10.

Note

writes copy the value for all readers, so the store suits data that changes rarely, not a value that changes on every request.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

Which call reads the stored value for :limits, or returns %{max_items: 10} when :limits was never stored?