liveBook · Manning

ETS table

As explained in Elixir in Action, Third Edition

ETS is Erlang Term Storage, an in-memory table facility and Erlang module for storing and retrieving Erlang terms within a BEAM instance.

ETS (Erlang Term Storage) is an in-memory table facility for sharing Erlang terms between BEAM processes without routing every operation through a dedicated server. It is an optimization: GenServer or Agent can express the same state management, but ETS can remove a single-process bottleneck in suitable workloads. section 10.0 section 10.3

Use ETS effectively by understanding its ownership, access, and concurrency boundaries:

  • Create tables with :ets.new/2; identify them by a reference or, with :named_table, by a global atom name. section 10.3.1
  • Allow multiple processes to read and write concurrently; concurrent writes to the same row are safe, with the last write winning. section 10.3.1
  • Remember that ETS copies terms into and out of separate table memory, so reads return snapshots and table data does not pressure the garbage collector. section 10.3.1
  • Keep the owner process alive: terminating it reclaims the table, while otherwise an unreachable table continues occupying memory. section 10.3.1
  • Prefer key-based operations for speed; use :ets.tab2list/1, traversal, or match patterns only when non-key queries require them. section 10.3.3

Removing the GenServer bottleneck

A key-value store can retain a GenServer solely as the supervised owner of a public, named ETS set. Callers invoke :ets.insert/2 and :ets.lookup/2 directly, allowing independent clients to operate simultaneously. In the demonstrated benchmark, the GenServer version reached about 953,182 operations per second, while the ETS version reached about 5,700,062; with 10,000 clients and repeated updates, the ETS version reached about 52,009,220 operations per second. section 10.3 section 10.3.2

Listing 10.8 Creating the ETS table (key_value/lib/ets_key_value.ex)
defmodule EtsKeyValue do
  use GenServer
 
  def start_link do
    GenServer.start_link(__MODULE__, nil, name: __MODULE__)   #1
  end
 
  def init(_) do
    :ets.new(                                                 #2
      __MODULE__,
      [:named_table, :public, write_concurrency: true]
    )
 
    {:ok, nil}
  end
 
  ...
end

Shows the supervised owner pattern: initialize a named, public ETS table with write concurrency enabled. section 10.3.2

defmodule EtsKeyValue do
  ...
 
  def put(key, value) do
    :ets.insert(__MODULE__, {key, value})   #1
  end
 
  def get(key) do
    case :ets.lookup(__MODULE__, key) do    #2
      [{^key, value}] -> value              #3
      [] -> nil                             #4
    end
  end
 
  ...
end

Shows direct caller-side insertion and lookup, including conversion of the set lookup result into a value or nil. section 10.3.2

Match patterns and process registries

A :bag table can store several rows under one key, such as appointments grouped by date. :ets.match_object/2 can then retrieve rows by value criteria, such as every appointment named "Dentist". ETS also supports process registries: a GenServer owns a public table while clients perform registration and lookup directly, leaving the server to manage lifecycle and cleanup. section 10.3.3 section 10.3.4

How Elixir in Action, Third Edition covers it

How deep it goes
Explains table creation, ownership, access, copying, concurrency, benchmarks, traversal, match patterns, and registry design, while deferring exhaustive ETS behavior.
Examples
Demonstrates key-value stores, concurrent benchmarks, named tables, to-do appointments, match patterns, and a unique process registry.
What it assumes
Assumes familiarity with BEAM processes, GenServer, supervision, and Erlang terms while teaching ETS operations and ownership directly.
What you can do after
Build it from scratch as a supervised shared store or registry and choose access patterns and concurrency options through measurement.
How it connects
Connects ETS with GenServer, Agent, OTP supervision, process registries, concurrency, and BEAM memory behavior.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Elixir in Action, Third Edition. The section links point to the parts of the book it draws on.