Skip to content

Erlang Concurrency — Spawn, Send, Receive, and Process Linking

DodaTech Updated 2026-06-29 1 min read

In this tutorial, you will learn about Erlang Concurrency. We cover key concepts, practical examples, and best practices to help you master this topic.

Erlang's concurrency is its superpower. Processes are lightweight (millions per VM), isolated, and communicate through message passing. This model makes concurrent programming safer and more scalable.

Spawn

%% Spawn a process that runs a function
Pid = spawn(fun() ->
    io:format("Hello from ~p~n", [self()])
end).

%% Spawn with module/function/args
Pid2 = spawn(module, function, [Arg1, Arg2]).

Message Passing

%% Send
Pid ! {hello, world}.

%% Receive (selective receive — picks matching messages)
receive
    {hello, Msg} ->
        io:format("Got: ~p~n", [Msg]);
    {bye, _} ->
        io:format("Goodbye~n");
    Other ->
        io:format("Unknown: ~p~n", [Other])
    after 5000 ->
        io:format("Timeout~n")
end.

Ping-Pong Example

-module(pingpong).
-export([start/0, ping/2, pong/0]).

ping(0, _) ->
    io:format("Game over~n");
ping(N, PongPid) ->
    PongPid ! {ping, self()},
    receive
        pong ->
            io:format("Got pong (~p)~n", [N])
    end,
    ping(N - 1, PongPid).

pong() ->
    receive
        {ping, PingPid} ->
            PingPid ! pong,
            pong()
    end.

start() ->
    PongPid = spawn(fun pong/0),
    spawn(fun() -> ping(5, PongPid) end).

Linking

%% Link processes  if one dies, both die
process_flag(trap_exit, true),
link(Pid).

%% Monitoring (one-way)
Ref = monitor(process, Pid).
receive
    {'DOWN', Ref, process, Pid, Reason} ->
        io:format("Process died: ~p~n", [Reason])
end.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro