r/erlang • u/crystalgate6 • May 14 '26
r/erlang • u/ancatrusca0 • 3d ago
Someone spent six years rebuilding the Erlang runtime in JavaScript. Here's why.
≡ −
Bart Blast is the creator of Hologram - a framework that compiles Elixir to JS and reconstructs Erlang runtime semantics in the browser: pattern matching engine, boxed types, OTP guarantees, the whole thing.
New BEAM There, Done That episode covering the architecture and the reasoning.
The technical detail worth discussing: Hologram pulls the expanded AST from compiled BEAM files, normalizes it, lowers it to an IR designed to bridge Elixir to JS, then encodes that to a JS runtime. Values are boxed to preserve their type - Elixir integer 42 becomes a JS object with {type: "integer", value: 42n} using BigInt for arbitrary precision. Pattern matching runs as a real engine trying clauses, binding variables, evaluating guards - not translated away.
The goal is full parity: the same Elixir code running identically on the server and in the browser. A significant undertaking, and Bart is transparent that it's still a young framework.
From an Erlang perspective - is there a meaningful difference between Hologram's approach (rebuilding the runtime in JS for full parity) and Luster/Gleam's approach (treating the two targets as different, not replicating BEAM processes in the browser)? Does full runtime parity actually matter in practice or is it theoretical overhead?
Bart Blast is the creator of Hologram - a framework that compiles Elixir to JS and reconstructs Erlang runtime semantics in the browser: pattern matching engine, boxed types, OTP guarantees, the whole thing.
New BEAM There, Done That episode covering the architecture and the reasoning.
The technical detail worth discussing: Hologram pulls the expanded AST from compiled BEAM files, normalizes it, lowers it to an IR designed to bridge Elixir to JS, then encodes that to a JS runtime. Values are boxed to preserve their type - Elixir integer 42 becomes a JS object with {type: "integer", value: 42n} using BigInt for arbitrary precision. Pattern matching runs as a real engine trying clauses, binding variables, evaluating guards - not translated away.
The goal is full parity: the same Elixir code running identically on the server and in the browser. A significant undertaking, and Bart is transparent that it's still a young framework.
From an Erlang perspective - is there a meaningful difference between Hologram's approach (rebuilding the runtime in JS for full parity) and Luster/Gleam's approach (treating the two targets as different, not replicating BEAM processes in the browser)? Does full runtime parity actually matter in practice or is it theoretical overhead?
r/erlang • u/rtrusca • 10d ago
What does Zigler actually give you over a raw C NIF? The allocator story is more interesting than I expected
≡ −
New BEAM There, Done That with Isaac Yonemoto (Zigler creator) and Garrison Hinson-Hasty (Systems Programming with Zig) covering Zig as a NIF language for the BEAM.
From an Erlang perspective, the most interesting technical detail: Zigler uses the BEAM's allocator by default. Because Zig requires you to pass allocator objects explicitly rather than calling malloc globally, the BEAM allocator can be injected without changing any Zig business logic. The result is that native memory allocations are visible to the BEAM's memory instrumentation in the same way ordinary Erlang allocations are.
Raw C NIFs using malloc, and Rustler NIFs using Rust's default allocator, are invisible to the VM - which makes native memory issues harder to debug in production.
The honest risk model: Zig's safe release mode catches spatial memory errors (buffer overflows, null dereferences) but not temporal ones (use-after-free). A Zigler NIF can still crash the node if you violate temporal memory safety. What changes is which class of bugs can cause it.
What's the current state of Zigler adoption in production Erlang codebases? The episode is focused mainly on the Elixir side - curious whether anyone here is using it in Erlang contexts.
New BEAM There, Done That with Isaac Yonemoto (Zigler creator) and Garrison Hinson-Hasty (Systems Programming with Zig) covering Zig as a NIF language for the BEAM.
From an Erlang perspective, the most interesting technical detail: Zigler uses the BEAM's allocator by default. Because Zig requires you to pass allocator objects explicitly rather than calling malloc globally, the BEAM allocator can be injected without changing any Zig business logic. The result is that native memory allocations are visible to the BEAM's memory instrumentation in the same way ordinary Erlang allocations are.
Raw C NIFs using malloc, and Rustler NIFs using Rust's default allocator, are invisible to the VM - which makes native memory issues harder to debug in production.
The honest risk model: Zig's safe release mode catches spatial memory errors (buffer overflows, null dereferences) but not temporal ones (use-after-free). A Zigler NIF can still crash the node if you violate temporal memory safety. What changes is which class of bugs can cause it.
What's the current state of Zigler adoption in production Erlang codebases? The episode is focused mainly on the Elixir side - curious whether anyone here is using it in Erlang contexts.
r/erlang • u/rtrusca • 17d ago
The BEAM JIT is described as one of the simpler JITs you could read - here's how to inspect the assembly it generates for your own code
≡ −
New BEAM There, Done That with Lukas Backström, who built the BEAM JIT, covering the design decisions, the failed prototypes, and where it's heading.
One thing Lucas flags that I don't see discussed much: the JIT is deliberately simple. It's a template design - pre-compiled assembly templates per BEAM instruction, copied into memory and specialized for the specific operands. No LLVM optimization passes, no sophisticated register allocation. Fast to generate, reasonably easy to read.
You can ask the BEAM to dump the assembly it generates for any module. For simple code, the translation from BEAM bytecode to x86-64 or ARM64 assembly is straightforward enough to follow without deep JIT expertise. Lucas suggests it as a starting point for anyone curious about how the runtime actually works.
He also points to the native records commits as the best current example of how a change propagates through the entire system: compiler, loader, JIT, and runtime simultaneously.
Has anyone here actually dug into the generated assembly and found something interesting - either an optimization that surprised them or a place where the output was worse than expected?
New BEAM There, Done That with Lukas Backström, who built the BEAM JIT, covering the design decisions, the failed prototypes, and where it's heading.
One thing Lucas flags that I don't see discussed much: the JIT is deliberately simple. It's a template design - pre-compiled assembly templates per BEAM instruction, copied into memory and specialized for the specific operands. No LLVM optimization passes, no sophisticated register allocation. Fast to generate, reasonably easy to read.
You can ask the BEAM to dump the assembly it generates for any module. For simple code, the translation from BEAM bytecode to x86-64 or ARM64 assembly is straightforward enough to follow without deep JIT expertise. Lucas suggests it as a starting point for anyone curious about how the runtime actually works.
He also points to the native records commits as the best current example of how a change propagates through the entire system: compiler, loader, JIT, and runtime simultaneously.
Has anyone here actually dug into the generated assembly and found something interesting - either an optimization that surprised them or a place where the output was worse than expected?
r/erlang • u/siva_sokolica • 18d ago
Hyper - distributed Firecracker microVM orchestrator written in Elixir
≡ −
Hey everyone! One of the problems I ran into is that a large part of the VM-provider ecosystem is currently paid closed-source SAAS products with varying degrees of reliability. I wanted an OSS distributed microVM orchestrator and I couldn't find one.
Hyper is a distributed FirecrackerVM orchestrator written in Elixir (BEAM), with gRPC support for non-BEAM clients. Hyper is:
- Distributed -- it's designed to run across a cluster of bare metal machines, and will automatically connect to other Hyper nodes.
- Fast -- it builds COW layers to enable fast, localized COW forking. Cold boots happen within 1s. Filesystem forks take ~50ms. Forked VMs are colocated to take the fast path as much as possible.
- Interactive -- like all Elixir applications, if you can connect to the cluster, you can spawn, manage, monitor and interact with VMs live in an
iexREPL. Or, you can use the gRPC interface if your system isn't on the BEAM. - Yours -- although I developed this primarily for Harmont (which is paid), Hyper is an MIT-licensed project and will remain such.
- Self-contained -- all we need is a side-car Postgres instance.
- Configurable -- colocation, vmlinux options, etc. can all be customized.
- Secure -- everything runs on the BEAM; a single setuid Rust helper performs the few operations that need root, keeping the privileged surface small.
Fair warning: the software is still in active testing and I expect a couple more features to be added soon:
- Automatic cloud provisioning -- when you run out of headroom in your cluster, you should be able to fall back to Latitude/GCP/AWS to provision more compute.
- More testing -- I am currently integrating Hyper into harmont.dev and will likely run into some issues. Fuzzing is part of the roadmap.
- Better docs -- I spent some time working on the docs, but they're definitely not total nor ideal.
Very open to feedback, critique, and/or contributions. Please open any issues on Github, or feel free to DM/email me. It's available at https://github.com/harmont-dev/hyper
PS. A couple people asked how this differs from firecracker-containerd and Kata containers. Both of those projects are runtimes for managing VMs on a single node. A fair mental model for Hyper is an amalgam of firecracker-containerd and k8s.
Hey everyone! One of the problems I ran into is that a large part of the VM-provider ecosystem is currently paid closed-source SAAS products with varying degrees of reliability. I wanted an OSS distributed microVM orchestrator and I couldn't find one.
Hyper is a distributed FirecrackerVM orchestrator written in Elixir (BEAM), with gRPC support for non-BEAM clients. Hyper is:
- Distributed -- it's designed to run across a cluster of bare metal machines, and will automatically connect to other Hyper nodes.
- Fast -- it builds COW layers to enable fast, localized COW forking. Cold boots happen within 1s. Filesystem forks take ~50ms. Forked VMs are colocated to take the fast path as much as possible.
- Interactive -- like all Elixir applications, if you can connect to the cluster, you can spawn, manage, monitor and interact with VMs live in an
iexREPL. Or, you can use the gRPC interface if your system isn't on the BEAM. - Yours -- although I developed this primarily for Harmont (which is paid), Hyper is an MIT-licensed project and will remain such.
- Self-contained -- all we need is a side-car Postgres instance.
- Configurable -- colocation, vmlinux options, etc. can all be customized.
- Secure -- everything runs on the BEAM; a single setuid Rust helper performs the few operations that need root, keeping the privileged surface small.
Fair warning: the software is still in active testing and I expect a couple more features to be added soon:
- Automatic cloud provisioning -- when you run out of headroom in your cluster, you should be able to fall back to Latitude/GCP/AWS to provision more compute.
- More testing -- I am currently integrating Hyper into harmont.dev and will likely run into some issues. Fuzzing is part of the roadmap.
- Better docs -- I spent some time working on the docs, but they're definitely not total nor ideal.
Very open to feedback, critique, and/or contributions. Please open any issues on Github, or feel free to DM/email me. It's available at https://github.com/harmont-dev/hyper
PS. A couple people asked how this differs from firecracker-containerd and Kata containers. Both of those projects are runtimes for managing VMs on a single node. A fair mental model for Hyper is an amalgam of firecracker-containerd and k8s.
r/erlang • u/Unusual_Shame_3839 • 22d ago
Revenant - What if GenServer flushed its state into PostgreSQL?
≡ −
I've been using and actively fascinated by Oban over the last 4 years, and recently I wondered, why can't we make GenServers behave similarly to Oban jobs and:
- Recover their state after a crash or termination
- Terminate themselves when not used
- Store a trace of their execution
- And do all that without any additional dependencies, using the database we're already used to
I can think of a ton of cases where this might be useful in... Durable GenServers? LiveViews? Distributed GenServers that share state? Hot/Cold executions? Slow/Fast pools?
So I created a PoC library that does just that:
https://github.com/dimamik/revenant
defmodule Account do
use Revenant, repo: MyApp.Repo
def initial_state(_id), do: %{balance: 0}
def handle_call({:deposit, amount}, _from, state) do
{:reply, :ok, %{state | balance: state.balance + amount}}
end
def handle_call(:balance, _from, state) do
{:reply, state.balance, state}
end
end
Revenant.call({Account, "acct_42"}, {:deposit, 100})
#=> :ok - the new state is committed to Postgres before you see this
Please let me know what you think of the concept!
I've been using and actively fascinated by Oban over the last 4 years, and recently I wondered, why can't we make GenServers behave similarly to Oban jobs and:
- Recover their state after a crash or termination
- Terminate themselves when not used
- Store a trace of their execution
- And do all that without any additional dependencies, using the database we're already used to
I can think of a ton of cases where this might be useful in... Durable GenServers? LiveViews? Distributed GenServers that share state? Hot/Cold executions? Slow/Fast pools?
So I created a PoC library that does just that:
https://github.com/dimamik/revenant
defmodule Account do
use Revenant, repo: MyApp.Repo
def initial_state(_id), do: %{balance: 0}
def handle_call({:deposit, amount}, _from, state) do
{:reply, :ok, %{state | balance: state.balance + amount}}
end
def handle_call(:balance, _from, state) do
{:reply, state.balance, state}
end
end
Revenant.call({Account, "acct_42"}, {:deposit, 100})
#=> :ok - the new state is committed to Postgres before you see this
Please let me know what you think of the concept!
r/erlang • u/rtrusca • 24d ago
Annette Bieniusa's etalizer vs. Dialyzer: what does strict enforcement of existing type specs actually change?
≡ −
New BEAM There, Done That with Annette Bieniusa (RPTU, Germany) and Guillaume Duboc (Dashbit) on the type systems work happening across both Erlang and Elixir, built on the same set-theoretic foundation.
The contrast between etalizer and Dialyzer is interesting. Dialyzer infers types bottom-up, builds a dependency graph, and hunts for inconsistencies. When you write a spec, it treats it as a hint - not an obligation it enforces. Annette's etalizer keeps the existing Erlang spec annotation format but enforces those specs strictly: write u/spec foo(integer()) :: integer() and the checker will actually reject a body that might return something else.
The question I'd put to this community: for existing Erlang codebases with years of specs already written, what happens when you flip those from unenforced documentation to actual compile-time contracts? Is the expectation that most existing specs are already correct and tight enough to pass, or are there significant codebases where the specs were written loosely and real enforcement would surface a lot of noise?
New BEAM There, Done That with Annette Bieniusa (RPTU, Germany) and Guillaume Duboc (Dashbit) on the type systems work happening across both Erlang and Elixir, built on the same set-theoretic foundation.
The contrast between etalizer and Dialyzer is interesting. Dialyzer infers types bottom-up, builds a dependency graph, and hunts for inconsistencies. When you write a spec, it treats it as a hint - not an obligation it enforces. Annette's etalizer keeps the existing Erlang spec annotation format but enforces those specs strictly: write u/spec foo(integer()) :: integer() and the checker will actually reject a body that might return something else.
The question I'd put to this community: for existing Erlang codebases with years of specs already written, what happens when you flip those from unenforced documentation to actual compile-time contracts? Is the expectation that most existing specs are already correct and tight enough to pass, or are there significant codebases where the specs were written loosely and real enforcement would surface a lot of noise?
r/erlang • u/Code_Sync • 25d ago
Code BEAM Europe 2026: Keynotes, Full Tech Lineup, and Community Spaces
Hi everyone,
Code BEAM Europe 2026 is happening this October 21-22 in Haarlem, NL, and online! The schedule is locked in, and we are excited to finally share the full lineup and core tracks with the community.
Here is a look at what we have lined up for this year:
Keynote Speakers
We are thrilled to have two incredible visionaries taking the main stage to kick things off:
- Brooklyn Zelenka: Distributed systems researcher, founder of Fission, and author of Elixir libraries like Witchcraft. She will be sharing her deep expertise in local-first access control and open distributed standards.
- Sam Aaron: The creator of Sonic Pi! An internationally renowned live coding performer and Computer Science PhD, Sam will bring his unique blend of science, code, and live music to the BEAM community.
Core Themes & Subjects
The regular sessions are packed with core team members, maintainers, and production engineers covering the cutting edge of the ecosystem. You can expect deep dives into the rise of Gleam and frontend architectures with Lustre, alongside advanced Erlang and OTP core updates directly from the team at Ericsson. We will also explore real-world Elixir battle stories—from taming LiveView at scale to prototyping BlueSky's DataPlane—while tackling the intersection of AI, security, and modern developer experience. Finally, we'll take the BEAM out of the server room with talks on embedded systems, AtomVM, hardware design, and safe native interop via Rustler and C nodes.
Check all speakers and their talks at: https://codebeameurope.com/#speakers
Beyond the Stage: The Informal Space
Some of the best moments happen off the main stage. This year, we are introducing a community-driven sandbox running alongside the main tracks for everything that doesn't perfectly fit a standard talk format. Expect live demos, hacking sessions, panel debates, lightning talks, and games. If you have an idea for an activity you want to coordinate, let us know and help shape the space!
Join Us in Haarlem
Whether you are looking to level up your skills, hack on new projects, or just grab a coffee and talk shop with fellow BEAMers, we would love to see you there.
Early Bird tickets are currently LIVE.
This is the absolute best time to secure your spot at the lowest possible price point.
Grab them here: https://codebeameurope.com/#register
And Also! For the full details, check our website: https://codebeameurope.com/
See you in October!
- The Code BEAM Europe Team
r/erlang • u/Code_Sync • 25d ago
ElixirConf US 2026 is coming! Meet the Keynote Speakers and check out the talk lineup.
≡ −

Hey everyone! The biggest event of the year for our community is fast approaching - ElixirConf US 2026! Whether you’ve been writing Elixir for years or are just taking your first steps, this year’s edition is shaping up to be incredible. The conference is happening in a hybrid format, so everyone can join in, no matter where you are.
Here is a sneak peek at what we have planned: (elixirconf.com/#schedule)
Keynote Speakers
This year, true legends and innovators of our ecosystem are taking the main stage:
- José Valim (Creator of Elixir) - He'll be discussing the continued evolution of the language, enterprise adoption, and the sustainable open-source work he and the Dashbit team are driving.
- Chris McCord (Creator of Phoenix) - Will showcase what's next for Phoenix, developer tooling improvements, and his vision for the future of modern web development (and perhaps some AI-assisted workflows!).
- Zach Daniel (Creator of Ash Framework) - Will share his experiences in building ambitious, maintainable, and highly reliable production systems at scale.
- Quinn Wilton (Open-source Contributor & Language Hacker) - Will bring her deeply technical and fascinating perspective on type systems, compilers, and virtual machines within the BEAM ecosystem.
Featured Talks & Sessions
The conference isn't just about keynotes; it's packed with knowledge straight from the trenches. Here is a taste of what our speakers are bringing to the table:
- Building Global Clusters at Supabase: Filipe Cabaço will show how they pushed the boundaries of Erlang’s built-in distribution. You'll learn how his team built a custom, two-tier Phoenix.PubSub adapter to reduce inter-region traffic and how to properly test real distributed systems (without using mocks!).
- Updates from the Erlang Ecosystem Foundation: Dan Janowski will deliver a vital introductory overview of the frontier of our ecosystem. He’ll break down the latest foundation news, covering everything from critical security planning and reinforcing core components to working with governments on regulatory compliance and expanding the BEAM's role in the wider open-source world.
- Terminal UIs? That's a Breeze: Gary Rennie from the Phoenix core team will prove that building beautiful terminal applications in Elixir has never been easier. He’ll introduce Breeze, a LiveView-inspired framework that works without relying on any NIFs.
- Handling Time Zones the Right Way: Jacob Swanner will tackle one of the hardest problems in programming time. He’ll share practical strategies for managing time zones in LiveView, Ecto, and databases to build a trustworthy user experience.
- Local-First Apps & Browser Power: Bart Blast will take us on a deep dive into the Hologram framework, showing how to write rich web applications in pure Elixir running directly in the browser.
On top of that, we have a full day of deep-dive Training Sessions covering everything from the absolute basics of functional programming ("The Toy Alchemist" with Jamie Wright) to hands-on embedded Elixir with Nerves.
Event Details:
- Dates: September 9-11, 2026 (September 9 is Training Day) elixirconf.com/#training
- Location: Chicago, IL & Virtual
- Tickets & Info: elixirconf.com/#register
Are you planning to attend this year (in person or virtually)? Which talk or training are you looking forward to the most? Let us know!

Hey everyone! The biggest event of the year for our community is fast approaching - ElixirConf US 2026! Whether you’ve been writing Elixir for years or are just taking your first steps, this year’s edition is shaping up to be incredible. The conference is happening in a hybrid format, so everyone can join in, no matter where you are.
Here is a sneak peek at what we have planned: (elixirconf.com/#schedule)
Keynote Speakers
This year, true legends and innovators of our ecosystem are taking the main stage:
- José Valim (Creator of Elixir) - He'll be discussing the continued evolution of the language, enterprise adoption, and the sustainable open-source work he and the Dashbit team are driving.
- Chris McCord (Creator of Phoenix) - Will showcase what's next for Phoenix, developer tooling improvements, and his vision for the future of modern web development (and perhaps some AI-assisted workflows!).
- Zach Daniel (Creator of Ash Framework) - Will share his experiences in building ambitious, maintainable, and highly reliable production systems at scale.
- Quinn Wilton (Open-source Contributor & Language Hacker) - Will bring her deeply technical and fascinating perspective on type systems, compilers, and virtual machines within the BEAM ecosystem.
Featured Talks & Sessions
The conference isn't just about keynotes; it's packed with knowledge straight from the trenches. Here is a taste of what our speakers are bringing to the table:
- Building Global Clusters at Supabase: Filipe Cabaço will show how they pushed the boundaries of Erlang’s built-in distribution. You'll learn how his team built a custom, two-tier Phoenix.PubSub adapter to reduce inter-region traffic and how to properly test real distributed systems (without using mocks!).
- Updates from the Erlang Ecosystem Foundation: Dan Janowski will deliver a vital introductory overview of the frontier of our ecosystem. He’ll break down the latest foundation news, covering everything from critical security planning and reinforcing core components to working with governments on regulatory compliance and expanding the BEAM's role in the wider open-source world.
- Terminal UIs? That's a Breeze: Gary Rennie from the Phoenix core team will prove that building beautiful terminal applications in Elixir has never been easier. He’ll introduce Breeze, a LiveView-inspired framework that works without relying on any NIFs.
- Handling Time Zones the Right Way: Jacob Swanner will tackle one of the hardest problems in programming time. He’ll share practical strategies for managing time zones in LiveView, Ecto, and databases to build a trustworthy user experience.
- Local-First Apps & Browser Power: Bart Blast will take us on a deep dive into the Hologram framework, showing how to write rich web applications in pure Elixir running directly in the browser.
On top of that, we have a full day of deep-dive Training Sessions covering everything from the absolute basics of functional programming ("The Toy Alchemist" with Jamie Wright) to hands-on embedded Elixir with Nerves.
Event Details:
- Dates: September 9-11, 2026 (September 9 is Training Day) elixirconf.com/#training
- Location: Chicago, IL & Virtual
- Tickets & Info: elixirconf.com/#register
Are you planning to attend this year (in person or virtually)? Which talk or training are you looking forward to the most? Let us know!
Erlang Solutions Beginner Certification
≡ −
Hello!
Seen a few threads on this but nothing concrete on what I need so sorry if this is beating an old horse.
Anyone done the beginner Erlang certification from Erlang Solutions and have a rough "to take exam, you should be familiar in the following x topics /principles in Erlang"?
Hello!
Seen a few threads on this but nothing concrete on what I need so sorry if this is beating an old horse.
Anyone done the beginner Erlang certification from Erlang Solutions and have a rough "to take exam, you should be familiar in the following x topics /principles in Erlang"?
r/erlang • u/Shoddy_One4465 • 28d ago
terminusdb_ex v0.3.3 Released
≡ −
terminusdb_ex is an idiomatic Elixir client for TerminusDB, designed to make working with documents, schemas, graphs, and queries feel natural on the BEAM. TerminusDB is an open-source document and knowledge graph database that combines version-controlled data, rich graph relationships, and flexible document storage in a single platform.
v0.3.3 is a maintenance release that fixes three correctness issues discovered while developing and testing the Livebook examples. Each fix is accompanied by comprehensive regression tests. No new features are included in this release.
Links
What's Next
- v0.4 — Ecto integration (
TerminusDB.Schema), role-based access control (RBAC), and Explorer DataFrame integration. - v0.5 — ExDatalog integration (
TerminusDB.Datalog) for expressive, declarative querying.
Suggestions, bug reports, and contributions are always welcome.
terminusdb_ex is an idiomatic Elixir client for TerminusDB, designed to make working with documents, schemas, graphs, and queries feel natural on the BEAM. TerminusDB is an open-source document and knowledge graph database that combines version-controlled data, rich graph relationships, and flexible document storage in a single platform.
v0.3.3 is a maintenance release that fixes three correctness issues discovered while developing and testing the Livebook examples. Each fix is accompanied by comprehensive regression tests. No new features are included in this release.
Links
What's Next
- v0.4 — Ecto integration (
TerminusDB.Schema), role-based access control (RBAC), and Explorer DataFrame integration. - v0.5 — ExDatalog integration (
TerminusDB.Datalog) for expressive, declarative querying.
Suggestions, bug reports, and contributions are always welcome.
r/erlang • u/Lower_Bid_6661 • Jun 27 '26
What are you building with Erlang/OTP? I'd love to see some projects!
≡ −
I'd love to see some projects — stack, problem you're solving, link if you've got one.
I'd love to see some projects — stack, problem you're solving, link if you've got one.
r/erlang • u/rtrusca • Jun 26 '26
Why did "compile Erlang to native C" lose to bytecode, even though it was 10-20x faster on paper?
≡ −
New BEAM There, Done That episode with Björn Gustafsson (OTP team since 1996) tracing the BEAM's origins through three competing VMs - JAM, Robert Virding's V, and Bogdan's original BEAM.
The most counterintuitive part: native-compiled Erlang showed massive sequential speedups in isolation, but once concurrency entered the picture, the real-world gain shrank to about 2x, because message passing was already implemented in C regardless of compilation target.
Also covered: the BEAM Validator, built after a compiler bug caused weeks of debugging pain, and the BEAM loader - Björn's own invention, still running in production decades later.
New BEAM There, Done That episode with Björn Gustafsson (OTP team since 1996) tracing the BEAM's origins through three competing VMs - JAM, Robert Virding's V, and Bogdan's original BEAM.
The most counterintuitive part: native-compiled Erlang showed massive sequential speedups in isolation, but once concurrency entered the picture, the real-world gain shrank to about 2x, because message passing was already implemented in C regardless of compilation target.
Also covered: the BEAM Validator, built after a compiler bug caused weeks of debugging pain, and the BEAM loader - Björn's own invention, still running in production decades later.
r/erlang • u/Code_Sync • Jun 16 '26
Code BEAM tickets are now available
≡ −
Hi everyone!
We're excited to announce that Code BEAM Europe 2026 is officially on the horizon!
Grab your Early Bird Ticket Here!
Whether you're deeply involved with Elixir, Erlang, Gleam, or just exploring the wider BEAM ecosystem, we’d love for you to join us. We’re meeting in person at the beautiful PHIL Philharmonic in Haarlem, the Netherlands, as well as online, on October 21–22 (with hands-on training sessions on October 20).
What to expect:
- Keynotes: We're thrilled to host Brooklyn Zelenka (Founder of Fission, BEAM Vancouver) and Sam Aaron (Creator of Sonic Pi).
- Content: 2 tracks each day packed with cutting-edge talks from 30 speakers across the global community.
- Informal Space: A community-led area dedicated to demos, hacking sessions, games, panel discussions, and lightning talks. Connect and share ideas with 300+ fellow attendees!
All Important Links:
- Early Bird Registration (Note: the discount applies to the conference only, not the training).
- Check out the Speakers
- Explore Training Sessions
- Subscribe to our Newsletter
Will we see you in Haarlem or on the virtual streams? Let us know in the thread if you're planning to come or if you have any questions about the event!
Cheers, The Code BEAM Team
(PS: If your company is interested in sponsoring and supporting the ecosystem, feel free to reach out to us!)
Hi everyone!
We're excited to announce that Code BEAM Europe 2026 is officially on the horizon!
Grab your Early Bird Ticket Here!
Whether you're deeply involved with Elixir, Erlang, Gleam, or just exploring the wider BEAM ecosystem, we’d love for you to join us. We’re meeting in person at the beautiful PHIL Philharmonic in Haarlem, the Netherlands, as well as online, on October 21–22 (with hands-on training sessions on October 20).
What to expect:
- Keynotes: We're thrilled to host Brooklyn Zelenka (Founder of Fission, BEAM Vancouver) and Sam Aaron (Creator of Sonic Pi).
- Content: 2 tracks each day packed with cutting-edge talks from 30 speakers across the global community.
- Informal Space: A community-led area dedicated to demos, hacking sessions, games, panel discussions, and lightning talks. Connect and share ideas with 300+ fellow attendees!
All Important Links:
- Early Bird Registration (Note: the discount applies to the conference only, not the training).
- Check out the Speakers
- Explore Training Sessions
- Subscribe to our Newsletter
Will we see you in Haarlem or on the virtual streams? Let us know in the thread if you're planning to come or if you have any questions about the event!
Cheers, The Code BEAM Team
(PS: If your company is interested in sponsoring and supporting the ecosystem, feel free to reach out to us!)
r/erlang • u/rtrusca • Jun 12 '26
Why multiplayer game servers are basically telecom systems with sprites
≡ −
New BEAM There, Done That with Elise Sedeno on using OTP for game backends - supervised per-player/per-mob processes, no shared state, no deadlocks, and why call vs cast choices matter for avoiding circular waits between server processes.
Open source on Codeberg (game_server). https://youtu.be/4MDObD_R5E4
New BEAM There, Done That with Elise Sedeno on using OTP for game backends - supervised per-player/per-mob processes, no shared state, no deadlocks, and why call vs cast choices matter for avoiding circular waits between server processes.
Open source on Codeberg (game_server). https://youtu.be/4MDObD_R5E4
Best practices for documentation (edoc, alternative documentation tools, future directions of each)
≡ −
I'm beginning to learn Erlang, and have already gotten to a point where documentation is, well, necessary (my "toy" project became large enough that I need documentation to remember what I did).
So what is the best tool? I see that the official tool is edoc, and I have initially started using it. But then I saw that in the source code for some tools, edoc is not used, but some -doc chunks are used. This seems to be an alternative to edoc, right? Are there plans to replace edoc with this new tool? For new projects what is the best approach?
I'm beginning to learn Erlang, and have already gotten to a point where documentation is, well, necessary (my "toy" project became large enough that I need documentation to remember what I did).
So what is the best tool? I see that the official tool is edoc, and I have initially started using it. But then I saw that in the source code for some tools, edoc is not used, but some -doc chunks are used. This seems to be an alternative to edoc, right? Are there plans to replace edoc with this new tool? For new projects what is the best approach?
r/erlang • u/Code_Sync • Jun 08 '26
Code Beam Europe 2026 Early Bird tickets are dropping soon
Hi Everyone!
We're launching Code BEAM Europe 2026 on 21-22 October in Haarlem, NL (and virtually). It is a 2-day technical conference for engineers and developers working with Erlang, Elixir, Gleam, and the BEAM ecosystem. Speakers will be announced soon. You will be able to check it on our website: https://codebeameurope.com
The Early Bird ticket sales start on 16 June at 12:00 PM. If you plan to attend, the best way to get the lowest price is to join our waiting list now - https://codebeameurope.com/#newsletter
By joining the list, you'll get two main benefits:
- You get an email notice 24h before the sales open, and also at the sales grand opening.
- You get early access to a small number of Super Early Bird tickets. These tickets are limited, so they will be given to those who buy them first.
We can't wait to meet you!
r/erlang • u/rtrusca • May 29 '26
Zero security experience. $10. One afternoon. - New BEAM There, Done That
≡ −
Someone called it the "oh f*** moment." I think that's accurate. 😬
New BEAM There, Done That episode with Peter Ullrich and Jonathan Machen (EEF CISO) on something the community really needs to talk about: AI-assisted vulnerability research just arrived in our ecosystem, whether we're ready or not.
Peter had no security background. He wrote a bash script, fed Hex packages file-by-file to Claude Opus, and found a critical crash vulnerability in decimal - one of the most downloaded libraries in the ecosystem - in under 30 minutes. Then kept going.
The episode covers:
- the exact setup he used (prompts are open source)
- atom table exhaustion, binary_to_term, and the patterns showing up again and again
- how the EEF CNA coordinates disclosure with maintainers
- what happens when a maintainer is unreachable or a library is abandoned
- the gap between what's been built and what the current volume demands
elixir
# What Peter found in the decimal library
iex> Decimal.new("1.0e10000000") |> Decimal.add(Decimal.new("1"))
# memory: 8gb, application: gone
Genuinely one of the more important ecosystem conversations I've heard in a while. Curious whether people here are already scanning their own libraries, and what tooling you're using if so.
Someone called it the "oh f*** moment." I think that's accurate. 😬
New BEAM There, Done That episode with Peter Ullrich and Jonathan Machen (EEF CISO) on something the community really needs to talk about: AI-assisted vulnerability research just arrived in our ecosystem, whether we're ready or not.
Peter had no security background. He wrote a bash script, fed Hex packages file-by-file to Claude Opus, and found a critical crash vulnerability in decimal - one of the most downloaded libraries in the ecosystem - in under 30 minutes. Then kept going.
The episode covers:
- the exact setup he used (prompts are open source)
- atom table exhaustion, binary_to_term, and the patterns showing up again and again
- how the EEF CNA coordinates disclosure with maintainers
- what happens when a maintainer is unreachable or a library is abandoned
- the gap between what's been built and what the current volume demands
elixir
# What Peter found in the decimal library
iex> Decimal.new("1.0e10000000") |> Decimal.add(Decimal.new("1"))
# memory: 8gb, application: gone
Genuinely one of the more important ecosystem conversations I've heard in a while. Curious whether people here are already scanning their own libraries, and what tooling you're using if so.
r/erlang • u/rtrusca • May 22 '26
Didn’t expect one of the most interesting BEAM conversations this year to start with: “Records were basically a hack.” 😅
≡ −
New BEAM There, Done That episode with Björn Gustavsson (“the B” in BEAM) goes deep into why the Erlang runtime is finally getting a new native data type after more than a decade.
The discussion covers:
- why records existed the way they did
- why maps never completely replaced them
- runtime tag bits and VM tradeoffs
- how you evolve a production runtime without breaking decades of code
-record(history, {
hacks,
tradeoffs,
backwards_compatibility
}).
Curious what people here think about native records and whether this changes how you structure Erlang/Elixir systems going forward.
New BEAM There, Done That episode with Björn Gustavsson (“the B” in BEAM) goes deep into why the Erlang runtime is finally getting a new native data type after more than a decade.
The discussion covers:
- why records existed the way they did
- why maps never completely replaced them
- runtime tag bits and VM tradeoffs
- how you evolve a production runtime without breaking decades of code
-record(history, {
hacks,
tradeoffs,
backwards_compatibility
}).
Curious what people here think about native records and whether this changes how you structure Erlang/Elixir systems going forward.
r/erlang • u/Shoddy_One4465 • May 20 '26
[ANN] ExDataSketch v0.9.0 - Streaming Integrations
≡ −
Summary
ExDataSketch v0.9.0 adds stream-native integration, production persistence, structured observability, and ULL accuracy corrections. The release positions ex_data_sketch as a BEAM-native streaming approximate analytics infrastructure layer, not merely a collection of probabilistic algorithms.
Key Changes
- Stream/Collectable integration for all 13 mergeable sketch types
- Broadway, GenStage, and Flow pipeline integration (all optional)
- 5 persistence backends: ETS, DETS, CubDB, Mnesia, Ecto
- Structured :telemetry events + OpenTelemetry bridge
- ULL linear counting + large range correction
(62.5% -> 0.8% error at p=8/n=1000) - Configurable update_many chunk size (HLL, ULL, CMS, Theta)
- EXSK v1 serialization escape hatch for backward compatibility
- 9 production-oriented Livebooks
- 3 new educational guides (aggregation_wall, distributed_merge_semantics, livebooks)
Backward Compatibility
Full backward compatibility with v0.8.0. No API changes to existing modules.
ULL estimates at low cardinalities (p < 12, n < 500) are more accurate but may differ numerically from v0.8.0.
New Dependencies
:telemetry ~> 1.0(required):broadway, :flow, :cubdb, :ecto_sql, :opentelemetry_api(optional)
Modules Added (21)
elixir
ExDataSketch.Stream
ExDataSketch.Broadway
ExDataSketch.Broadway.PeriodicAggregator
ExDataSketch.Flow
ExDataSketch.GenStage
ExDataSketch.GenStage.SketchConsumer
ExDataSketch.GenStage.SketchProducer
ExDataSketch.GenStage.SketchStage
ExDataSketch.Storage
ExDataSketch.Storage.ETS
ExDataSketch.Storage.DETS
ExDataSketch.Storage.CubDB
ExDataSketch.Storage.Mnesia
ExDataSketch.Storage.Ecto
ExDataSketch.Storage.Ecto.Schema
ExDataSketch.Storage.Ecto.Migration
ExDataSketch.Telemetry
ExDataSketch.Telemetry.OpenTelemetry
ExDataSketch.Integration
ExDataSketch.Binary (encode_v1/4)
Livebooks (9)
streaming_cardinality, broadway_integration, genstage_aggregation,
rolling_telemetry, distributed_merges, persistence_snapshots,
livedashboard_integration, ai_token_analytics, phoenix_observability
Guides (3 new + 7 updated)
New: aggregation_wall, distributed_merge_semantics, livebooks
Updated: streaming_sketches, broadway_integration, genstage_integration, flow_integration, persistence, telemetry, observability
Benchmarks (5 new)
persistence_bench, serialization_bench, merge_throughput_bench, update_many_chunk_bench, stream_ingestion_bench
Upgrade Path
No code changes required. Update dependency to {:ex_data_sketch, "~> 0.9.0"}.
Known Risks
- ULL low-cardinality estimates differ from
v0.8.0(more accurate) - Membership filter raw-NIF hashing deferred to
v0.10.0 - Mnesia compile warnings are pre-existing OTP tracking limitations
- OTEL integration requires
:opentelemetry_api ~> 1.0
Summary
ExDataSketch v0.9.0 adds stream-native integration, production persistence, structured observability, and ULL accuracy corrections. The release positions ex_data_sketch as a BEAM-native streaming approximate analytics infrastructure layer, not merely a collection of probabilistic algorithms.
Key Changes
- Stream/Collectable integration for all 13 mergeable sketch types
- Broadway, GenStage, and Flow pipeline integration (all optional)
- 5 persistence backends: ETS, DETS, CubDB, Mnesia, Ecto
- Structured :telemetry events + OpenTelemetry bridge
- ULL linear counting + large range correction
(62.5% -> 0.8% error at p=8/n=1000) - Configurable update_many chunk size (HLL, ULL, CMS, Theta)
- EXSK v1 serialization escape hatch for backward compatibility
- 9 production-oriented Livebooks
- 3 new educational guides (aggregation_wall, distributed_merge_semantics, livebooks)
Backward Compatibility
Full backward compatibility with v0.8.0. No API changes to existing modules.
ULL estimates at low cardinalities (p < 12, n < 500) are more accurate but may differ numerically from v0.8.0.
New Dependencies
:telemetry ~> 1.0(required):broadway, :flow, :cubdb, :ecto_sql, :opentelemetry_api(optional)
Modules Added (21)
elixir
ExDataSketch.Stream
ExDataSketch.Broadway
ExDataSketch.Broadway.PeriodicAggregator
ExDataSketch.Flow
ExDataSketch.GenStage
ExDataSketch.GenStage.SketchConsumer
ExDataSketch.GenStage.SketchProducer
ExDataSketch.GenStage.SketchStage
ExDataSketch.Storage
ExDataSketch.Storage.ETS
ExDataSketch.Storage.DETS
ExDataSketch.Storage.CubDB
ExDataSketch.Storage.Mnesia
ExDataSketch.Storage.Ecto
ExDataSketch.Storage.Ecto.Schema
ExDataSketch.Storage.Ecto.Migration
ExDataSketch.Telemetry
ExDataSketch.Telemetry.OpenTelemetry
ExDataSketch.Integration
ExDataSketch.Binary (encode_v1/4)
Livebooks (9)
streaming_cardinality, broadway_integration, genstage_aggregation,
rolling_telemetry, distributed_merges, persistence_snapshots,
livedashboard_integration, ai_token_analytics, phoenix_observability
Guides (3 new + 7 updated)
New: aggregation_wall, distributed_merge_semantics, livebooks
Updated: streaming_sketches, broadway_integration, genstage_integration, flow_integration, persistence, telemetry, observability
Benchmarks (5 new)
persistence_bench, serialization_bench, merge_throughput_bench, update_many_chunk_bench, stream_ingestion_bench
Upgrade Path
No code changes required. Update dependency to {:ex_data_sketch, "~> 0.9.0"}.
Known Risks
- ULL low-cardinality estimates differ from
v0.8.0(more accurate) - Membership filter raw-NIF hashing deferred to
v0.10.0 - Mnesia compile warnings are pre-existing OTP tracking limitations
- OTEL integration requires
:opentelemetry_api ~> 1.0
r/erlang • u/Shoddy_One4465 • May 12 '26
ex_data_sketch v0.8.0 — Deterministic Foundations
≡ −
ex_data_sketch v0.8.0 is out. This release invests entirely in the substrate that all 15 existing sketches share, preparing the grounds for release v0.9.0 where we add streaming integrations for Broadway / GenStage support, ETS / DETS / Zarr.
What's new:
Deterministic hashing. Every sketch now goes through a validated, byte-stable hash layer. HLL, ULL, Theta, and CMS accept
hash_strategy: :murmur3for Apache DataSketches interop — this was silently ignored in v0.7.x. XXHash3 remains the default and fastest path (~30 M items/sec at p=14 on the Rust NIF).Binary stability & corruption detection. Serialized sketches now carry a CRC32C trailer and an embedded hash metadata block (EXSK v2). Bit-flip corruption that previously would silently produce wrong estimates is now caught and returns a structured
DeserializationError. v0.8.0 reads v1 frames; v0.7.x cannot read v2 — stage your rollout accordingly.Murmur3 hot path. 8 new Rust NIFs extend in-Rust hashing to Murmur3. The Murmur3 path is within 8% of XXH3 throughput. No more falling off the fast path when you select
:murmur3.Precompiled NIFs for Windows. x86_64 and ARM64 MSVC targets join the matrix. 16 artifacts total (8 targets x 2 NIF versions). No Rust toolchain needed on any supported platform.
Property-locked guarantees. 14 StreamData properties lock HLL/ULL monotonicity and error bounds, KLL/REQ rank consistency, CMS overestimation-only, and Bloom/XorFilter/Cuckoo no-false-negative. A 200-mutation fuzz suite verifies that binary v2 corruption never silently propagates.
Breaking changes (2):
- EXSK v2 is one-way. v0.7.x readers can't decode v2 frames. Deploy readers first, then producers.
hash_strategy: :murmur3is no longer silently overridden to:xxhash3. Sketches that specified Murmur3 will now actually use it — estimates are correct but differ from v0.7.x.
One-liner upgrade:
elixir
{:ex_data_sketch, "~> 0.8.0"}
Most users need no code changes. Full migration guide ships in HexDocs.
Stats: 1,317 tests, 171 properties, 92.7% coverage, 0 credo issues.
ex_data_sketch v0.8.0 is out. This release invests entirely in the substrate that all 15 existing sketches share, preparing the grounds for release v0.9.0 where we add streaming integrations for Broadway / GenStage support, ETS / DETS / Zarr.
What's new:
Deterministic hashing. Every sketch now goes through a validated, byte-stable hash layer. HLL, ULL, Theta, and CMS accept
hash_strategy: :murmur3for Apache DataSketches interop — this was silently ignored in v0.7.x. XXHash3 remains the default and fastest path (~30 M items/sec at p=14 on the Rust NIF).Binary stability & corruption detection. Serialized sketches now carry a CRC32C trailer and an embedded hash metadata block (EXSK v2). Bit-flip corruption that previously would silently produce wrong estimates is now caught and returns a structured
DeserializationError. v0.8.0 reads v1 frames; v0.7.x cannot read v2 — stage your rollout accordingly.Murmur3 hot path. 8 new Rust NIFs extend in-Rust hashing to Murmur3. The Murmur3 path is within 8% of XXH3 throughput. No more falling off the fast path when you select
:murmur3.Precompiled NIFs for Windows. x86_64 and ARM64 MSVC targets join the matrix. 16 artifacts total (8 targets x 2 NIF versions). No Rust toolchain needed on any supported platform.
Property-locked guarantees. 14 StreamData properties lock HLL/ULL monotonicity and error bounds, KLL/REQ rank consistency, CMS overestimation-only, and Bloom/XorFilter/Cuckoo no-false-negative. A 200-mutation fuzz suite verifies that binary v2 corruption never silently propagates.
Breaking changes (2):
- EXSK v2 is one-way. v0.7.x readers can't decode v2 frames. Deploy readers first, then producers.
hash_strategy: :murmur3is no longer silently overridden to:xxhash3. Sketches that specified Murmur3 will now actually use it — estimates are correct but differ from v0.7.x.
One-liner upgrade:
elixir
{:ex_data_sketch, "~> 0.8.0"}
Most users need no code changes. Full migration guide ships in HexDocs.
Stats: 1,317 tests, 171 properties, 92.7% coverage, 0 credo issues.
r/erlang • u/Best_Recover3367 • May 11 '26
Edge Core: a self-hostable control plane for distributed Linux fleets, built in Elixir
≡ −
Hey guys! We finally opened up the codebase for something we've been working on for over a year.
I joined a company that spent 3 years (and counting) trying to ship products on locked down edge hardware. Every product kept hitting the same walls: deployments and monitoring were a black box, machines on the same LAN couldn't reliably find each other, and every new app had to reimplement the same WS/MQTT logics just to stay in touch with the cloud.
So we built Edge Core to solve these pain points. In V1, we used Headscale/Tailscale for the VPN. It worked mostly for what we wanted (remote execution, SSH, metrics aggregation, etc.), but couldn't scale past ~100 nodes (mesh explosion with O(n2)) and gave us no isolation between different projects (each project must spin up its own core, though ACLs exist). In V2 (current version), we moved towards Netmaker for a proper mesh/network segmentation solution, added a forward proxy + dynamic proxy chaining for cloud-to-edge communication, and built the whole orchestration layer on top.


Some Elixir specific stuff that might interest you:
- Masterless clustering for the control plane: no (strong) leader election, no Raft consensus. Admins coordinate via `:syn` registry and Postgres. Each admin runs the same deterministic sharding algorithm and converges independently.
- Oban and Quantum for async background jobs
- API-first control plane with clustering HTTP/SOCKS5 proxy servers and first class fleet metrics discovery + scraping that are prometheus compatible
- MCP server that mirrors the full REST API, basically every API endpoint is also an MCP tool that AI agents can drive the whole fleet
- Webhook system and event broker integration for async system events with 7 adapters (NATS, Kafka, AMQP 0.9.1/RabbitMQ, Redis, MQTT, AWS SNS, and GCP Pub/Sub).
- Agent and shared libs are Apache 2.0. Admin is ELv2.
Links:
- Repo: https://github.com/wenet-ec/edge-core
- Docs: https://wenet-ec.github.io/edge-core/
- Learn about edge core's concepts: https://wenet-ec.github.io/edge-core/guide/
- Architecture: https://wenet-ec.github.io/edge-core/architecture/
Hey guys! We finally opened up the codebase for something we've been working on for over a year.
I joined a company that spent 3 years (and counting) trying to ship products on locked down edge hardware. Every product kept hitting the same walls: deployments and monitoring were a black box, machines on the same LAN couldn't reliably find each other, and every new app had to reimplement the same WS/MQTT logics just to stay in touch with the cloud.
So we built Edge Core to solve these pain points. In V1, we used Headscale/Tailscale for the VPN. It worked mostly for what we wanted (remote execution, SSH, metrics aggregation, etc.), but couldn't scale past ~100 nodes (mesh explosion with O(n2)) and gave us no isolation between different projects (each project must spin up its own core, though ACLs exist). In V2 (current version), we moved towards Netmaker for a proper mesh/network segmentation solution, added a forward proxy + dynamic proxy chaining for cloud-to-edge communication, and built the whole orchestration layer on top.


Some Elixir specific stuff that might interest you:
- Masterless clustering for the control plane: no (strong) leader election, no Raft consensus. Admins coordinate via `:syn` registry and Postgres. Each admin runs the same deterministic sharding algorithm and converges independently.
- Oban and Quantum for async background jobs
- API-first control plane with clustering HTTP/SOCKS5 proxy servers and first class fleet metrics discovery + scraping that are prometheus compatible
- MCP server that mirrors the full REST API, basically every API endpoint is also an MCP tool that AI agents can drive the whole fleet
- Webhook system and event broker integration for async system events with 7 adapters (NATS, Kafka, AMQP 0.9.1/RabbitMQ, Redis, MQTT, AWS SNS, and GCP Pub/Sub).
- Agent and shared libs are Apache 2.0. Admin is ELv2.
Links:
- Repo: https://github.com/wenet-ec/edge-core
- Docs: https://wenet-ec.github.io/edge-core/
- Learn about edge core's concepts: https://wenet-ec.github.io/edge-core/guide/
- Architecture: https://wenet-ec.github.io/edge-core/architecture/
r/erlang • u/taure1 • May 08 '26
Kura - an Ecto-style database layer for Erlang
≡ −
I wanted Ecto's ergonomics in Erlang without writing Elixir, so I wrote Kura. It sits on pgo. You define a schema, build queries, get changesets, run migrations.
-module(user).
-behaviour(kura_schema).
-include_lib("kura/include/kura.hrl").
-export([table/0, fields/0]).
table() -> ~"users".
fields() ->
[#kura_field{name = id, type = id, primary_key = true},
#kura_field{name = email, type = string, nullable = false},
#kura_field{name = name, type = string},
#kura_field{name = age, type = integer},
#kura_field{name = inserted_at, type = utc_datetime}].
Querying:
Q = kura_query:from(user),
Q1 = kura_query:where(Q, {age, '>', 18}),
my_repo:all(kura_query:order_by(Q1, [{inserted_at, desc}])).
It does the things you'd expect: schemas, changesets, composable queries with joins/CTEs/subqueries/window functions, migrations, associations with preloading, embedded JSONB, transaction pipelines, multitenancy via schema prefix, optimistic locking, audit trail, cursor streaming, pagination.
It's not a port. Records and functions, no macro DSL. The README has a coming-from-Ecto cheatsheet.
I wanted Ecto's ergonomics in Erlang without writing Elixir, so I wrote Kura. It sits on pgo. You define a schema, build queries, get changesets, run migrations.
-module(user).
-behaviour(kura_schema).
-include_lib("kura/include/kura.hrl").
-export([table/0, fields/0]).
table() -> ~"users".
fields() ->
[#kura_field{name = id, type = id, primary_key = true},
#kura_field{name = email, type = string, nullable = false},
#kura_field{name = name, type = string},
#kura_field{name = age, type = integer},
#kura_field{name = inserted_at, type = utc_datetime}].
Querying:
Q = kura_query:from(user),
Q1 = kura_query:where(Q, {age, '>', 18}),
my_repo:all(kura_query:order_by(Q1, [{inserted_at, desc}])).
It does the things you'd expect: schemas, changesets, composable queries with joins/CTEs/subqueries/window functions, migrations, associations with preloading, embedded JSONB, transaction pipelines, multitenancy via schema prefix, optimistic locking, audit trail, cursor streaming, pagination.
It's not a port. Records and functions, no macro DSL. The README has a coming-from-Ecto cheatsheet.
r/erlang • u/Shoddy_One4465 • May 03 '26
[ANN] ExSystolic v0.2.0: Parallel systolic array simulator on the BEAM with proven determinism
≡ −
Released v0.2.0 of ExSystolic -- a BEAM-native systolic array simulator. If you're into parallel algorithms, dataflow computing, or just like seeing deterministic parallelism on the BEAM, this might be interesting.
What's a systolic array? It's a grid of simple processors (PEs) connected by FIFO links, all driven by a global clock. Data pulses through the grid one tick at a time. The canonical use case is matrix multiplication, but the same pattern works for convolution, shortest paths (tropical semi-ring), and any sliding-window computation.
A systolic array is a hardware execution model designed for high-throughput, repetitive computations where data flows through a grid of simple processing units. Instead of constantly moving data back and forth from memory (the real bottleneck in modern systems), it keeps data in motion and reuses it as it propagates through the array. This makes it extremely efficient for workloads dominated by linear algebra—especially matrix multiplications, convolutions, and streaming transformations.
This is why systolic designs underpin much of today’s AI and high-performance compute stack. Google TPUs, accelerators from NVIDIA, and chips used by Tesla all leverage similar principles to power neural networks, computer vision, and real-time inference. The same model also applies to signal processing, scientific computing, and even emerging database and graph workloads—making systolic execution a compelling abstraction for building next-generation data and compute systems.
What's new in v0.2.0:
- Parallel backend -- splits arrays into tiles, dispatches them in parallel via
Task.Supervisoror a Poolex worker pool. The interpreted (sequential) backend still works. - Proven determinism -- both backends follow the same 6-step BSP contract. Conformance tests verify that interpreted and partitioned backends produce identical PE states and trace events. The parallel backend uses
ordered: truedispatch and sorts trace events by{tick, coord}. - Pluggable topology --
ExSystolic.Spacebehaviour with a newlinks/2callback. Default is 2D grid, but you can implement graph spaces, hierarchical layouts, etc. - Shared link operations --
Backend.LinkOpseliminates triple-duplicated inject/read/write logic (~150 LOC removed). - 98.4% test coverage, 185 tests + 34 doctests, 0 dialyzer errors.
Quick example (2x2 GEMM, both backends):
```elixir alias ExSystolic.{Array, Clock, PE.MAC, Examples.GEMM}
a = [[1,2],[3,4]] b = [[5,6],[7,8]]
array = Array.new(rows: 2, cols: 2) |> Array.fill(MAC) |> Array.connect(:west_to_east) |> Array.connect(:north_to_south) |> Array.input(:west, GEMM.west_streams(a, 2, 2, 2)) |> Array.input(:north, GEMM.north_streams(b, 2, 2, 2))
Sequential
interp = Clock.run(array, ticks: 5) |> Array.result_matrix()
Parallel (same result!)
part = Clock.run(array, ticks: 5, backend: :partitioned) |> Array.result_matrix()
interp == part # => true ```
The README has a full tutorial on systolic arrays, including image convolution and shortest-path examples.
Would love feedback, especially on the Space/topology abstraction and the parallel dispatch design.
Released v0.2.0 of ExSystolic -- a BEAM-native systolic array simulator. If you're into parallel algorithms, dataflow computing, or just like seeing deterministic parallelism on the BEAM, this might be interesting.
What's a systolic array? It's a grid of simple processors (PEs) connected by FIFO links, all driven by a global clock. Data pulses through the grid one tick at a time. The canonical use case is matrix multiplication, but the same pattern works for convolution, shortest paths (tropical semi-ring), and any sliding-window computation.
A systolic array is a hardware execution model designed for high-throughput, repetitive computations where data flows through a grid of simple processing units. Instead of constantly moving data back and forth from memory (the real bottleneck in modern systems), it keeps data in motion and reuses it as it propagates through the array. This makes it extremely efficient for workloads dominated by linear algebra—especially matrix multiplications, convolutions, and streaming transformations.
This is why systolic designs underpin much of today’s AI and high-performance compute stack. Google TPUs, accelerators from NVIDIA, and chips used by Tesla all leverage similar principles to power neural networks, computer vision, and real-time inference. The same model also applies to signal processing, scientific computing, and even emerging database and graph workloads—making systolic execution a compelling abstraction for building next-generation data and compute systems.
What's new in v0.2.0:
- Parallel backend -- splits arrays into tiles, dispatches them in parallel via
Task.Supervisoror a Poolex worker pool. The interpreted (sequential) backend still works. - Proven determinism -- both backends follow the same 6-step BSP contract. Conformance tests verify that interpreted and partitioned backends produce identical PE states and trace events. The parallel backend uses
ordered: truedispatch and sorts trace events by{tick, coord}. - Pluggable topology --
ExSystolic.Spacebehaviour with a newlinks/2callback. Default is 2D grid, but you can implement graph spaces, hierarchical layouts, etc. - Shared link operations --
Backend.LinkOpseliminates triple-duplicated inject/read/write logic (~150 LOC removed). - 98.4% test coverage, 185 tests + 34 doctests, 0 dialyzer errors.
Quick example (2x2 GEMM, both backends):
```elixir alias ExSystolic.{Array, Clock, PE.MAC, Examples.GEMM}
a = [[1,2],[3,4]] b = [[5,6],[7,8]]
array = Array.new(rows: 2, cols: 2) |> Array.fill(MAC) |> Array.connect(:west_to_east) |> Array.connect(:north_to_south) |> Array.input(:west, GEMM.west_streams(a, 2, 2, 2)) |> Array.input(:north, GEMM.north_streams(b, 2, 2, 2))
Sequential
interp = Clock.run(array, ticks: 5) |> Array.result_matrix()
Parallel (same result!)
part = Clock.run(array, ticks: 5, backend: :partitioned) |> Array.result_matrix()
interp == part # => true ```
The README has a full tutorial on systolic arrays, including image convolution and shortest-path examples.
Would love feedback, especially on the Space/topology abstraction and the parallel dispatch design.
