Which makes the engine much smaller and less complex than a "normal" browser.
We’re doing pretty well as a business already, contrary to Rochus’ comment, which is not accurate.
Our team is 16, we have $30M in investment, and already some of the largest brokerages, exchanges, and wealth managements, in their respective jurisdictions are customers of TigerBeetle.
We have a saying:
“Good engineering is good business, and good business is good engineering.”
At least in TigerBeetle’s experience, the saying is proving true. We really appreciate your support and kind words!
May I ask what made you use Zig instead of e.g. Rust or C++ (or even Ada/SPARK)? I assume Go would be too undeterministic for real-time applications?
The claim is factually backwards. Go significantly outperforms Java, C#, and Python (~10x faster than Python, lower memory usage than C#), and runs successfully in countless 24/7 production systems including high-throughput APIs and distributed services.
The actual valid concern, which made me question its suitability, is that Go wouldn't be appropriate for TigerBeetle's specific real-time requirements. TigerBeetle is a financial transaction database requiring deterministic, predictable microsecond-level latencies with strict timestamp ordering across a distributed consensus protocol. Go's garbage collector introduces unpredictable pauses that would likely violate these hard real-time guarantees.
To answer your question is it too early. My expectation is that the core language, being quite small by design, will not change that much before 1.0. Some things will, especially async support.
What I think we will see is something like a comprehensive book on C++14 . The language is not much changed between now and then, but there will be new sections to add and some sections to rework with changes to the interface. The book would still be useful today.
Not a perfect analogy because C++ maintains backwards compatibility but I think it is close.
Outstanding issue on Zig side for 1.0 release: https://github.com/ziglang/zig/issues/16270
But I will also admit I don’t follow developments in zig as closely as Rust. I’ve never written any Zig. And in any case, past performance isn’t indicative of future performance.
I could be wrong about this prediction, but I don’t think I will be. From what I’ve seen Andy Kelley is a perfectionist who could work on point releases forever. But his biggest users (tigerbeetle and bun especially) will only be taken seriously once Zig is 1.0. They’ll nudge him towards 1.0. They can wait a few years, but not forever. That’s why I guessed 4 years.
TB is only 5 years old but already migrating some of the largest brokerages, exchanges and wealth managements in their respective jurisdictions.
Zig’s quality for us here holds up under some pretty extreme fuzzing (a fleet of 1000 dedicated CPU cores), Deterministic Simulation Testing and Jepsen auditing (TB did 4x the typical audit engagement duration), and is orthogonal to 1.0 backwards compatibility.
Zig version upgrades for our team are no big deal, compared to the difficulty of the consensus and local storage engine challenges we work on, and we vendor most of our std lib usage in stdx.
> They’ll nudge him towards 1.0.
On the contrary, we want Andrew to take his time and get it right on the big decisions, because the half life of these projects can be decades.
We’re in no rush. For example, TigerBeetle is designed to power the next 30 years of transaction processing and Zig’s trajectory here is what’s important.
That said, Zig and Zig’s toolchain today, is already better, at least for our purposes, than anything else we considered using.
If you don’t mind my asking, did TB add support for transaction metadata? I’ve seen this anti-pattern of map<string, string> associated with each transaction. Far from ideal, but useful. Last I checked TB didn’t support that because it would need dynamic memory allocation. Does it support it now or will it in future?
It’s not that it would need dynamic memory allocation (it could be done with static), but rather it’s not essential to performance—you could use any KV or OLGP for additional “user data”, it’s not the hard contended part.
To keep consistency, the principle is:
- write your data dependencies if any, then “write to TB last as your system of record”,
- “read from TB first”, and if it’s there your data dependencies will be too.
If what I’m saying is correct, we won’t actually see any performance benefits, only possible regressions. And if we’re already happy with Cassandra’s record keeping, what does TB add here?
Correct me if I’m missing something though! Like maybe we could rework how we write to Cassandra.
If you have any contention in your workload, which is typical for OLTP workloads [1], then, per Amdahl’s Law, that portion of the work will dominate, and TB will be orders faster.
For example, if your KV can do high throughput writes (and most can) at low latency then you should be looking at 20-50ms P100s all combined, per 8K transactions, when you’re running at 500K TPS, even with extreme contention up to 90%. Very hard if not impossible to do that if you don’t have TB as part of your stack. At least not with the durability and strict serializability guarantees that TB gives.
[1] Worth watching! https://youtu.be/yKgfk8lTQuE