Elixir and the BEAM for AI systems
Elixir Libraries Discord and Supabase Open-Sourced
Discord and Supabase publish Elixir libraries. What each solves, whether it is still maintained in 2026, and whether a small team should depend on it.
In this post
TL;DR: This is about the Elixir libraries Discord and Supabase have released to the public — not libraries for writing a Discord bot (that’s Nostrum’s job). Discord has 13 public Elixir repos; four are still actively pushed, five are worth a careful look, and six are abandoned — four of those six are staples people still cargo-cult into new projects.
fastglobalis the clearest case: dead since 2023, and Erlang’s own:persistent_term, verified against the OTP docs, now does the identical zero-copy read trick FastGlobal reimplemented. Supabase’srealtimeandsupavisorare active but they’re services you run, not dependencies you add;libcluster_postgresandplug_caissonare the quiet, actually-useful picks. Outside those two companies, almost nobody publishes Elixir infra — except Adobe, whoseelixir-styleris the single most adoptable library on this whole list.
What “big company open source” actually means for a small team
The honest question with any “libraries companies use at scale” list is whether the thing is still alive, and whether the problem it solves applies to a five-person team or only to a company running Erlang clusters at 11-million-concurrent-user scale. So I ran it as a maintenance audit: for every public Discord and Supabase Elixir repo, I pulled the last push date, the latest Hex release, and read the README for the actual production problem each one was built to solve. For a spot-check of Whatnot, Ramp, Podium, Remote, SumUp, Stord, PepsiCo, and Adobe, I worked from repo descriptions and push/release dates instead. Then I applied one filter: would I tell a five-person Elixir team to add this as a dependency today.
The answer, most of the time, is no — not because the code is bad, but because it was built to solve Discord’s scale problem, and Discord’s scale problem is not yours.
Discord’s public Elixir repos
Discord’s engineering blog has told the scaling story twice — how Discord scaled Elixir to 5,000,000 concurrent users (2017) and using Rust to scale Elixir for 11 million concurrent users (2019, by Matt Nowack). I’m not re-litigating why they picked Elixir — that’s been covered to death. What’s more useful is what came out of solving those problems at that scale, and whether any of it survives contact with a codebase that isn’t Discord’s.
| Library | Solves | Last push | Verdict |
|---|---|---|---|
| manifold | Batches remote-node sends by destination node instead of one
send/2 per recipient |
2026-07-07 | SKIP |
| sorted_set_nif | Rust-NIF sorted set with ordering + index ops | 2026-05-13 | USE-WITH-CAUTION |
| instruments | StatsD/DataDog metrics instrumentation | 2026-07-01 | SKIP |
| jemalloc_info | Exports jemalloc allocator stats | 2025-12-02 | SKIP |
| semaphore | ETS-backed low-contention semaphore | 2024-06-07 | USE-WITH-CAUTION |
| ex_hash_ring | Pure-Elixir consistent hashing for key/request distribution | 2025-04-03 | USE-WITH-CAUTION |
| memory_size | Approximate memory footprint of a term | 2023-09-12 | SKIP |
| fastglobal | Zero-copy fast reads of large shared data | 2023-03-09 | SKIP — use :persistent_term |
| zen_monitor | Batches/throttles :DOWN messages to survive monitor
thundering herds |
2023-07-12 | SKIP |
| limited_queue | Fixed-capacity queue with O(1) size | 2023-07-07 | USE-WITH-CAUTION |
| deque | Fast append/prepend deque with O(1) size | 2023-05-31 | USE-WITH-CAUTION |
| dispenser | Buffers/distributes events with an overload drop mode | 2022-07-15 | SKIP — use GenStage |
| gen_registry | Process-per-natural-id registry with lazy spawn | 2022-10-11 | SKIP — use Registry |
Four are still active: manifold,
sorted_set_nif, instruments, and
jemalloc_info — though the last one is a seven-star niche
utility. Everything below ex_hash_ring in the table hasn’t
been pushed since 2023 or earlier.
The staple everyone still assumes is current, and isn’t
If you’ve read a “cool Elixir libraries” thread in the last few
years, fastglobal, gen_registry,
dispenser, and zen_monitor are probably on it.
All four are abandoned — no push in over three years. That wouldn’t be
worth a whole section if the replacements weren’t this direct.
FastGlobal exists to solve a problem the runtime now solves on its own.
FastGlobal’s README frames the problem honestly: “the Erlang VM is great at many things, but quick access to large shared data is not one of them.” A single GenServer holding shared state becomes a bottleneck under read load; ETS degrades as the table grows and still copies data to the caller on every read; an Agent has the same copy cost. FastGlobal’s trick was to compile the data into a module body at runtime, so reads hit BEAM’s constant pool, the same mechanism the VM uses for literals, and cost effectively nothing per read.
That’s a real trick, and it worked. It’s also exactly what
:persistent_term does now. Verified: per
the Erlang/OTP
docs, :persistent_term (introduced in OTP 21.2) gives
O(1), lock-free, non-copying reads through that same constant-pool
mechanism — and it carries the identical tradeoff FastGlobal has: a
write or delete triggers a global garbage collection across every
scheduler, so it’s built for data that’s read constantly and written
rarely, never as a general-purpose key-value store. If you’re reaching
for FastGlobal in 2026, you’re reimplementing a standard library
function that ships with every Elixir install.
The other three abandoned staples have the same shape — a real Discord-scale problem with a now-standard answer:
gen_registrysolved “address a process byuser_idinstead of tracking PIDs” with lazy spawn-or-lookup semantics. Elixir’s ownRegistry, in the standard library since 1.4, does exactly this with no third-party dependency and no NIF risk.dispenserbuffered events to subscribers and dropped under overload instead of growing unbounded. GenStage, actively maintained and core-adjacent, already does buffered producer/consumer distribution with real backpressure, not just a drop switch.zen_monitorbatches and truncates:DOWNmessages so a heavily-monitored process doesn’t get flooded when a remote node dies. It’s a real problem, but it’s specifically a distributed-systems-at-Discord’s-node-count problem; a five-person team’s cluster isn’t large enough to trigger the thundering herd it exists to survive.
None of these are bad code. They’re solved problems wearing a
company’s logo. Two of these replacements — Registry and, a
section above, :persistent_term — ship with the runtime you
already have installed.
What’s actually worth a look
sorted_set_nif is the most interesting active one — it’s
a Rust NIF (via Rustler) giving you an ordered, indexable set with fast
capacity growth. It’s genuinely useful if you need ordered-set semantics
with index lookups, but it’s a caution, not a straight yes: a panic
inside a NIF can take down the whole BEAM VM, and that’s a real
operational risk for a team without NIF debugging experience on
call.
semaphore and ex_hash_ring are both dormant
— no push in over a year — but small and focused: an ETS-counter
semaphore and a consistent-hash ring are both self-contained enough that
“dormant” isn’t disqualifying; if either breaks, you’re reading a few
hundred lines, not archaeology. deque and
limited_queue are abandoned outright but tiny enough to
vendor if you actually need O(1) size on a queue; Erlang’s built-in
:queue covers most cases without the dependency.
instruments and jemalloc_info are both
actively pushed and both skip: instruments duplicates what
:telemetry plus telemetry_metrics already does
in a stock Phoenix app, and jemalloc_info is only useful if
you’ve explicitly swapped the BEAM’s allocator to jemalloc, which almost
nobody does.
Supabase’s public Elixir repos
Supabase runs its realtime infrastructure in Elixir/Phoenix, and it’s published six non-fork repos, two of them archived since 2021 and 2022. Of the four that are live: two are full services, two are libraries.
| Library | Solves | Last push | Verdict |
|---|---|---|---|
| realtime | Postgres logical replication → WebSocket broadcast, Presence, Postgres Changes | 2026-09-02 | USE-WITH-CAUTION — it’s a service |
| supavisor | Multi-tenant, cloud-native Postgres connection pooler | 2026-09-02 | USE-WITH-CAUTION — it’s a service |
| libcluster_postgres | Node discovery via Postgres LISTEN/NOTIFY
instead of cloud-specific DNS |
2025-07-02 | USE |
| plug_caisson | Decompresses gzip/brotli/deflate/zstd request bodies for
Plug.Parsers |
2025-04-13 | USE |
realtime and supavisor are both actively
developed, pushed the same day I compiled this list, and they both solve
problems worth having solved: WebSocket fan-out with Presence and CDC,
and pooling database connections against a serverless client storm. But
calling them “libraries” undersells what adopting either one costs.
You’re not adding a Hex dependency; you’re standing up and operating a
second Elixir cluster. If you already run Phoenix,
Phoenix.PubSub and Phoenix.Presence cover
broadcast and presence without a second service to keep alive, and a
managed connection pooler (or your host’s own PgBouncer) probably covers
your connection count before you need a purpose-built multi-tenant
pooler.
libcluster_postgres and plug_caisson are
the ones worth actually depending on. Both are dormant — no push in over
a year — but both are small, single-purpose, and solve a problem that’s
awkward to hand-roll: cloud-agnostic node clustering off Postgres
NOTIFY/LISTEN (useful if you’re already
running Postgres, which if you’re on Supabase you are), and transparent
request-body decompression that Plug.Parsers doesn’t handle
out of the box. Neither is a NIF, neither has a large surface area, and
both would be cheap to vendor if abandonment ever becomes a real
problem.
{:libcluster_postgres, "~> 0.2"}
{:plug_caisson, "~> 0.2"}If you’re picking your first-week Elixir dependencies rather than auditing someone else’s, I’ve written up the ones I actually reach for day one — that list sits at the boring-and-load-bearing end of this spectrum, not the Discord scale-infra end.
What about companies other than Discord and Supabase?
I checked GitHub orgs for Whatnot, Ramp, Podium, Remote, SumUp, Stord, PepsiCo, and Adobe. Most of them publish nothing, which is itself the finding. Whether each of them actually runs Elixir in production, and on what evidence, is a separate audit: I fact-checked the viral “15 most valuable companies using Elixir” chart row by row, so this section stays on what they’ve published, not what they run.
Whatnot publishes zero public Elixir repos, and PepsiCo has no public GitHub org at all. Ramp has no Elixir under any org I could tie to it. That’s not a knock: most companies treat their Elixir stack as competitive infrastructure, not marketing, but it means the “everyone’s open-sourcing their Elixir tooling” narrative is really a two-company narrative.
Podium and Remote each publish a handful of small utilities, worth naming with honest verdicts rather than padding the list:
- Podium’s
uinta(structured JSON logging) andredis_mutex(Redis-backed distributed lock) are both actively pushed in 2026 — USE-WITH-CAUTION. Small and current, but low star counts mean you’re the primary support line if something breaks. - Remote’s
email_guard(email validation/deliverability checks) is dormant but narrowly scoped — USE-WITH-CAUTION for the same reason. Three others (phx_gen_solid,recaptcha,ex_dash) are abandoned and only worth it if you need that exact niche.
Adobe’s elixir-styler
is the outlier, and it’s the one library in this entire “other
companies” tier I’d tell a team to add today, independent of who wrote
it. It’s an opinionated auto-formatter that plugs into
mix format and just rewrites your code to its house style
instead of complaining about it — pushed within a week of my check, 804
stars as of September 2026, the kind of adoption number none of the
Podium or Remote repos come close to. If you already run
mix format, adding Styler is close to free.
Does big-company open source actually tell you anything?
Yes — but not what the GitHub star count implies. Three patterns held across every company I checked:
It solves their scale problem, not yours.
manifold’s fan-out batching only matters once you’re
routing sends to something like 100,000 connected PIDs across nodes.
fastglobal’s zero-copy trick only mattered before
:persistent_term existed. A library born from a specific
incident at a specific scale carries that scale as a hidden dependency:
read the README’s problem statement before the star count, because the
star count measures fame, not fit.
It goes dormant when the internal owner moves on. Six of Discord’s thirteen public repos hadn’t been pushed in three-plus years when I checked. That’s not malice; it’s what happens to internal tooling once the engineer who owned it changes teams or leaves, and the company has no product incentive to keep an OSS repo current. Nobody’s obligated to maintain a library they open-sourced as a courtesy.
The ones that survive are the small, single-purpose
ones. libcluster_postgres,
plug_caisson, elixir-styler — none of them are
ambitious. Each does one narrow, well-scoped thing, which is exactly why
they’re cheap to vendor, audit, or replace if the upstream goes quiet.
The big, architecturally load-bearing repos (realtime,
supavisor, manifold) are either services you
have to operate yourself or infrastructure calibrated to a scale you
probably don’t have. Read the source before you trust the label, the way
I did with Oban’s job execution
internals.
If you’re weighing whether Elixir’s ecosystem generally can support a production AI backend rather than one specific dependency choice, that’s a separate question I’ve answered in more depth in why Elixir for an AI startup backend, the broader case for the language choice itself, and running AI agents on the BEAM, the narrower case for why long-lived agent processes specifically want BEAM supervision.
The honest audit, run once a year, beats trusting a “cool libraries” thread that was accurate the year it was posted. If you want a second set of eyes on which dependencies are load-bearing versus quietly rotting in your own stack, that’s the kind of thing a fractional CTO engagement exists to catch before it’s an incident.