Case TigerBeetle — Banco de Dados Financeiro de Missão Crítica em Zig
O TigerBeetle representa um dos usos mais ambiciosos e críticos do Zig em produção. Trata-se de um banco de dados distribuído projetado especificamente para contabilidade financeira, onde um único bug pode significar perda de dinheiro real. O fato de que uma equipe escolheu Zig para esse nível de criticidade é uma validação extraordinária da linguagem.
O Problema que o TigerBeetle Resolve
Sistemas financeiros modernos enfrentam um paradoxo: precisam de throughput massivo (milhões de transações por segundo) com correção absoluta (nunca perder centavos). Bancos de dados genéricos como PostgreSQL não foram otimizados para esse caso de uso específico:
- Double-entry bookkeeping: Cada transação deve debitar uma conta e creditar outra atomicamente
- Saldo nunca negativo: A menos que explicitamente permitido
- Auditabilidade total: Cada transação deve ser rastreável
- Alta disponibilidade: Downtime em sistemas financeiros custa milhões por minuto
- Throughput extremo: Fintechs e marketplaces processam milhões de eventos por dia
Por Que Zig
Joren Spit, CEO do TigerBeetle, documentou extensivamente a decisão de usar Zig:
Correção de Código
Em um banco de dados financeiro, bugs custam dinheiro literal. O Zig oferece:
- Detecção de integer overflow: Operações aritméticas em valores monetários nunca silenciosamente overflow
- Segurança de ponteiros: Eliminação de classes inteiras de vulnerabilidades
- Controle explícito de erros: Todo caminho de erro é tratado ou explicitamente propagado
- Safety checks em produção: O modo ReleaseSafe mantém verificações com otimização
Performance Determinística
- Sem GC: Latência previsível para cada transação
- Alocação explícita: Uso de memória é modelável e testável
- io_uring: I/O assíncrono de alta performance no Linux
- Direct I/O: Bypass do cache do OS para controle total de durabilidade
Compilação Cruzada
O TigerBeetle precisa rodar em Linux x86_64, ARM64, macOS e Windows. O Zig compila para todos esses targets de qualquer máquina de desenvolvimento.
Arquitetura Detalhada
Motor de Armazenamento: LSM-Forest
O TigerBeetle implementa uma variação customizada do LSM-Tree chamada LSM-Forest:
Nível 0: Memtable (RAM) — Escritas recentes
↓ Flush quando cheio
Nível 1: SSTable (Disco) — Dados semi-recentes
↓ Compactação periódica
Nível N: SSTable (Disco) — Dados antigos
Cada nível é otimizado para o padrão de acesso:
- Memtable: HashMap em memória para escritas O(1)
- SSTables: Blocos ordenados e indexados no disco
- Bloom filters: Eliminação rápida de lookups desnecessários
- Block cache: Cache LRU de blocos de disco em memória
Protocolo de Consenso: Viewstamped Replication
O TigerBeetle implementa VSR (Viewstamped Replication) para tolerância a falhas:
Operação normal:
1. Cliente envia batch de transferências ao líder
2. Líder replica para backups
3. Maioria (quorum) confirma
4. Líder aplica e responde ao cliente
Failover:
1. Backup detecta que líder está offline
2. Protocolo de eleição de novo líder
3. Novo líder sincroniza estado com quorum
4. Operação normal retomada
Batching Inteligente
O TigerBeetle acumula operações em batches para maximizar throughput:
// Conceitual: como batching funciona
const Batch = struct {
transferencias: [8192]Transfer,
count: usize = 0,
pub fn adicionar(self: *Batch, t: Transfer) !void {
if (self.count >= self.transferencias.len) {
try self.flush();
}
self.transferencias[self.count] = t;
self.count += 1;
}
pub fn flush(self: *Batch) !void {
// Escrever batch inteiro no WAL com um único fsync
try self.wal.writeAll(std.mem.sliceAsBytes(
self.transferencias[0..self.count]
));
try self.wal.sync();
// Aplicar no memtable
for (self.transferencias[0..self.count]) |t| {
try self.memtable.apply(t);
}
self.count = 0;
}
};
Resultados de Performance
Benchmarks Oficiais
| Operação | Throughput | Latência p99 |
|---|---|---|
| Transfers (batch) | ~3.4M/s | <1ms |
| Account lookup | ~5M/s | <0.5ms |
| Transfers (single) | ~200K/s | <2ms |
| Recovery (1GB) | ~30s | N/A |
Comparação com Alternativas
| Sistema | Transações/s | Garantias |
|---|---|---|
| TigerBeetle | 3.400.000 | ACID, Distributed |
| PostgreSQL | 50.000 | ACID |
| MySQL | 40.000 | ACID |
| Redis | 100.000 | Eventual |
| CockroachDB | 20.000 | ACID, Distributed |
Clientes e Adoção
O TigerBeetle é usado por empresas em produção para:
Fintechs
- Processamento de pagamentos PIX em tempo real
- Controle de saldo de carteiras digitais
- Split de pagamentos em marketplaces
Exchanges
- Registro de ordens de compra/venda
- Controle de saldo de ativos digitais
- Liquidação de operações
Sistemas de Fidelidade
- Gestão de pontos e recompensas
- Transferência de pontos entre programas
- Expiração automática de saldo
Investimento e Sustentabilidade
O TigerBeetle recebeu investimento significativo de VCs de Silicon Valley, validando tanto o produto quanto a escolha tecnológica do Zig:
- Time de engenharia em tempo integral
- Contribuições ativas para o compilador Zig
- Documentação extensiva e open source
- Programa de suporte empresarial
Técnicas de Zig Utilizadas
Comptime para Verificação
// Verificar invariantes em tempo de compilação
comptime {
// Transfer deve ter exatamente 128 bytes
if (@sizeOf(Transfer) != 128) {
@compileError("Transfer struct tem tamanho incorreto");
}
// Alinhamento para Direct I/O
if (@alignOf(Transfer) % 512 != 0) {
@compileError("Transfer deve ser alinhada a 512 bytes");
}
}
Testes Determinísticos
O TigerBeetle usa o sistema de testes do Zig para simulação determinística:
test "transferência atômica entre duas contas" {
var cluster = try TestCluster.init(testing.allocator, .{
.replicas = 3,
});
defer cluster.deinit();
// Criar contas
try cluster.createAccount(.{ .id = 1, .ledger = 1 });
try cluster.createAccount(.{ .id = 2, .ledger = 1 });
// Transferir
try cluster.createTransfer(.{
.id = 1,
.debit_account_id = 1,
.credit_account_id = 2,
.amount = 1000,
.ledger = 1,
});
// Verificar saldos
const conta1 = try cluster.lookupAccount(1);
const conta2 = try cluster.lookupAccount(2);
try testing.expectEqual(@as(u128, 1000), conta1.debits_posted);
try testing.expectEqual(@as(u128, 1000), conta2.credits_posted);
}
Lições para o Ecossistema
- Zig serve para missão crítica: Se pode gerenciar dinheiro real, pode fazer qualquer coisa
- Comptime é game-changer: Verificações em compilação eliminam bugs antes da produção
- Performance e segurança não são excludentes: ReleaseSafe prova isso
- O modelo de alocador é perfeito para databases: Controle fino de memória é essencial
- Comunidade de qualidade: Contribuições do TigerBeetle melhoraram o compilador
Próximos Passos
Explore os detalhes técnicos do TigerBeetle no ecossistema, conheça outros cases como Bun e Ghostty, e veja como fintechs usam Zig em outros contextos. Para oportunidades de carreira, visite nossa seção de carreira.