ZAP Protocol

Why ZAP?

What ZAP replaces, what it buys you, and the production stack that runs it with zero gRPC and zero protobuf.

Why ZAP?

ZAP replaces both halves of the conventional RPC stack — protobuf (serialization) and gRPC (transport + RPC) — with one layer. This page explains the mechanism, compares the alternatives honestly, and shows what a stack looks like when the replacement is complete: a real production deployment with zero gRPC and protobuf confined to one four-function file.

The problem

Modern distributed systems inherit four costs from their RPC framework:

  1. Serialization overhead — JSON and protobuf require an encode/decode step on every hop
  2. Transport lock-in — most frameworks are welded to a single transport (gRPC to HTTP/2)
  3. Bolted-on trust — auth is per-layer (TLS and tokens and API keys), consensus is a separate integration
  4. Two artifacts per contract — a schema and a framework config, each drifting independently

How ZAP solves these

Zero-copy serialization

ZAP's wire format is directly usable in memory. There is no parsing step — data is accessed in place from the buffer.

Traditional RPC:
  Wire -> Parse -> Memory Object -> Use

ZAP:
  Wire -> Use (directly)

Measured numbers live on the benchmarks page — every table there is reproducible from zap-proto/bench, and claims that can't be traced to a checked-in harness don't get published. The mechanism argument stands on its own: object-mode access has no decode step to pay for, which is why it leads every mode in the harness.

Transport flexibility

ZAP abstracts the transport layer:

TransportLatencyReliabilityUse Case
TCPLowGuaranteedDefault choice
UDPLowestBest-effortReal-time telemetry
Unix SocketLowestGuaranteedSame-host IPC
WebSocketMediumGuaranteedBrowser 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")

On the server side, zip takes the same idea further: one Listen verb, address scheme selects the transport, ZAP primary and HTTP secondary over the same routes.

One trust model

Authentication is bound to the transport — mutual post-quantum KEM identity, not TLS-plus-tokens — and authority is expressed as capabilities: references the holder can call but cannot forge, transferable to a third peer, revocable without rotating keys. The capability mailbox example shows what this makes possible that bearer tokens structurally cannot express. Optional BFT consensus rides the same wire.

First-class code generation

One .zap schema is the entire contract — structs, RPC surface, stable opcodes:

zap generate calculator.zap --lang=go --out=./gen

Generation emits a zero-copy View/Builder per struct plus a typed client and server per interface — the Schema Language and Code Generation pages are the references. The tools section covers the migration path off protobuf.

ZAP instead of gRPC + protobuf

gRPC and protobuf are two products you adopt together and pay for separately. ZAP is one layer:

ConcerngRPC + protobufZAP
Serializationprotobuf — encode/decode every hopzero-copy — the in-memory layout is the wire layout
TransportHTTP/2 onlyTCP, UDP, Unix, WebSocket; pluggable
Schema.proto + ordinals + separate service configone .zap file — structs + interface + opcodes
AuthTLS at the edge, tokens in-bandidentity-bound transport, PQ KEM, capabilities
Browserrequires grpc-web proxynative WebSocket
Streamingbidirectionalbidirectional + promise pipelining
Consensusseparate integrationbuilt-in, optional

Choose gRPC when: you need its ecosystem — existing proto contracts with external partners, off-the-shelf interceptor middleware, teams fluent in it.

Choose ZAP when: you control both ends of the wire and want one wire format, one trust model, and no serializer between layers.

ZAP-only in production

This is not a roadmap claim. The Hanzo AI + Lux Network stack runs ZAP-native today, with zero gRPC and zero protobuf in application code:

  • One binary. hanzoai/cloud composes IAM, KMS, gateway, commerce, AI, and a dozen more subsystems into a single Go binary. The compose root is under 1,000 lines of zip hosting ~75,000 lines of subsystem code — a 76:1 ratio of product over framework shim.
  • One wire contract per service. Every RPC surface is a .zap schema — structs plus stable opcodes. hanzoai/tasks (schema/tasks.zap) states it the way every service does: "This is the one and only wire contract. Nothing on this wire speaks protobuf, gRPC, or any temporal.io-branded framing."
  • One protobuf touchpoint. Observability is the industry edge that still speaks protobuf (OTLP/OpAMP). The stack's entire protobuf surface is zap2pb — one file, four functions. Spans are OTLP-protobuf payloads shipped over ZAP frames to the collector's ZAP receiver; no OTLP-over-gRPC, no second protobuf import anywhere.
  • Mechanical migration. pb2zap rewrote the unambiguous protobuf construction sites; humans restructured the read paths it reported.

The same dispatch generalizes upward: Hanzo and Lux run services as ZAP-native plugin VMs — ZAP is the dispatch surface, Lux consensus orders it, zapdb persists it. Deployments and their numbers are tracked on the ecosystem page.

When to use ZAP

  • 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
  • Agent infrastructure: MCP and A2A ride the ZAP wire natively

When not to use ZAP

  • Simple public REST APIs: standard HTTP may be all you need
  • Contracts you don't own: if external partners mandate proto/gRPC contracts, you keep them — though zap2pb shows how narrow that edge can be
  • Browser-only products: if browsers are your only client, GraphQL or plain HTTP may fit better

Performance

Every published number is on the benchmarks page, reproducible from the harness in zap-proto/bench. The honest summary: ZAP wins modestly at small payloads, ties in the middle, and the strongest arguments today are mechanism, not microseconds — one wire format under every protocol, PQ at the transport, capabilities instead of tokens.

Summary

  1. One layer replaces protobuf + gRPC — zero-copy wire, typed RPC, transport choice
  2. One trust model — identity-bound transport, capabilities, optional BFT
  3. One schema per service — .zap, with a complete toolchain on and off it
  4. Proven in production — a real stack runs ZAP-only, with protobuf confined to four functions

If you control both ends of your wire, ZAP removes an entire layer of your stack. The quick start takes five minutes.

On this page