Picture an online store. The checkout service needs the current price for an item, the user's saved address, and a fraud score before it can place an order. Over REST that is three separate HTTP calls, each opening a connection, sending JSON headers, and parsing a JSON body.
With gRPC, the checkout service holds one persistent HTTP/2 connection to each backend and fires getPrice, getAddress, and getFraudScore as multiplexed calls in flight at the same time. Each message is a few dozen bytes of protobuf. The generated client code means the developer just writes pricingClient.getPrice(request) and gets back a typed Price object, no manual parsing.
If the catalog team later adds a currency field to the price message, they add it with a new field number that has never been used, regenerate, and old clients that do not know about the field simply ignore it. Nothing breaks, and the upgrade is backward compatible by design.