필사 모드: Modern Elixir & Phoenix 2026 — A Deep Dive on Elixir 1.18, Phoenix 1.8, LiveView 1.0, Oban, Broadway, Bumblebee, Nx, and Livebook
EnglishPrologue — Why a 30-Year-Old VM Is Hot Again in 2026
Elixir is not a new language. Jose Valim started it in 2012 by layering a humane syntax on top of Erlang/OTP. And Erlang itself was born in 1986 at Ericsson for telephone switches — which means BEAM, the Erlang VM, is effectively forty years old.
In 2026 that forty-year-old VM is in vogue again. The reason fits in one sentence.
**"BEAM is the only VM that was built from day one around concurrency, distribution, and fault tolerance, and the era of multi-core, real-time, and AI inference is finally forcing everyone toward that shape."**
- **Elixir 1.18 (December 2024)** — first preview of set-theoretic types. Gradual static typing is on the roadmap.
- **Phoenix 1.8 (December 2024)** — Scope APIs bake the auth context into function signatures; daisyUI and Tailwind v4 are the default UI stack.
- **LiveView 1.0 (November 2024)** — five years of 0.x betas, then the real 1.0. Server-rendered HTML and real-time bidirectional updates in one abstraction.
- **Bumblebee plus Nx plus Axon** — run Hugging Face Transformer models in Elixir with GPU acceleration.
- **Tidewave (September 2025)** — Jose Valim's LLM serving platform on BEAM.
This post walks the full 2026 Elixir stack — from the actor model at the VM layer up through LiveView, Oban, Broadway, Membrane, Bumblebee, Tidewave, and on to real-world adoption in Korea and Japan — in a single read.
1. Why BEAM — Actors, Soft Real-Time, Fault Tolerance
First, the framing. Half of what makes Elixir attractive is not the language itself but the VM underneath it.
BEAM has three load-bearing properties.
1. **Lightweight processes (actors)** — millions of processes can live in one node. Each owns its memory (default heap around 2 KB) and a mailbox. These are not OS threads.
2. **Preemptive scheduling** — the scheduler forcibly swaps processes every N reductions. One process running an infinite loop never starves the others — that is "soft real-time".
3. **Let it crash plus supervisor trees** — when a process dies, the failure is contained, and a supervisor restarts the child under a pre-declared strategy (one_for_one, rest_for_one, and friends). You write recovery code instead of defensive code.
The picture is roughly:
[Application Supervisor]
|
+-------------+-------------+
| | |
[DB Pool Sup] [Web Sup] [Worker Sup]
| | |
[Pool Worker] [Endpoint] [Job Worker x N]
|
[LiveView Conn x M]
This single tree explains almost all of how an Elixir app is operated. If one LiveView connection crashes, only that connection dies. If the DB pool wobbles, Pool Sup restarts it. If a worker OOMs, Worker Sup spins up a fresh one.
**One-liner to remember**: "BEAM is not a VM that does not die — it is a VM that is allowed to die."
2. Elixir 1.18 (December 2024) — Set-Theoretic Types Preview
Elixir 1.18, released on December 19, 2024, is a milestone on its own.
2.1 Set-Theoretic Types — the First Step Toward Gradual Static Typing
For a long time the most frequent question from Elixir users was "why no static types". The answers used to be (1) Dialyzer exists and (2) BEAM concurrency plus hot code reload favors dynamic typing. The core team decided those answers were no longer enough.
1.18 is the start of a real answer. Set-theoretic types apply to function signatures and pattern matching. Unions (`A or B`), intersections (`A and B`), and negations (`not A`) are first-class.
The compiler infers automatically — no annotations needed
defmodule Numbers do
def add(x, y) when is_integer(x) and is_integer(y), do: x + y
def add(x, y) when is_float(x) and is_float(y), do: x + y
end
Invalid calls are caught at compile time
Numbers.add(1, 2.0)
warning: incompatible types — neither integer-pair nor float-pair
For now the scope is narrow (signatures, pattern matching, some guards). Per the roadmap, 1.19 and 1.20 will introduce explicit type-annotation syntax.
2.2 Mix Improvements
1.18 also polishes mix. `mix test --partitioned` is stable; `mix format` orders imports like prettier; `mix deps.tree` shows SAT-solver diagnostics for dependency conflicts.
2.3 Versioning Policy
Elixir intentionally stretches 1.x. A 2.0 is unlikely. Instead 1.x ships a minor release every December — 1.15 (2023), 1.16 (early 2024), 1.17 (mid-2024), 1.18 (late 2024), with 1.19 slated for December 2025.
3. Phoenix 1.8 (December 2024) — Scope APIs, daisyUI Default
Phoenix is the canonical Elixir web framework. The Rails analogy gets you started — controllers, views, router — but the core is different. Phoenix puts LiveView first, sits on top of Plug middleware, and routes messages between nodes via PubSub.
3.1 Scope API — Auth Context in the Function Signature
The headline change in 1.8 is Scope. Previously you pulled the authenticated user out of `conn.assigns.current_user`, which only worked inside controllers. Scope makes that user (and the org or tenant they belong to) an explicit first argument.
defmodule MyApp.Posts do
alias MyApp.Accounts.Scope
Scope as the first arg — auth context is part of the signature
def list_posts(%Scope{user: user, org: org}) do
Post
|> where(org_id: ^org.id)
|> where(author_id: ^user.id)
|> Repo.all()
end
def create_post(%Scope{} = scope, attrs) do
%Post{}
|> Post.changeset(attrs)
|> Ecto.Changeset.put_change(:org_id, scope.org.id)
|> Repo.insert()
end
end
Why does this matter? **Controllers, LiveView, Oban jobs, background tasks, and GenServers all receive the same auth context consistently.** Previously LiveView had to re-assign user on mount, and Oban jobs had to ship user_id in their args and re-fetch from the DB.
3.2 daisyUI plus Tailwind v4 by Default
From 1.8 onward, `mix phx.new` ships Tailwind v4 plus daisyUI plus Heroicons by default. You get a modern UI out of the box.
1.8 default templates
<.button class="btn btn-primary" phx-click="save">Save</.button>
<.input field={@form[:title]} class="input input-bordered" />
Before 1.8 you got Tailwind only and rolled your own components. 1.8 gives you daisyUI component classes (btn, card, modal, alert, and friends) immediately.
3.3 Creating a New Project
mix archive.install hex phx_new
mix phx.new my_app --live # includes LiveView
cd my_app
mix ecto.create
mix phx.server
Four lines and you have a Phoenix app with LiveView, Tailwind v4, daisyUI, Ecto, and Postgres running on port 4000.
4. LiveView 1.0 — Five Years of Beta, Then the Real Release
LiveView is the signature Elixir technology. Chris McCord demoed it at ElixirConf 2018; after five-plus years of 0.x betas, 1.0 shipped in November 2024.
4.1 The Problem LiveView Solves
A typical SPA stack (React, Vue) carries two recurring costs.
1. **You build the API twice** — a REST/GraphQL backend plus the frontend that calls it.
2. **State synchronization** — server state and client state diverge. That gap is the source of most bugs.
LiveView removes both. **State lives only on the server. The UI is HTML rendered on the server and pushed over WebSocket.** User events (click, submit, keypress) travel back over the WebSocket; the server mutates state and pushes only the changed DOM fragments.
defmodule MyAppWeb.CounterLive do
use MyAppWeb, :live_view
def mount(_params, _session, socket) do
{:ok, assign(socket, count: 0)}
end
def handle_event("inc", _params, socket) do
{:noreply, assign(socket, count: socket.assigns.count + 1)}
end
def render(assigns) do
~H"""
"""
end
end
That is the whole thing. A round trip happens in around 100 ms; only the changed text node is patched. Zero lines of JavaScript.
4.2 What 1.0 Brings
- **Streams** — efficient updates for large lists. Add/remove/move are declared on the server; the client tracks them by DOM key only. Infinite scroll feeds without memory blow-ups.
- **Async assigns** — `assign_async(:user, fn -> ... end)` makes asynchronous data loading a first-class citizen. Suspense-like UX.
- **Function components plus slots** — the children-prop pattern (familiar from React) is stabilized.
- **JS Commands** — for trivial toggles, hides, or focus you skip the round trip and use `JS.toggle("#menu")` style client-side commands.
4.3 When LiveView Is Not the Right Fit
LiveView is not a silver bullet.
- **Offline-first PWAs** — useless if the WebSocket is down.
- **Extremely interactive UIs** — millisecond-latency interactions such as 60 fps drag/scrub are better on the client side.
- **CDN-edge rendering** — server state means you cannot push it cleanly to the edge.
In those cases either lift parts into client JS with **LiveView Hooks** or just go React.
5. Ecto — The Canonical DB Layer
Ecto is not an Elixir ORM; it is a **DB query, validation, and migration library**. The ActiveRecord comparison is shallow and the substance is different.
Ecto has four modules.
1. **Repo** — DB pool and execution interface. `Repo.all`, `Repo.insert`, `Repo.transaction`.
2. **Schema** — table to struct mapping. Unlike ActiveRecord, this is **mapping only**, not a model.
3. **Changeset** — a validation and transformation pipeline. This is the real weapon.
4. **Query** — a DSL checked at compile time. Safer than raw SQL.
5.1 Changeset — the Real Weapon
A changeset captures, in a single pipeline, "take this input, run these validations, and persist it in this shape".
def changeset(post, attrs) do
post
|> cast(attrs, [:title, :body, :published_at])
|> validate_required([:title, :body])
|> validate_length(:title, min: 3, max: 200)
|> validate_format(:title, ~r/^[^<>]+$/)
|> unique_constraint(:slug)
|> put_change(:slug, slugify(attrs["title"]))
end
This is not just form validation. **Every DB write goes through a changeset**, so business rules are enforced at the data layer in one place.
5.2 Multi — the Transaction Builder
Complex transactions get composed with `Ecto.Multi`.
Multi.new()
|> Multi.insert(:post, Post.changeset(%Post{}, attrs))
|> Multi.update(:user, User.bump_post_count(user))
|> Multi.insert(:notification, fn %{post: post} ->
Notification.new_post(post)
end)
|> Repo.transaction()
Each step can read the result of the previous one; any failure rolls the whole thing back.
5.3 Ecto 3 — the Settled Standard
Between 2024 and 2026 Ecto is in a stable phase. 3.x is the de facto standard, evolving incrementally. Postgres arrays, jsonb, LISTEN/NOTIFY, MySQL 8, SQLite — all well supported.
6. Oban — Job Processing, and the 999 Dollar Pro Controversy
Oban is the canonical Elixir job queue. **It runs on Postgres**, which is the key insight — instead of standing up Redis like Sidekiq does, you add one more table to the Postgres you already operate.
6.1 Why Postgres-Backed
- **Business data and job enqueue commit in the same transaction.** With Sidekiq, the gap between "push to Redis" and "save to DB" can leave you with data without jobs or jobs without data. Oban keeps both inside one transaction.
- **The operations interface is SQL.** You query job state directly. An admin UI is optional rather than mandatory.
- **Backups, replication, and HA are Postgres-native.** No separate infra for the job queue.
Job definition
defmodule MyApp.Workers.EmailWorker do
use Oban.Worker, queue: :emails, max_attempts: 5
@impl Oban.Worker
def perform(%Oban.Job{args: %{"user_id" => user_id, "kind" => kind}}) do
user = Repo.get!(User, user_id)
MyApp.Mailer.deliver(user, kind)
:ok
end
end
Enqueue alongside business logic in the same transaction
Multi.new()
|> Multi.insert(:user, User.changeset(%User{}, attrs))
|> Oban.insert(:email_job, fn %{user: user} ->
EmailWorker.new(%{user_id: user.id, kind: "welcome"})
end)
|> Repo.transaction()
6.2 The 999 Dollar Oban Pro Controversy
Core Oban is free and open source. But the features you typically reach for in production — Cron, Batch Jobs (callbacks after N jobs finish), Workflow, Smart Engines — live in Pro. In mid-2024 the single-license Pro price was raised to **999 dollars per year** and the community got loud.
Both sides had a point.
- **Pro side** — one Oban maintainer working full-time is what keeps a job queue of this quality alive in the BEAM ecosystem. 999 dollars per year is one or two hours of senior engineering.
- **Con side** — Sidekiq Pro is 219 dollars per year. 999 dollars is steep, and some Pro-only features really should have been open source.
In the end the community split. New projects in 2026 mostly **just buy Pro** — 999 dollars per year buys back a few engineer-days.
7. Broadway — Kafka, RabbitMQ, AMQP, SQS Pipelines
If Oban is "DB job queue", Broadway is "data pipeline". It pulls messages from external systems (Kafka, RabbitMQ, AMQP, AWS SQS, Google PubSub), batches them, and manages back-pressure.
7.1 The Problem Broadway Solves
Streaming data processing typically needs:
1. **Consumer groups** — multiple nodes split a topic.
2. **Batch processing** — handle in groups of 100 or 1000, not one at a time.
3. **Back-pressure** — if downstream is slow, upstream pulls less.
4. **Retry and dead-letter** — quarantine failed messages.
Broadway puts all of that on top of GenStage as the standard solution.
defmodule MyApp.KafkaPipeline do
use Broadway
def start_link(_opts) do
Broadway.start_link(__MODULE__,
name: __MODULE__,
producer: [
module: {BroadwayKafka.Producer, [
hosts: [localhost: 9092],
group_id: "my_group",
topics: ["events"]
]},
concurrency: 1
],
processors: [
default: [concurrency: 10]
],
batchers: [
default: [batch_size: 100, batch_timeout: 1_000]
]
)
end
@impl true
def handle_message(_, message, _) do
transform a single message
message
end
@impl true
def handle_batch(:default, messages, _, _) do
bulk INSERT 100 messages at once
Enum.map(messages, &Message.update_data(&1, transformed(&1)))
end
end
That is it. Switch the producer module to consume Kafka, RabbitMQ, SQS, or PubSub.
7.2 Case — Event ETL
A shopping platform reads order events from Kafka at thousands per second, enriches them, and lands them in ClickHouse. Written in Broadway, a single BEAM node with producer 1, processor 64, batcher 8 handles tens of thousands of events per second comfortably. Add another node and the Kafka consumer group rebalances partitions automatically.
8. Membrane — Audio and Video Pipelines
Membrane is an audio/video processing framework built by Software Mansion. It powers WebRTC SFUs (think Jitsi/LiveKit), live-stream transcoding, RTSP camera integration, and HLS segment generation.
8.1 Why BEAM Fits Media Pipelines
- **Thousands of concurrent streams** — each as its own process. One call dropping does not affect the others.
- **Built-in back-pressure** — a slow stage upstream gets fewer messages from us.
- **Distribution** — load spreads naturally across nodes.
The codec work itself (H.264/VP9/Opus encode/decode) drops down to C or Rust through NIFs. Membrane composes the pipeline, manages lifecycle, and controls flow.
8.2 Simple Pipeline
defmodule MyApp.AudioPipeline do
use Membrane.Pipeline
@impl true
def handle_init(_ctx, opts) do
structure = [
child(:file_src, %Membrane.File.Source{location: opts.input}),
child(:mp3_decoder, Membrane.MP3.MAD.Decoder),
child(:opus_encoder, %Membrane.Opus.Encoder{}),
child(:rtp, Membrane.RTP.PayloadFormatResolver),
child(:udp_sink, %Membrane.UDP.Sink{destination: opts.dest})
]
{[spec: structure], %{}}
end
end
Decode the MP3 file, re-encode to Opus, packetize as RTP, send over UDP. Each node is a separate process and back-pressure flows automatically.
8.3 Real Uses
- **Jellyfish** — the WebRTC SFU server from the Membrane team. Multi-party conferencing on BEAM.
- **Veedo** — Membrane-based live streaming platform.
9. Igniter — Code Modification Tooling
Igniter is relatively new (2024). It safely auto-modifies Elixir code so that installing or upgrading a library injects the boilerplate for you.
9.1 What It Solves
`mix deps.get` just downloads the dependency. To use it you also have to touch `config/config.exs`, add a supervisor child in `application.ex`, add a plug to the router — historically you read the README and did all that by hand.
Igniter automates it. If a library ships an Igniter recipe, `mix igniter.install <lib>` performs all the file edits safely at the AST level.
mix igniter.install ash_authentication
config/config.exs is patched
lib/my_app/application.ex gets the supervisor child
lib/my_app_web/router.ex gets the routes
9.2 Direct Use
Igniter is also a migration tool — for example, auto-converting deprecated APIs when moving LiveView 0.20 to 1.0. Parts of the Phoenix 1.7 to 1.8 migration ship as Igniter recipes too.
10. Bumblebee — HF Transformers in Elixir
This is where "Elixir also does AI" becomes concrete.
Bumblebee is the Elixir port of Hugging Face Transformers. It loads the same model artifacts (safetensors) and tokenizer configs and runs inference from Elixir.
10.1 BERT in One Line
{:ok, model} = Bumblebee.load_model({:hf, "bert-base-uncased"})
{:ok, tokenizer} = Bumblebee.load_tokenizer({:hf, "bert-base-uncased"})
serving = Bumblebee.Text.fill_mask(model, tokenizer)
Nx.Serving.run(serving, "The capital of [MASK] is Paris.")
=> [%{token: "France", score: 0.97}, ...]
That is it. It runs fine on CPU. For GPU acceleration you switch the backend to EXLA (Google XLA, the JAX one).
10.2 Backends — Nx, EXLA, Torchx
Bumblebee lives on top of Nx, which is a NumPy-like tensor API. The actual computation happens in the backend.
- **EXLA** — XLA on CPU/GPU/TPU. The fastest for many workloads.
- **Torchx** — LibTorch (the PyTorch core) on CPU/GPU. Great PyTorch model compatibility.
config/config.exs
config :nx, default_backend: EXLA.Backend
config :nx, default_defn_options: [compiler: EXLA]
10.3 Stable Diffusion, Whisper, Llama
The supported model families keep growing.
- **Stable Diffusion XL** — text to image.
- **Whisper** — speech to text. Common for live captioning.
- **Llama 3, Mistral, Gemma** — 7B to 70B LLMs. With quantization they run on laptops.
- **CLIP** — image and text embeddings.
10.4 Pairing with Phoenix — Nx.Serving
Bumblebee inference runs inside an abstraction called `Nx.Serving`. This is the decisive piece: drop it as a child in your Phoenix supervisor tree and it handles **batching, queuing, and timeouts** for you.
application.ex
children = [
MyAppWeb.Endpoint,
{Nx.Serving,
serving: build_whisper_serving(),
name: WhisperServing,
batch_size: 8,
batch_timeout: 200}
]
Call from anywhere
Nx.Serving.batched_run(WhisperServing, audio_input)
If 10 concurrent requests arrive, `batch_size: 8` packs them in batches of 8 and ships to GPU. GPU utilization climbs.
11. Nx + Axon + Explorer — BEAM Data Science
Now the layer underneath the one-line Bumblebee call.
11.1 Nx — NumPy for BEAM
Nx is the tensor library. NumPy/PyTorch-shaped API.
defn softmax(t) do
Nx.exp(t) / Nx.sum(Nx.exp(t))
end
Nx.tensor([1.0, 2.0, 3.0]) |> softmax()
=> Nx.Tensor f32[3] [0.09, 0.24, 0.67]
`defn` declares a **numerics-only function**. It is not a regular Elixir function — it is JIT-compiled and lowered through EXLA into XLA, running on GPU/TPU.
11.2 Axon — Deep Learning Library
Axon is a neural-network library on top of Nx. Keras-style functional API.
model =
Axon.input("input", shape: {nil, 784})
|> Axon.dense(128, activation: :relu)
|> Axon.dropout(rate: 0.2)
|> Axon.dense(10, activation: :softmax)
Training
model
|> Axon.Loop.trainer(:categorical_cross_entropy, :adam)
|> Axon.Loop.metric(:accuracy)
|> Axon.Loop.run(train_data, %{}, epochs: 10)
Small models train directly on a BEAM node. Large models still get trained in PyTorch and served via Bumblebee in practice.
11.3 Explorer — DataFrames, Polars-Backed
Explorer is the Elixir take on Pandas/Polars. **Under the hood it calls Polars (Rust) through a NIF**, which is why it is fast.
require Explorer.DataFrame, as: DF
df = DF.from_csv!("sales.csv")
df
|> DF.filter(col("amount") > 100)
|> DF.group_by("region")
|> DF.summarise(total: sum(col("amount")), n: count(col("id")))
|> DF.sort_by(desc: "total")
Visualize it inside Livebook and you have a Jupyter-class analytical environment.
12. Livebook — The Elixir Notebook
Livebook is Jose Valim's Jupyter for Elixir. Compared to Jupyter, two things stand out.
1. **Collaboration is first-class** — multiple people edit one notebook simultaneously, Google Docs style.
2. **Version control is clean** — notebooks are `.livemd` (markdown). `git diff` is human-readable.
One-line install on Mac/Linux
mix escript.install hex livebook
livebook server
http://localhost:8080
12.1 Where Livebook Shines
- **Data exploration** — DB queries, Explorer, Vega-Lite charts.
- **ML inference experiments** — load a Bumblebee model in a notebook and tune hyperparameters interactively.
- **Operations notebooks** — "we need to run this query against prod" in a form that can be reviewed.
- **Tutorials and textbooks** — `.livemd` is an executable essay.
12.2 Smart Cells
Smart Cells are form-driven UI surfaces that emit code. Charts, DB queries, neural-network visualizations — you fill the form and a code cell is generated for you.
[Smart Cell: SQL Query]
Connection: prod_replica
Query: SELECT * FROM users WHERE created_at > $1
Variables: cutoff_date = ~D[2026-01-01]
→ Ecto/Postgrex code is auto-generated below the cell
13. Tidewave (September 2025, Jose Valim) — Elixir LLM Serving
In September 2025, Jose Valim and the Dashbit team unveiled **Tidewave** — an LLM serving platform on BEAM.
13.1 What It Solves
Serving LLMs at scale needs:
1. **Batching hundreds or thousands of concurrent requests onto a GPU well** — what vLLM solves.
2. **Streaming responses** — push token by token to the client.
3. **Session and state management** — multi-turn conversations, context.
4. **Fault isolation** — one user's bad request should not cascade.
5. **Distribution** — route across many GPU nodes.
Items 3, 4, and 5 have been BEAM strengths for **thirty years**. Items 1 and 2 fit naturally on top of Nx.Serving and Phoenix Channels.
13.2 Architecture
Tidewave looks roughly like this.
[Phoenix Endpoint]
|
+-------+-------+
| |
[HTTP /chat] [WS /stream]
| |
v v
[Session Sup] [Stream Channel]
| |
v v
[Session GenServer x N]
|
v
+---------+---------+
| |
[Nx.Serving] [Tool Runtime]
| |
v v
[GPU Workers] [DB / HTTP / RAG]
Each user session is a dedicated GenServer. One bad session does not affect the others. Nx.Serving manages GPU batching. Tool calls live in their own supervisor subtree.
13.3 Versus vLLM
Tidewave does not really compete head-on with vLLM; **it solves a different shape of problem**. vLLM is the champ for GPU efficiency. Tidewave trades some GPU efficiency for **operability, session management, fault isolation, and distribution** — the BEAM strengths.
The selection rule is simple.
- **Single node, short responses, maximum throughput** — vLLM.
- **Multi-session, long conversations, complex tool calls, high availability** — Tidewave.
14. Operating BEAM — Observer, Recompile, Hot Reload
A few operational joys that only the experienced Elixir runner knows.
14.1 Observer — Inspect a Live Node
iex --sname dev --remsh my_app@hostname
iex> :observer.start()
A GUI opens. Process tree, mailbox lengths, memory usage, CPU scheduler state — all live. If one process's mailbox is anomalously long, you have your bottleneck.
14.2 IEx Remote Shell
iex --sname remote@host --cookie SECRET --remsh prod@host
This drops you into a remote IEx on the production node. `Repo.get(User, 1)`, `Phoenix.PubSub.broadcast(...)` — all of it works. **The summit of operational debugging.**
14.3 Hot Code Reload
iex> r MyApp.SomeModule
Recompile and re-load a module in a running node. No full restart — one function flipped and live in seconds. **In production, use with great care.** Usually you cut a new release and roll restart instead.
15. Adoption in Korea and Japan
Elixir is not the dominant stack at any giant, but it is sharp in specific niches.
15.1 Korea
- **Toss** — the main fintech stack is Kotlin/JVM, but parts of the real-time systems (notifications, chat, certain payment workflows) reportedly run on Elixir/Phoenix.
- **BabyDragon** — a Korean mobile-game company. Uses Elixir/Phoenix broadly for game backends and matchmaking.
- **Banksalad** — the household-budget app. Earlier materials mention some Elixir on parts of the backend.
- **Individuals and startups** — small teams running real-time chat, collaboration, or game backends on a single BEAM node show up consistently.
Korean adoption is slow. The main reason is **a small hiring pool**. Compared to JVM/Kotlin/Node, Korean-language material is also thin. But teams that adopt Elixir tend to stay.
15.2 Japan
- **Drecom** — mobile-game company. Elixir/Phoenix on parts of the game servers.
- **DMM** — parts of the real-time systems.
- **Nintendo** — there is little official statement, but BEAM-family software (Erlang included) is reportedly involved in some online-service backends.
- **Cookpad** — primarily a Ruby shop, but some experimental backends in Elixir have been described.
- **CyberAgent** — real-time portions of advertising/ad tech.
Japan inherited an Erlang tradition early (NTT and Ericsson Japan). That makes the Elixir migration smoother than in Korea. Japanese-language materials (Qiita, Zenn) are more abundant than Korean ones.
15.3 Worldwide
- **Discord** — Erlang/Elixir message routing. One channel with millions of concurrent users on a BEAM cluster.
- **WhatsApp** — Erlang. The legendary "tiny team running for hundreds of millions of users" before the Meta acquisition.
- **Pinterest** — some notification/SMS systems.
- **Heroku** — routing layer was Erlang for a stretch.
- **Bleacher Report** — survived traffic spikes by going all-in on Elixir.
16. Who Should Pick Elixir
The closing decision matrix.
When Elixir/Phoenix Fits Well
1. **Real-time concurrency is the core** — chat, games, live streams, collaboration tools, trading.
2. **Lots of long-lived connections** — tens of thousands of WebSockets, tens of thousands of IoT devices.
3. **Soft real-time and fault tolerance are requirements** — telecoms, payment notifications, media.
4. **A small team going full-stack quickly** — one LiveView abstraction covers backend and frontend simultaneously.
5. **Message pipelines** — Broadway for Kafka/SQS/RabbitMQ ETL.
When Elixir Does Not Fit
1. **Heavy CPU-bound single-shot computation** — BEAM is slower than V8 or native. NIFs help, but simple workloads are better in Go/Rust.
2. **Massive ML training as the primary stack** — the PyTorch ecosystem dominates. Elixir is the serving/MLOps assistant.
3. **A rich library ecosystem is your primary need** — there is no equivalent of npm or PyPI volume. Hex packages number in the tens of thousands, not millions.
4. **Hiring and team composition is the top constraint** — landing five senior Elixir engineers in a short window in Korea is hard.
One-Line Guide
**"If your traffic involves 10,000-plus concurrent connections, or real-time is the core, or operational stability is the top priority, Elixir is worth a serious look. If you are building a CRUD-shaped SaaS, Phoenix is delightful but Rails/Django/Next will do just fine."**
17. References
- Elixir homepage: https://elixir-lang.org/
- Elixir 1.18 release notes: https://elixir-lang.org/blog/2024/12/19/elixir-v1-18-0-released/
- Phoenix Framework: https://www.phoenixframework.org/
- Phoenix 1.8 release notes: https://www.phoenixframework.org/blog/phoenix-1.8-released
- Phoenix LiveView: https://github.com/phoenixframework/phoenix_live_view
- LiveView 1.0 announcement: https://www.phoenixframework.org/blog/phoenix-liveview-1.0-released
- Ecto: https://github.com/elixir-ecto/ecto
- Oban: https://github.com/oban-bg/oban
- Oban Pro: https://oban.pro/
- Broadway: https://github.com/dashbitco/broadway
- Membrane Framework: https://membrane.stream/
- Igniter: https://github.com/ash-project/igniter
- Bumblebee: https://github.com/elixir-nx/bumblebee
- Nx: https://github.com/elixir-nx/nx
- Axon: https://github.com/elixir-nx/axon
- Explorer: https://github.com/elixir-explorer/explorer
- Livebook: https://livebook.dev/
- Tidewave: https://tidewave.ai/
- Dashbit (Jose Valim's company): https://dashbit.co/
- Fly.io Elixir guide: https://fly.io/docs/elixir/
- The BEAM Book (VM internals): https://github.com/happi/theBeamBook
- Erlang Solutions blog: https://www.erlang-solutions.com/blog/
- ElixirConf US: https://elixirconf.com/
- ElixirConf EU: https://www.elixirconf.eu/
- Code BEAM: https://codebeamamerica.com/
- ElixirForum: https://elixirforum.com/
- Awesome Elixir: https://github.com/h4cc/awesome-elixir
- Thinking Elixir podcast: https://thinkingelixir.com/
- BeamCommunity Slack invite: https://erlef.org/slack-invite
- Discord engineering blog: https://discord.com/category/engineering
- WhatsApp Erlang case (historical): https://www.erlang-factory.com/upload/presentations/558/efsf2012-whatsapp-scaling.pdf
- Drecom TechCon Elixir track: https://tech.drecom.co.jp/
- Toss tech blog: https://toss.tech/
- BabyDragon: https://babydragon.com/
현재 단락 (1/383)
Elixir is not a new language. Jose Valim started it in 2012 by layering a humane syntax on top of Er...