
Essay REST API
gRPC vs REST for Public-Facing API Design
Protocol choice depends on whether callers are internal partners or unknown external developers.
I've been arguing about REST versus gRPC for the better part of a decade, and the short version is this: the fight is really about who's calling your API and what tools are already sitting on their machine. REST was designed for an open, heterogeneous web where you have no control over the caller, their language, or their tooling. gRPC was designed for controlled environments where every participant agrees on schemas and build pipelines before writing a single line of code. Figure out which world your API lives in, and the protocol choice becomes straightforward rather than ideological. What follows is a breakdown of the technical constraints, performance tradeoffs, ecosystem realities, and architectural patterns that should govern that decision.
What REST and gRPC were each built for
REST runs on plain HTTP, usually 1.1, though nothing stops it from riding HTTP/2. It uses verbs you already know (GET, POST, PUT, PATCH, DELETE), ships JSON most of the time, and doesn't enforce a schema on anyone. It was built for the open web, back when you genuinely had no idea who'd be calling your endpoint or what language they'd write it in.
gRPC comes from a different world entirely. It runs over HTTP/2, leans on Protocol Buffers (a compact binary serialization format) for strict typed contracts, and supports four communication modes: unary (a plain request and response), server streaming (live prices, log tailing), client streaming (uploading a file or a stream of sensor readings), and bidirectional streaming (chat, live location, the kind of functionality that used to require WebSockets bolted on as a separate concern).
REST assumes you don't control the caller. gRPC assumes you do, or that everyone agreed on tooling before anyone wrote a line of code. Neither assumption is wrong. They're signals about what each protocol was optimized for, and ignoring those signals is how a team ends up building something technically impressive that nobody outside the organization can actually use.
What benchmarks show and what they miss
The performance numbers are real. A microservice benchmark from Markaicode in March 2025 put gRPC at 25,800 requests per second with 12.8 millisecond latency, against REST's 12,450 RPS and 24.5 ms on the same hardware. Roughly double the throughput, half the latency. Protobuf earns that honestly: field names get replaced with short numeric tags, so a payload that would otherwise spell out "customer_id" a thousand times sends a number instead. HTTP/2's multiplexing and header compression add further gains on top, as long as everything is on the same network.
Those benchmarks measure protocol overhead in a lab environment where network latency is essentially zero. On the public internet, round-trip time dominates everything else. If your request takes 80 milliseconds to cross the country and back, shaving a few milliseconds off serialization has negligible practical impact. The performance case for gRPC is strongest exactly where public APIs don't operate: inside a datacenter, between services that already trust each other.
These benchmarks are useful for internal architecture decisions. They are much weaker guidance when you are designing an API for unknown external developers.
The browser wall that kills most gRPC proposals
Browsers can't speak native gRPC. Full gRPC needs HTTP/2 trailer frames, and the browser's fetch API doesn't expose them. That's a structural constraint of how browsers work, not a configuration option someone forgot to enable.
gRPC-Web exists as a workaround. It's JavaScript-friendly, runs over HTTP/1.1 or HTTP/2, and requires a proxy (usually Envoy, an open-source edge and service proxy) to translate between gRPC-Web on the front end and native gRPC behind it. Even then, full bidirectional streaming isn't reliably available in stable browsers as of early 2026. Some experimental Chromium builds support it, but Safari and Firefox don't, which means any claim that a gRPC-Web implementation "works in browsers" requires a lot of qualifying footnotes.
Connect-RPC, from Buf, deserves mention here. It's designed as idiomatic HTTP from the ground up, runs in browsers without a proxy, and a single Connect-RPC server can speak Connect, native gRPC, and gRPC-Web simultaneously. It's genuinely well-engineered. That said, it's not what a third-party developer expects to find when they land on your documentation, and that expectation mismatch has real costs in adoption and support overhead.
Any architecture where browsers appear on the list of callers means gRPC introduces infrastructure complexity that REST never requires.
The developer experience gap compounds the browser problem
REST's tooling advantage comes from being old and widely used. Every language has a mature HTTP client. curl works. Postman works. Browser devtools show you the response in plain text immediately. Nobody installs anything to evaluate your API for the first time.
If you expose a gRPC API, you are asking the person on the other end for more before they make a single call: they need the protobuf compiler, the correct language plugin, and build system integration. Sharing .proto files across an organizational boundary usually means asking an outside developer to adopt tooling (Buf's Schema Registry, Bazel) that they have no interest in learning just to evaluate whether your API does what they need. When a call fails, REST surfaces a readable error in devtools immediately, while gRPC returns a binary blob that requires the exact .proto file and a deserializer to interpret.
Error handling adds another layer of friction. gRPC uses its own status vocabulary (UNAVAILABLE, DEADLINE_EXCEEDED, NOT_FOUND, INTERNAL) that is entirely separate from HTTP status codes. A developer who has spent years debugging 404s and 500s has to learn a different model, and the two systems don't map onto each other cleanly.
That friction doesn't land on your team. It lands on a developer who hasn't committed to your API yet and is deciding right now whether integrating with it is worth their time. Teams that ship explicit API contracts (OpenAPI, SDL, .proto) get new integrations built 23% faster, per the 2025 State of API report. Schema-first design pays off regardless of protocol, but OpenAPI is what third-party developers already expect, so REST begins with a substantial head start in that regard.
REST assumes you don't control the caller. gRPC assumes you do, or that everyone agreed on tooling before anyone wrote a line of code.
REST's structural advantages for public APIs
Caching is REST's most underappreciated advantage for public APIs. A GET request caches natively at CDN edges, in browsers, and inside API gateways, which means a public API can absorb significant read traffic without changes to application code. gRPC has no equivalent: no native GET semantics, and caching binary protobuf at the edge requires custom gateway configuration that most teams never implement.
Versioning follows a similar pattern. REST's versioning strategies (URL versioning, date-based versioning) are well-established. Stripe's REST API has maintained backward compatibility for over a decade, meaning code written years ago against it still runs today without modification. That durability reflects the ecosystem of tooling and discipline that has grown up around REST because it has been the default for public interfaces long enough for those practices to mature.
Observability tooling and API gateways are built primarily around REST. 89% of organizations use REST as their primary API format, which means tooling vendors have invested a decade of work in deep REST support. gRPC support in the same tools continues to improve but remains uneven at the public edge.
REST's lack of an enforced schema is a genuine tradeoff. Without schema enforcement, a careless team can ship a breaking change that goes undetected until an integration fails in production. OpenAPI has become the standard mitigation, and by 2026 external developers expect a machine-readable spec to ship alongside your API rather than be added later in response to complaints.
Where gRPC belongs in public-facing architecture
gRPC is a protocol with a specific job, and it does that job well in the right context.
Mobile apps on constrained, metered connections are a strong fit. Smaller payloads matter when every megabyte has a cost. Uber rebuilt its mobile push platform on gRPC's bidirectional streaming, citing standardized implementations across languages and the ability to run QUIC sessions on mobile through Cronet.
IoT devices fit the same profile. A sensor transmitting frequent, small updates benefits from compact payloads and persistent connections. Because you built the client yourself, the tooling burden that discourages external developers doesn't apply.
Partner APIs are another clear case. If your public API is really a small set of enterprise partners building against a shared SDK or .proto files you distribute directly, the third-party friction argument largely disappears. Typed contracts and generated stubs become an asset rather than a barrier once both sides control their own build pipeline.
For genuinely real-time use cases, such as live tracking, gaming state synchronization, or streaming data feeds, gRPC's four communication modes provide native support for patterns where REST requires additional infrastructure: long polling, server-sent events, or WebSockets managed as a separate system. gRPC earns its place at the public edge when the caller is a known partner, a controlled SDK, or a device you built yourself, not when the caller is an anonymous developer or a browser.
How mature teams deploy both protocols together
Teams that have shipped at scale don't treat this as a binary choice. They split responsibility: REST fronts the public API, gRPC handles internal service-to-service communication, and a gateway sits at the boundary translating between them.
Netflix is the most commonly cited example. Its internal service mesh runs on gRPC, while the public-facing edge goes through Zuul, its API gateway. That split reflects a deliberate architectural decision rather than unfinished migration work.
Mercari and Merpay moved to gRPC internally as the organization scaled. Every microservice's .proto file lives in a shared repository, CI generates client code automatically on merge, and API design review happens on .proto pull requests before implementation begins. That approach reinforces the same pattern: gRPC's benefits appear inside the organization, not at the boundary where external developers integrate.
In the CNCF annual survey, 71% of organizations running a service mesh in production named gRPC as a primary reason for adopting one. Gateways like Envoy and Kong make protocol translation operationally straightforward. One healthcare SaaS company ran REST and new gRPC internal routes side by side for a full year, using gateway routing to migrate incrementally rather than switching all at once.
A practical framework for making the decision
Use the following framework to make your protocol decision. Use the following framework to make your protocol decision. Start with who's calling. If your callers are anonymous or unknown third-party developers, choose REST. Tooling friction settles that question before performance considerations become relevant. If your clients include browsers, choose REST, paired with WebSockets if you need streaming. The browser compatibility constraint isn't negotiable. If your callers are known enterprise partners running their own build toolchain, gRPC is worth evaluating against their existing infrastructure. Mobile and IoT contexts where you control the SDK are where gRPC performs best.
Then assess the environment. Public internet traffic from a heterogeneous mix of client types favors REST's caching and gateway ecosystem. Constrained or metered bandwidth is where gRPC's payload efficiency provides measurable benefit. Real-time bidirectional data exchange belongs to gRPC's streaming modes; REST-based workarounds are functional but introduce additional moving parts.
Finally, consider what your caller reaches for first. If your callers reach for curl or Postman, design for REST. If they reach for a generated SDK in a typed language, gRPC is worth the investment. Needing to support both isn't a compromise; it's a hybrid architecture with a gateway handling the translation layer.
Kelsey Hightower's observation is worth keeping in mind: the wire protocol matters less than the discipline behind it. A well-designed REST API outperforms a poorly structured gRPC implementation. The protocol is a tool; your engineering decisions determine quality. REST's adoption reached 89% according to the Postman State of the API 2025 report, up from 82% in an earlier edition, and that growth reflects a genuine match between what REST was designed to do and what public APIs require.
Notes
- https://smartdev.com/ai-powered-apis-grpc-vs-rest-vs-graphql/
Provided the 23% faster integration statistic from the 2025 State of API report and the 89% REST adoption figure cited in the observability section.
- https://markaicode.com/grpc-vs-rest-benchmarks-2025/
Supplied the specific March 2025 benchmark figures comparing gRPC and REST throughput and latency on the same hardware.


