Direct answer
Build a small rubric of weighted criteria that map to what actually matters for this environment (latency behavior, streaming support, developer ergonomics, language and tooling coverage, observability, and operational cost), score each candidate protocol from 1 to 5 against each criterion, multiply by weight, and let the arithmetic surface the leading option rather than gut feel, then sanity-check the result with a short proof of concept, a small prototype built specifically to validate the winning assumption, before treating it as final.
Criteria and weights
Weights should sum to 100% and reflect what a medium-scale internal microservices environment actually cares about, not a generic checklist:
| Criterion | Weight | Rationale |
|---|
| Latency and performance | 20% | Core cost for internal request-response traffic |
| Streaming and real-time capability | 18% | Needed wherever event or continuous-transfer use cases exist |
| Developer ergonomics | 16% | Directly affects onboarding speed and day-to-day productivity |
| Language and tooling support | 14% | Ecosystem maturity across a polyglot stack |
| Observability and debuggability | 16% | Determines how fast incidents get diagnosed in production |
| Operational cost and complexity | 16% | Ongoing maintenance and infrastructure burden |
Scoring each option
| Criterion (weight) | REST/JSON | gRPC | GraphQL |
|---|
| Latency (20%) | 3, plain HTTP/1.1 plus JSON parsing overhead | 5, HTTP/2 plus binary protocol buffers | 3, similar transport cost to REST plus resolver overhead |
| Streaming (18%) | 2, no native support, needs a bolt-on | 5, streaming is a first-class protocol feature | 3, subscriptions exist but are heavier to operate |
| Ergonomics (16%) | 4, simple and familiar | 3, steeper learning curve for schema and generated clients | 4, strong client-side flexibility |
| Tooling (14%) | 5, universal client and proxy support | 4, strong but less universal than plain HTTP | 4, mature but narrower ecosystem |
| Observability (16%) | 4, works with mature HTTP-native tooling | 3, needs extra config for some proxies and tracing setups | 3, resolver-level tracing needs deliberate setup |
| Operational cost (16%) | 4, lowest day-to-day friction | 3, more moving parts (codegen, proto registry) | 2, added server complexity and the N+1 resolver risk (a naive nested-field resolver can issue a separate database call per item instead of one batched query) |
Computing the result
The weighted total for each option is score=∑iwi×si, computed directly from the table above:
REST/JSON: 3(0.20)+2(0.18)+4(0.16)+5(0.14)+4(0.16)+4(0.16)=0.60+0.36+0.64+0.70+0.64+0.64=3.58
gRPC: 5(0.20)+5(0.18)+3(0.16)+4(0.14)+3(0.16)+3(0.16)=1.00+0.90+0.48+0.56+0.48+0.48=3.90
GraphQL: 3(0.20)+3(0.18)+4(0.16)+4(0.14)+3(0.16)+2(0.16)=0.60+0.54+0.64+0.56+0.48+0.32=3.14
| Protocol | Weighted total |
|---|
| REST/JSON | 3.58 |
| gRPC | 3.90 |
| GraphQL | 3.14 |
Under these weights and scores, gRPC wins for an internal, medium-scale, latency- and streaming-sensitive environment; REST is a close second, well ahead of GraphQL, which is dragged down here specifically by operational complexity and the streaming gap rather than any single criterion.
Trade-offs and pitfalls
A weighted total gives a defensible number, but the weights themselves encode a value judgment the team needs to agree on before the score means anything. If two totals are close (REST at 3.58 versus gRPC at 3.90 here), re-run the same rubric with a couple of alternate weightings, for example dropping streaming's weight and redistributing it to operational cost, to see whether the ranking is sensitive to your specific weighting choices or genuinely robust. A ranking that flips under a plausible alternate weighting is a signal to validate with a real proof of concept rather than trust the score alone; a ranking that holds up across several reasonable weightings is much stronger evidence. Never fill in the 1-to-5 scores from a protocol's general reputation without checking that the specific criterion actually applies to your workload and your team's current skill set.