Engineering teams still burn whole afternoons arguing whether REST is dead or if gRPC has made everything else obsolete. That debate misses the point. You are not choosing the best protocol. You are choosing the right boundary. A protocol that sings inside your Kubernetes cluster will suffocate when you hand it to a thousand external developers. One that saves your mobile app precious bandwidth will bankrupt your infrastructure if you open it to arbitrary public queries. Treat this decision like a technology popularity contest, and you cement architectural debt that outlasts every current member of your team.
The Boundary Principle
Architecture is about trade-offs, not champions. The correct question is never "Which is fastest?" or "Which is newest?" It is "Who sits on the other side of the wire, and what do they control?" Protocols are boundary objects. Picking the wrong one does not just slow you down. It bakes mistakes into your system for years.
Public APIs: REST Is Not Boring, It Is Responsible
When your consumer is an external developer you have never met, your API is a product, not merely an interface. That developer is debugging at two in the morning with nothing but curl and a Postman collection. If they must install a custom client library or learn a schema language before their first successful call, you have already lost them.
REST survives here because it is the web itself. HTTP methods, status codes, and JSON are the common tongue. Caching is not an afterthought; it is infrastructure that already exists. Browsers, CDNs, and edge caches understand Cache-Control headers and ETag validation natively. You can place a REST API behind a standard CDN and get immediate bandwidth savings without writing a single line of caching logic. That matters when public traffic is unpredictable and you are paying for every gigabyte that leaves your cloud.
GraphQL, by contrast, brings a heavy tax to a public boundary. Public GraphQL endpoints need query cost analysis, depth limiting, and complexity scoring to prevent a single careless or malicious query from crushing your database. You are not just shipping an API; you are building a query execution engine, a rate-limiting strategy, and a compute billing model. Unless you have the operational muscle of the largest platforms, that overhead is reckless for a public surface area. REST sets guardrails by default. Each endpoint does one thing. Consumers fetch exactly what you offer, not whatever they can dream up.
Internal Services: Own the Whole Pipe
Inside your organization, the conversation changes. You control both the client and the server. You can dictate the technology stack for every service in the call chain. This is where gRPC earns its keep.
First, stop treating JSON as sacred. Protocol Buffers serialize about three times faster than JSON. The payloads are smaller because the format is binary. On a busy internal network, those milliseconds and megabytes compound into real money and lower tail latency. More importantly, Protobuf gives you a strict contract. When you change a field type or rename a message, the break happens at compile time, not at three in the morning in production when a downstream service starts throwing parse exceptions.
gRPC runs over HTTP/2, so you get header compression, multiplexed streams, and real streaming semantics. If you are piping high-throughput events between services or pushing real-time updates, server-side and bidirectional streaming are native features, not long-polling workarounds duct-taped onto a request-response framework.
There is a hard catch: do not point gRPC directly at a browser. Browser networking models do not speak HTTP/2 the way gRPC expects. You will end up grafting grpc-web and a proxy like Envoy onto your stack just to get a browser to talk to a backend. That is not a bug; it is a boundary signal. Keep gRPC behind your firewall, between services that trust one another, and treat its debugging complexity as the price of speed. Binary payloads do not eyeball nicely in a log file the way JSON does.
Complex UIs and Mobile: GraphQL's Niche
Modern mobile screens are patchworks. One view might need a user profile,
