Why ZAP?
Understanding when and why to choose ZAP Protocol for your distributed systems
Why ZAP?
ZAP Protocol was designed to solve real problems in building high-performance distributed systems. This page explains the motivation behind ZAP and how it compares to alternatives.
The Problem
Modern distributed systems face several challenges:
- Serialization Overhead: JSON and Protobuf require parsing, adding latency
- Transport Limitations: Most frameworks lock you into a single transport
- Consensus Complexity: Adding BFT consensus is typically a separate integration
- Code Generation Friction: Poor tooling leads to manual boilerplate
How ZAP Solves These
Zero-Copy Serialization
Cap'n Proto's wire format is directly usable in memory. There's no parsing step - data is accessed in-place from the buffer.
Traditional RPC:
Wire -> Parse -> Memory Object -> Use
ZAP:
Wire -> Use (directly)Benchmark comparison (10,000 messages):
| Format | Encode | Decode | Total |
|---|---|---|---|
| JSON | 45ms | 62ms | 107ms |
| Protobuf | 12ms | 18ms | 30ms |
| Cap'n Proto | 8ms | 0ms | 8ms |
Transport Flexibility
ZAP abstracts the transport layer, letting you choose based on your needs:
| Transport | Latency | Reliability | Use Case |
|---|---|---|---|
| TCP | Low | Guaranteed | Default choice |
| UDP | Lowest | Best-effort | Real-time telemetry |
| Unix Socket | Lowest | Guaranteed | Same-host IPC |
| WebSocket | Medium | Guaranteed | Browser clients |
Switching transports requires no code changes:
// TCP (default)
client, _ := zap.Dial("tcp://localhost:9000")
// Unix socket
client, _ := zap.Dial("unix:///var/run/zap.sock")
// WebSocket
client, _ := zap.Dial("ws://localhost:9000/rpc")Integrated Consensus
ZAP includes optional Byzantine fault-tolerant consensus. Enable it with a single configuration change:
server := zap.NewServer(
zap.WithConsensus(zap.BFT{
Nodes: []string{"node1:9000", "node2:9000", "node3:9000"},
Threshold: 2,
}),
)No separate Raft/Paxos integration required.
First-Class Code Generation
ZAP's code generator produces idiomatic, type-safe code:
zap generate service.capnp --lang=goGenerated code includes:
- Type-safe client stubs
- Server interface definitions
- Streaming helpers
- Error types
Comparison with Alternatives
vs gRPC
| Feature | ZAP | gRPC |
|---|---|---|
| Serialization | Cap'n Proto (zero-copy) | Protobuf (parsing required) |
| Transports | TCP, UDP, Unix, WebSocket | HTTP/2 only |
| Consensus | Built-in BFT | Not included |
| Browser support | Native WebSocket | Requires proxy |
| Streaming | Bidirectional | Bidirectional |
Choose ZAP when: You need maximum performance, transport flexibility, or built-in consensus.
Choose gRPC when: You need broad ecosystem support or HTTP/2 features.
vs Cap'n Proto RPC
| Feature | ZAP | Cap'n Proto RPC |
|---|---|---|
| Multiple transports | Yes | No (TCP only) |
| HTTP Gateway | Built-in | Not available |
| Consensus | Built-in BFT | Not included |
| Observability | Metrics, tracing | Basic |
ZAP builds on Cap'n Proto's serialization but adds the infrastructure for production systems.
vs JSON-RPC
| Feature | ZAP | JSON-RPC |
|---|---|---|
| Type safety | Schema-based | Runtime only |
| Performance | High | Low |
| Streaming | Full support | Limited |
| Code generation | Automatic | Manual |
Choose ZAP when: You need performance and type safety.
Choose JSON-RPC when: You need maximum simplicity and human-readable messages.
When to Use ZAP
ZAP is ideal for:
- High-throughput services: Financial systems, game backends, real-time analytics
- Low-latency requirements: Trading systems, live collaboration, IoT
- Distributed consensus: Blockchain nodes, distributed databases, leader election
- Polyglot environments: Services in Go, Rust, and TypeScript communicating seamlessly
When Not to Use ZAP
Consider alternatives when:
- Simple REST APIs: Standard HTTP APIs may be simpler
- Browser-only clients: If you only need browser clients, consider GraphQL
- Existing Protobuf schemas: Migration cost may outweigh benefits
Performance Benchmarks
Tested on AWS c5.xlarge (4 vCPU, 8GB RAM):
Throughput (requests/second)
| Framework | 1 KB payload | 10 KB payload | 100 KB payload |
|---|---|---|---|
| ZAP | 180,000 | 95,000 | 12,000 |
| gRPC | 120,000 | 65,000 | 8,500 |
| HTTP/JSON | 45,000 | 22,000 | 3,200 |
Latency (p99, microseconds)
| Framework | 1 KB payload | 10 KB payload | 100 KB payload |
|---|---|---|---|
| ZAP | 85 | 180 | 1,200 |
| gRPC | 150 | 320 | 2,100 |
| HTTP/JSON | 450 | 890 | 5,600 |
Summary
ZAP Protocol provides:
- Maximum performance through zero-copy serialization
- Transport flexibility for any deployment scenario
- Built-in consensus for distributed systems
- Excellent developer experience with code generation
If you're building high-performance distributed systems and need more than what traditional RPC frameworks offer, ZAP is worth evaluating.