The Problem with REST/JSON for Internal Services
HTTP/2 and HTTP/3 are optimized for browser-to-server communication. But in a microservices architecture, you have dozens or hundreds of services talking to each other — an order service calling an inventory service, a payment service calling a fraud detection service, an API gateway routing to ten backend services. This service-to-service traffic can dwarf browser traffic in volume.
For this use case, REST with JSON has real costs:
Verbosity: JSON is a text format. The number 22.5 is stored as the characters 2, 2, ., 5 — 4 bytes. In binary, a 32-bit float is always 4 bytes, but a 64-bit double is 8 bytes and carries far more precision. More importantly, JSON repeats field names in every message: {"temperature": 22.5, "sensor_id": 99485, "timestamp": 1704067200} — the keys temperature, sensor_id, and timestamp are retransmitted with every reading, even though both sides already know the schema.
Parsing cost: Converting a JSON string into in-memory objects (deserialization) requires scanning the text character by character, allocating strings for keys, and type-coercing values. At millions of requests per second, this CPU cost is significant.
No formal contract: REST APIs are typically documented in OpenAPI/Swagger specs, but these are separate from the code. Nothing enforces that the client and server agree on the schema at compile time. A field rename in the server causes a runtime error in the client.
gRPC (gRPC Remote Procedure Calls), open-sourced by Google in 2016, addresses all three problems. It is built on HTTP/2, uses Protocol Buffers for serialization, and generates strongly-typed client and server code from a shared schema definition.