The software engineering methodology developed by TigerBeetle to produce safer, faster software in less time

Scroll to continue

Do the hard thing today to make tomorrow easy

Safety

Correctness is necessary but not sufficient for safety.

To be safe, a program must not only run correctly. It must apply defense-in-depth and verify itself while running, to run correctly or else shut down if it detects that it has violated expectations.

NASA's Power Of Ten Rules

TigerStyle follows the spirit of NASA's Power of Ten Rules for Safety-Critical Code by Gerard J. Holzmann. For example, static allocation, assertions and explicit limits. Read the Original Rules, which will change the way you code forever.

“The rules act like the seat-belt in your car: initially they are perhaps a little uncomfortable, but after a while their use becomes second-nature and not using them becomes unimaginable.”

— Gerard J. Holzmann

Explicit Limits

Put a limit on everything because everything has a limit. Bound all resources, all concurrency, and all execution.

Avoid recursion. Bound loops and queues to detect infinite loops and latency spikes.

Use fixed types like u32. Avoid architecture-specific types like usize.

Static Memory Allocation

Allocate all memory at startup. Don't allocate after initialization.

This centralizes and simplifies resource management, solves fragmentation, forces you to think through “the physics of the system”, and leads to an elegant design, with efficient, predictable performance.

Assertions

Where types check structure, assertions check all logic and state, to detect programmer error, multiply fuzzing, and downgrade catastrophe. Assert arguments, returns, and invariants: what you expect and don't expect, the positive and negative space, not only contract but breach.

Logical Interfaces

The safety (as well as performance and experience) of a system is dominated by the quality of its interfaces.

  • Minimize surface area.
  • Define fault models.
  • Abstract physical non-deterministic interfaces with logical deterministic interfaces.
  • Push control flow up and data flow down.
Dimensionality

Simplify function signatures to minimize branches at the call site, which are viral through the call graph.

As a return type, bool trumps u64 trumps !u64.

Minimize or define variables near to when/where they are used, to close semantic gaps in time/space.

Zero Dependencies

Dependencies risk safety and performance, invite supply chain attacks, and increase install times. For infrastructure in particular, these costs multiply up the stack.

Similarly, tools have costs. A small standard toolbox feels slow for you at first but accelerates the team long term.

Zero Technical Debt

Code, like steel, is easier to change while it's hot. Do it right the first time, the best you know how, because you may not get another chance, and because quality builds momentum. This is the only way to make steady progress, knowing that the foundations are solid.

Performance

The lack of back-of-the-envelope sketches is a root of all evil.

Think about performance from the outset. The time to solve performance, and get the 1000x wins, is in the design phase, when you can't profile. It's hard to fix a system after implementation, and the gains are less. Have mechanical sympathy. Like a carpenter, work with the grain.

Primary Colors

Like a painter, perform back-of-the-envelope performance sketches with respect to the four primary colors (network, storage, memory, compute) and their two textures (bandwidth, latency) to be “roughly right” and land within 90% of the global maxima.

Control Plane / Data Plane

Separate the control plane from the data plane by batching. Use bigger buffers to amortize network, storage, memory and compute costs, and to enable assertions in the control plane without trading performance in the data plane. Let the CPU sprint through large units of work.

Tough Environments

Place fewer demands on hardware for performance. Think of the future, where things are going. Make the roads bigger. Use bigger block sizes to amortize fixed costs, and to minimize control plane overhead. Embrace concurrency. Don’t react to stimuli.

Zero Copy / Deserialization

Per core memory bandwidth is a new bottleneck:

  • Do things in the most direct way possible.
  • Don't copy memory in the data plane.
  • Don't thrash the CPU cache.
  • Don't serialize or deserialize data.
  • Use fixed-size cache line aligned structs.
  • Align structs to their largest field.

Experience

Together, we serve the users.

A day of design is worth weeks or months in production. Therefore, go slow to go fast. Optimize the total cost of software ownership, not for those who write it once, but for those who read and run it many times. Trade linear deadlines for exponential quality.

Simplicity And Elegance

“...simple and elegant systems tend to be easier and faster to design and get right, more efficient in execution, and much more reliable, [but] require hard work and discipline to achieve…”

— Edsger Dijkstra

Nouns And Verbs

Great names are the essence of great code, capturing what a thing is or does, for a crisp mental model.

  • Append qualifiers to names.
  • Sort by most significant word (big endian naming).
  • Use the same number of characters for related names (e.g. source/target) so they line up in the source.
  • Use snake_case.
  • Don't abbreviate.
Biodigital Jazz

Software is engineering, and more, it is art. Information and inspiration. Reason and experience. Precision and poetry. Just like music. A tight beat. A rare groove. Words that rhyme and rhymes that break. If you believe in the songs, take them on tour. Making is showbiz.

u32 u32 u32 z_max x_max y_max
Assertion Failure
3x 2x 1x 0x Dependency A Dependency F Dependency E Dependency C Dependency D Dependency B Technical Debt Time Performance Storage Memory Compute Network
Network, Storage, Memory - Bandwidth 2020 2025 Block Size 512 KiB Memory Storage Network 64 KiB 4096 B Without cache line alignment With cache line alignment
TIME COST QUALITY Design Cost Production Cost
Little Endian Naming min_connection_delay max_connection_delay max_connections Big Endian Naming connection_delay_max_ms connection_delay_min_ms connection_count_max

If you want to be remembered, be remarkable.