By Jeff Hajewski
A comprehensive guide to building scalable, concurrent, and fault-tolerant systems with Elixir and the BEAM VM.
From basic syntax to distributed systems, OTP patterns, and production testing — everything you need to write professional Elixir.
Elixir powers systems at
Elixir gives you superpowers that most languages can't match.
Run tens of thousands of lightweight processes on a single machine. Elixir's actor model makes concurrency simple and safe.
Built on the battle-tested BEAM VM that has powered telecom systems for decades. Your systems self-heal with supervisor trees.
From a single node to a distributed cluster — Elixir's architecture means you scale without rewriting your application.
Ruby-inspired syntax with the power of functional programming. No type Tetris — just expressive, maintainable code.
A progressive journey from first steps to production-ready distributed systems.
Data types, pattern matching, functions, modules, structs, and control flow — the complete foundation.
Immutability, pure functions, Enum, Stream, and the pipe operator. Write elegant, composable code.
Lightweight processes, message passing, and the actor model. Harness multi-core processors with confidence.
GenServer, Supervisors, and Applications — the battle-tested framework for building reliable systems.
Build systems that span multiple nodes. Inter-service communication, clustering, and real-world architectures.
ExUnit, Mox, property-based testing with StreamData, and idiomatic Elixir patterns for production code.
19 chapters that take you from zero to building distributed, fault-tolerant systems. Click a chapter to preview.
Elixir is a dynamic, functional language designed for building scalable and maintainable applications. It runs on top of the BEAM VM, the same VM that powers Erlang, which is known for being incredibly fault-tolerant, fast, and supporting a huge level of concurrency.
Elixir's out-of-the-box support for concurrency, fault-tolerance, and functional programming is one of the main draws to the language. If you are looking for a language to build large, highly concurrent, and performant systems, Elixir should be at the top of your list. Companies like Discord, Pinterest, Pepsi, Moz, and Toyota use Elixir to power some of their highest traffic/highest demand systems.
Get Elixir installed and configured on your machine. This chapter walks you through setting up your development environment, your first IEx session, and creating your first Mix project.
This chapter will give you just about everything you need to know to start writing some basic Elixir code. By the end of the chapter you will know how to do everything from iteration, branching, comments, basic pattern matching, and defining functions.
Dive into Elixir's collection types: lists, tuples, keyword lists, and maps. Understand how each is implemented, when to use which, and the performance trade-offs between them.
Modules are the primary way to organize code in Elixir. Structs build on maps to give you named, compile-time-checked data structures. Together they form the backbone of every Elixir application.
As a functional language, functions sit at the core of Elixir. Functions can be passed as if they were data. They can be defined inline and assigned to variables. Functions may have side-effects, or they may be pure, having no side-effect at all.
Elixir provides several constructs for controlling program flow: case, cond, if/else, and the powerful with expression. Each has its place, and knowing when to use which will make your code cleaner.
When most people are first introduced to functional programming there are two immediate observations: the learning curve for working with immutable data is steep and pattern matching is awesome. Pattern matching is one of those language features that is hard to live without.
In Elixir, the = operator is actually called the match operator, not an assignment operator. When you write an expression like x = 42, Elixir tries to match the left-hand side with the right-hand side.
The Enum and Stream modules are workhorses of Elixir. Enum provides eager operations on collections — map, filter, reduce, and dozens more. Stream provides their lazy counterparts for working with large or infinite data sets.
Processes are the fundamental building blocks for concurrent programming in Elixir and form the foundation for building scalable and fault-tolerant systems. Elixir processes are lightweight and isolated. A single machine can run tens of thousands of processes without issue.
OTP (Open Telecom Platform) is a set of libraries and design principles that come bundled with Erlang and Elixir. It provides battle-tested abstractions for building concurrent, fault-tolerant applications.
The GenServer behaviour directs us in how to build a server in a manner that aligns with OTP. GenServer helps us abstract the complexities of process management and message-passing by providing a high-level interface for managing state, handling requests, and ensuring robustness.
Supervisors monitor child processes and restart them when they fail. This is the core of Elixir's "let it crash" philosophy — instead of defensive programming, you build systems that recover automatically.
An Application in Elixir is more than just "your program." It's an OTP concept — a component with a defined start/stop lifecycle that can be started, stopped, and managed as a unit.
Many modern applications have some degree of real-time interaction. Building these kinds of systems involves overcoming a unique set of challenges, particularly as the load increases and you need to scale out the machines running your software.
Testing is an essential part of any software project. One of the great features of Elixir is immutability — it makes your code simpler to test. You don't have to worry about state mutation between tests, and pure functions are straightforward to verify.
Write idiomatic Elixir that other developers will thank you for. This chapter covers naming conventions, the pipe operator, pattern matching style, and the small decisions that separate good Elixir from great Elixir.
Go under the hood of the virtual machine that makes it all possible. Understand how the BEAM schedules processes, manages memory, and achieves the performance characteristics that set Elixir apart.
Elixir is expressive, readable, and powerful. Here's a glimpse.
defmodule Greeter do
def hello("Elixir"), do: "You're speaking my language!"
def hello(name), do: "Hello, #{name}!"
end
Greeter.hello("Elixir") # "You're speaking my language!"
Greeter.hello("World") # "Hello, World!"
# Spawn thousands of lightweight processes
1..10_000
|> Enum.each(fn i ->
spawn(fn -> IO.puts("Process #{i} running") end)
end)
# Each process is isolated, concurrent,
# and costs only ~2KB of memory
Whether you come from Ruby, Python, JavaScript, or Java — this book gives you a clear, progressive path into Elixir and functional programming.
Building APIs, real-time systems, or data pipelines? Learn why companies like Discord chose Elixir for their most demanding workloads.
Understand OTP supervision trees, distributed clustering, and fault-tolerant design patterns you won't find in typical language guides.
Start building scalable, fault-tolerant systems today.
ISBN: 979-8-218-62881-9
Buy on Amazon