rbino

rbino

Ash Core Team

TigerBeetlex - an Elixir client for TigerBeetle

Hey folks!

I’m happy to introduce TigerBeetlex, an Elixir client for TigerBeetle, the financial transactions database. I’ve been working on this for some time and I finally feel it’s ready for general usage.

The goal of TigerBeetle is making financial transactions safe and fast, and TigerBeetlex allows you to interact with it from the Elixir world. If you’re building applications requiring high-throughput, fault-tolerant double-entry accounting, TigerBeetle, and now TigerBeetlex, could be a great fit.

It exposes all the available operations with two different flavored APIs: a message-based one, useful to plug into and existing process architecture, and a blocking API, providing a more familiar RPC-like interface. Moreover, it translates TigerBeetle binary data back and forth to Elixir structs.

The client is built upon the official TigerBeetle Zig client as a NIF, which is the approach used by all other TigerBeetle high-level clients. The NIF is built using build_dot_zig, so it automatically downloads the Zig toolchain for you and doesn’t require any system dependency to be built.

The docs contain a walkthrough that can be executed in LiveBook and should cover all the main features, but I suggest checking out the official TigerBeetle docs, especially the recipes section, which show some really cool accounting-foo to implement concrete use cases.

I’ve also done an introductory talk to TigerBeetlex at ElixirConf EU 2025, I’ll post the recording of the talk here when it’s released.

Let me know if you have any questions or suggestions, someone on the forum was already asking for integration with Ash which was something I already had on my mind.

https://github.com/rbino/tigerbeetlex

Most Liked

rbino

rbino

Ash Core Team

Hey everyone!

I’ve released version 0.16.47 today (like I do almost every Tuesday, following TigerBeetle release schedule). This time though the version doesn’t just bump the TigerBeetle client version, but also adds support for TigerBeetle Change Data Capture functionality.

To provide a little more context, since version 0.16.43 TigerBeetle has the ability to stream its transactions to RabbitMQ, so in this version of TigerBeetlex I’ve added structs to decode the JSON payload of the events and a guide showing how to use Broadway to build a pipeline processing TigerBeetle CDC data.

matt-savvy

matt-savvy

How’s your experience with TigerBeetle been so far? I’m evaluating it for an upcoming project, and I still have a bunch of questions.

I’m curious what’s the best approach for something that you expect to be atomic across your general purpose DB (Postgres) and your TigerBeetle DB.

For example, let’s say you have an Invoice in your general purpose DB and you’re using its id as user_data_128 on the TB Transfer. So when you bill an account, you would create a transfer that debits this amount, crediting the account doing the invoicing. And then the opposite when the billed account pays up, crediting them and debiting the account doing the invoicing. At that point, I would probably want to mark the Invoice as paid in some way. But then you run into the questions like, what happens if the server goes down when the transfer has been written in TB but not in the general purpose DB? Or if you go to update the invoice and this write fails because the invoice didn’t ever exist, etc?

I’m wondering if it even makes sense to have an explicit enum like that on the Invoice in the first place or if TigerBeetle should just be the only source of truth, and when you need to look that up, you just hit TB to see if there is a transfer with that Invoices id as user_data_128 and a code that represents an invoice being paid. E.g. code=10 is an invoice billed, code=20 is an invoice being paid, code=30 is an invoice being cancelled or otherwise comped.

rbino

rbino

Ash Core Team

To be transparent, I didn’t actually get to use the library in a project yet :smile: I’m mainly developing it as an interesting project where I can work with both Elixir and Zig. You can have a look at TigerFans for an example of a project built with TigerBeetle (not in Elixir, but data modeling is language agnostic anyways).

Regarding transactions across TigerBeetle and Postgres, there’s a recent blogpost on the TigerBeetle blog detailing why you would want to use a specific order for write and reads (i.e. write to TigerBeetle last, read from TigerBeetle first). For temporary failures, TigerBeetle pushes towards end-to-end idempotency to be able to safely retry operations, more details here.

Where Next?

Popular in Announcing Top

wmnnd
Hi there, for my project DBLSQD, I needed a file storage solution that is a bit more flexible than Arc. Because I thought others might f...
New
OvermindDL1
I created a new library (rather I pulled out a couple files from my big project), it manages an operating system PID file for the BEAM. ...
New
tmbb
PhoenixWS - Websockets over Phoenix Channels Source code on Github here: GitHub - tmbb/phoenix_ws: Websockets implemented over Phoenix Ch...
New
seancribbs
Today I released a new dialyzer Mix task as the dialyzex package! At the time we started writing this task, the existing dialyzer integra...
New
Crowdhailer
I have been updating a library that allows you to pipe between functions that use the erlang result tuple convention. Assuming you have ...
New
kip
ex_cldr provides localisation and internationalisation support based upon the data from the Unicode CLDR project. Unicode released CLDR ...
407 12840 120
New
zachdaniel
Ash Framework What is Ash? Ash Framework is a declarative, resource-oriented application development framework for Elixir. A resource can...
New
markmark206
simple_feature_flags is a tiny package that lets you turn features on or off based on which environment (e.g. localhost, staging, product...
New
OvermindDL1
Been making an MLElixir thing (not released yet…) for fun in spare time in the past day. I’m just trying to see how much I can get an ML...
132 13966 106
New
marcuslankenau
I feel kind of stuck with the absence of a proper xml library for Elixir. Currently I use SweetXML which was ok for me more or less to pa...
New

Other popular topics Top

sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 53690 245
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 39297 209
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New

We're in Beta

About us Mission Statement