Skip to content
GenServer
step 1/5

Reading — step 1 of 5

Learn

~1 min readOTP Building Blocks

GenServer is OTP's most-used behaviour — a server process with sync call, async cast, and lifecycle hooks. Replaces hand-rolled receive loops.

defmodule Counter do
    use GenServer

    # Client API
    def start_link(initial \\\\ 0) do
        GenServer.start_link(__MODULE__, initial, name: __MODULE__)
    end

    def increment, do: GenServer.cast(__MODULE__, :inc)
    def value, do: GenServer.call(__MODULE__, :get)

    # Server callbacks
    def init(initial), do: {:ok, initial}

    def handle_call(:get, _from, state), do: {:reply, state, state}

    def handle_cast(:inc, state), do: {:noreply, state + 1}
end

This pattern is THE Elixir convention — client API + server callbacks in one module.

Run:

Counter.start_link()
Counter.increment()
Counter.increment()
Counter.increment()
Counter.value()       # 3

Differences:

  • call — synchronous. Caller blocks until reply. Use for queries.
  • cast — fire-and-forget. Returns :ok immediately. Use for actions where caller doesn't need a response.

Server callback return shapes:

  • {:reply, reply, new_state} — for handle_call
  • {:noreply, new_state} — no reply (or used in handle_cast)
  • {:stop, reason, reply, state} / {:stop, reason, state} — terminate

Lifecycle:

  • init(args) — runs on startup. Return {:ok, state} or {:stop, reason}.
  • handle_info(msg, state) — for messages that aren't calls/casts (e.g., timeouts)
  • terminate(reason, state) — called on normal/abnormal shutdown (best-effort cleanup)

Why GenServer over manual processes:

  • Battle-tested message passing
  • Hooks into supervision (next lesson)
  • Built-in tracing, hot code reload, debugging
  • Standard error handling — :sys module gives you :sys.get_state(pid) for inspection

99% of stateful Elixir code uses GenServer. The simple spawn + receive pattern is for understanding, not production.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…