April in TigerLand

    Dear friends,

    Hope your April was awesome! We improved throughput by 10%, reduced binary size, and introduced multi-batching encoding. We also put the final polish on our Rust Client, had a memorable interview with Jerod on Changelog, and enjoyed tales of taming TigerBeetle’s tail together in leafy TU Darmstadt.

    Let’s go!

    “Juliet is the sun.” William Shakespeare

    “Juliet is like the sun in respect to radiance. [… to make it poetry] we delete all those logical but unnecessary steps.” Leonard Bernstein American conductor, composer, and pianist.

    • At TigerBeetle, we like to delete code because it means we’ve deepened our understanding of the system, yet with less code… poetry!

    • TigerBeetle’s OLTP throughput is directly a result of its batch-oriented interface. By batching many transactions into a single DBMS request, we amortize the overhead of consensus and I/O. The object_cache is an in-memory data structure that plays a key role in amortizing I/O.

    For example, in a create_transfers request, up to 8K transfers can be batched together. Before execution, we prefetch all the 16K debit and credit accounts into the object cache (hot accounts may already be present), and then each transfer is processed entirely in memory, in a tight hot loop without any I/O.

    We realized that some objects, such as historical balances , are never prefetched and do not need the machinery of an object cache associated with them. Making the object cache optional not only saved memory but also removed the unnecessary code responsible for cache consistency, improving throughput by 10%.

    • We reduced binary size by de-generifying our intrusive queue and stack data structures. When dealing with a generic type, for example, a Queue(T) — it reads as Queue over T — the compiler can efficiently generate static calls for a given T. However, this also creates a specialized copy of this data structure for every occurrence of T through a process called monomorphization, resulting in undesirable binary bloat.

    Instead of using generics, the Queue and Stack types now operate over a common link type that knows nothing about the actual element, requiring each caller to convert it to a meaningful value through simple pointer arithmetic. We achieved performance comparable to the generic version but without inflating the binary size. Yet, to get the best of both worlds, we kept the generic API for type safety—it is now just a thin wrapper with minimal extra size when monomorphized by the Zig compiler.

    • We also simplified the Darwin I/O implementation with fewer lines of code, without poking into the internal details of the Queue.

    • Still on the theme of amortizing costs through batching, while applications should pack as many transactions as possible into a request, there might not always be enough to fill 8K events at once.

    In the past, we dealt with small batches by automatically aggregating events from concurrent calls at the client side and submitting them as one larger batch. Although this worked, it required our client to be aware of the content being submitted and to do extra work to make it appear to the application as if it were from different requests. Worse, it didn’t apply to all TigerBeetle operations.

    We therefore took TigerBeetle’s automatic batching one step further and introduced the concept of multi-batching: an encoding on top of VSR messages that allows clients to submit arrays of batches, encoding the payloads of concurrent calls into a single physical VSR request. The most significant benefit is that this now works for any kind of operation, including queries and lookups, optimizing the TigerBeetle client for highly concurrent environments.

    • It is no secret that we have been pursuing a more efficient way to review pull requests, and this has already been a recurring theme in two episodes of IronBeetle. We want to avoid the slowness of web-based user interfaces and invite reviewers to pull the code locally, run tests, and interact with the PR author through code comments, directly from their primary tool: the code editor. A crucial benefit, in addition to speed, is that all code review comments can be preserved in the repo history.

    Now, we have landed the minimal viable implementation of this code review workflow, a simple wrapper around git commands with a parser for special comments marked with //?. Nothing ambitious, since we intend to develop a database, not a reviewing tool, but good enough to accelerate our team. We are excited to see how it will evolve with use!

    Last month in IronBeetle, we descended into VOPR and Tobias Ziegler joined episode 066 to teach matklad the tree of losers–a memorable episode starting at Knuth and ending in ᴩᴇʀꜰ.

    In Brian’s TigerBeetle Stream, final polish was added to the Rust client PR before prep for CI (including some debugging). The live coverage of coding our Rust client for TigerBeetle is headed towards its conclusion, the PR is prepared, but did it land? Go and see! :)

    Join us live every week on Twitch or catch up on the TigerTube!

    Changelog Interviews Ep. #635 The 1000x Faster Financial Transactions Database, April 2 Joran chatted to Jerod Santo about how TigerBeetle got fast, resilient and durable, and shared our philosophy on open source and the difference between interfaces (competition) and implementation (collaboration)… plus, how not to build sand castles but rather jump in and surf the wave of innovation instead!

    Elixir Meetup in Milan, April 9 We wish we could have joined the Elixir meetup last month in Milan, where Riccardo Binetti spoke about building an Elixir client for TigerBeetle. Kudos to the organisers. Local meetups rock. If you host one, we sponsor pizza! Ping marina@tigerbeetle.com.

    The Tale of Taming TigerBeetle’s Tail, April 9 Some of the TigerBeetle team met in Darmstadt last month, and enjoyed The Tale of Taming TigerBeetle’s Tail, on how to reduce TB’s P100 latencies from 125ms to 25ms, as told by Tobias Ziegler of TU Munich/Darmstadt.

    Mojaloop Foundation Conference, April 14 We were delighted to join a few central bankers, to listen, learn, and share at the 27th Mojaloop convening in Accra, Ghana. A real ‘homecoming moment’ for TigerBeetle. Thanks for having us, Mojaloop! Catch Lewis Daly of TigerBeetle interviewed by Julie Guetta here (1”56 minutes remaining mark).

    Staff Podcast Two-Part Interview, March 26 and April 23 Triple jump with matklad (in Russian) into the depth of TigerBeetle! A two-part live streamed interview series on StaffPodcast with matklad, the first of which was 3 hours long, only ending after 3 hours because Discord broke. Part two was equally lively and lengthy. Thanks for having us, Aleksandr!

    New blog post: Swarm Testing Data Structures, April 30 We discovered a cute little pattern the other day when refactoring TigerBeetle’s intrusive queue—using Zig’s comptime reflection for exhaustively testing a data structure’s public API. Isn’t it cool when your property test fails when you add a new API, because “public API is tested” is one of the properties you test?! Read the post by matklad.

    J on the beach (May 14-16) Coming soon, Federico Massimiliano Lorenzi’s talk on TigerBeetle’s Multiversion Binaries for J on The Beach! Don’t be papafrita, but join us in Malaga.

    Systems Distributed (June 19-20) The agenda for SD’25 is now up! Join us in Amsterdam for two days of talks, film references, and systems… distributed! Premium tickets enable us to maximize our donation to the Zig Software Foundation. Just 45 days to go!

    Tweet Tweet Tweet Tweet Tweet Tweet Tweet Tweet

    ‘Till next time… stop some traffic!

    The TigerBeetle Team

    P.S. If you’re on Bluesky,we are, too.

    RSS iconRSS
    An idling tiger beetle Speech bubble says hi