Essay:

Building high-scale, distributed apps with - Google Cloud, Kubernetes, Microsoft Orleans, .Net Core & Xamarin Forms (1/3)

By Vishnu Rajkumar

Originally published on linkedin

Building high-scale, distributed apps with - Google Cloud, Kubernetes, Microsoft Orleans, .Net Core & Xamarin Forms (1/3)

What happens if you wake up one day and are struck by the idea of building something for the world, in the order of WhatsApp or Uber? These applications are representative of the kind of high-scale, distributed software that many future consumer systems will share. The goal here is to explore a systematic way to build systems that are scalable and robust.

This article is the first of a three-part series. It focuses on the design and architecture phase: how to think about the problem, what kinds of components you need, and how to map product needs to technology choices.

This article attempts to devise ways to think about such a massive system and tame the chaos associated with scale, complexity, and technology. The approach is broken into three parts:

  • Design and architecture
  • Deploy and implement
  • Operate and stabilize

The first part covers design and architecture.

Design and Architecture

The design phase begins by identifying the priorities for an internet-scale distributed application and mapping those priorities to the right services and components. In other words, this is where we imagine the real-world shape of the system before implementation starts.

For the sake of a concrete example, imagine a taxi service. Users and drivers are both large in number, taxis are constantly moving, and the backend has to book the nearest taxi, track it in real time, and keep the experience responsive even under load.

The broad technology stack in this example is:

  • Cloud platform for hosting and PaaS services: Google Cloud, Microsoft Azure
  • Container and orchestration: Docker and Kubernetes
  • Actor framework for high-scale distributed computing: Microsoft Orleans
  • Mobile app platform: Xamarin Forms

Before going deep into implementation details, the system can be thought of using a 4+1 architecture lens. The main idea is that different parts of the system will have different load, latency, upgrade, and language requirements.

Core Infrastructure, Technologies & Kubernetes

Kubernetes is the primary compute tier for most services in the design. PaaS services are used where it makes sense to avoid reinventing specialized capabilities. Any code that is written becomes a container or service in the Kubernetes cluster, and any code that is avoided is replaced by a managed service that already fits the scale and cost profile.

The component view of the system includes:

  1. Mobile and web clients requesting a taxi and sending location plus identity data.
  2. A Google Cloud L7 load balancer, provisioned through Kubernetes Ingress, handling routing.
  3. All application code and services running in managed Kubernetes in Google Cloud.
  4. Taxis sending their geolocation to the system continuously.
  5. Google Cloud Pub/Sub consuming the incoming taxi location stream.
  6. Application services exposed as Kubernetes services, each independently scalable.
  7. The backend representing users, drivers, and vehicles as Orleans grains.
  8. Orleans cluster membership stored in Azure Table Storage.
  9. Geographical search updates pushed into Azure Search.

This diagram does not try to cover monitoring, logging, or CI/CD. Those belong in the next part of the series.

Application Architecture - Microservices

The application follows a microservice pattern. Kubernetes makes it easy to build this with services, pods, ingress, and load balancing. Core capabilities like booking a taxi, searching for a taxi nearby, and applying campaign logic are separated into independently scalable services.

Each service can be upgraded independently without affecting the whole system. Versioning can happen at the URI level or through headers, with a service mesh if needed.

Virtual Actors & Microsoft Orleans

The system has a lot of state to manage: taxi locations, rider requests, driver availability, ride history, and regional demand. Orleans is a good fit here because it provides a simple actor model with isolated state, single-threaded execution per grain, and a strong story for scale and concurrency safety.

In this design:

  • Every taxi, driver, and rider can be represented as a grain.
  • Silos run as pods in the Kubernetes cluster.
  • The cluster membership table tracks which silos are healthy.
  • If a silo fails, the cluster redistributes work and keeps the system alive.

That makes the system resilient without forcing the application to manage the concurrency and distribution mechanics directly.

gRPC, Http2, Binary Serialization & Streaming Data

The system uses gRPC for communication between clients and the backend. The reasoning is straightforward: HTTP/2 multiplexing plus binary serialization and streaming make a far better fit for low-latency, real-time interaction than repeated HTTP/1.1 polling.

That matters especially for a taxi service, where the user should be able to see a vehicle approach in real time and not wait on repeated calls to a server endpoint.

So far, this part has focused on the high-level architecture, technology choices, and the major building blocks. Microservices, scale, streaming data, and distributed behavior are first-class concerns in this design.

In the next section, the implementation details cover CI/CD, Spinnaker, VSTS/Travis, Kubernetes scaling, deployment, and the service structure for the microservices and Orleans silos.

Evaluation criteria, product selection, geographic distribution, disaster recovery, and backup are intentionally out of scope for this piece.

Originally published on LinkedIn

WRITTEN BY

Vishnu Rajkumar

Vishnu leads AI engineering at Microland and writes about artificial intelligence, systems, judgment, work and technological change.

About the author →