MDK Logo

Scalability

How far MDK scales, along which axes, and what changes as a deployment grows

The axes

Three independent numbers describe how big an MDK deployment is:

  • Devices per Worker plugin: how many devices one Worker instance manages. Bounded by the device protocol and the Worker's own connection model, not by Kernel.
  • Worker instances per Kernel: how many Worker processes one Kernel coordinates. Kernel places no hard cap; the practical limit is how much command/telemetry traffic one Kernel process can route.
  • Kernels per Gateway: how many Kernel instances one Gateway (and, above it, one AI agent) connects to at once.

This page is about how many Workers and Kernels a deployment runs, not how those processes are packaged on a host (one process versus many machines). That's a deployment topology choice, made independently of the numbers on this page.

Single-kernel versus multi-kernel

The one topology distinction this page owns: does your deployment run one Kernel serving a site, or several Kernels, each serving its own site, behind one Gateway?

  • One Kernel is the default and the right choice until you have a concrete reason to split: a single Kernel process routes commands and telemetry for every Worker registered to it, with no per-Worker partitioning.
  • Several Kernels, one per physical site, is the shape for multi-site operations (for example, a Texas site and an Iceland site). Each Kernel is fully isolated: Kernel instances do not federate registries, share queues, or synchronize state with each other. A crash at one site has zero effect on any other. A single Gateway (and, above it, an AI agent) connects to all of them and merges results in its own controller code: that aggregation is Gateway-layer work, not something Kernel does for you.

When to add a Kernel

Add a second Kernel when you're adding a second physically- or organizationally-distinct site, not because one Kernel is running out of capacity for a single site's device count: Kernel is not currently known to bottleneck at realistic single-site device counts (see the benchmark table below for what's actually been measured). Splitting Kernels for a single site buys you nothing: you'd gain isolation you don't need and lose the single registry that makes routing simple.

What serializing Workers and Kernels means

Workers never share devices: device-to-Worker ownership is a strict, exclusive mapping the registry enforces, so adding Worker instances scales device count linearly with no coordination between them. Kernel routes to whichever Worker owns a deviceId; it does not load-balance a device's traffic across multiple Workers, because only one Worker is ever registered as the owner of a given device at a time.

Where state lives as you grow

See the storage model for the full picture. In short: each Kernel keeps its own separate store: a multi-Kernel deployment means multiple independent stores, not one shared or federated one.

Failure behavior

  • A single Worker going offline degrades reads/writes for that Worker's devices only. Kernel continues routing to every other registered Worker normally.
  • A Kernel crash is recovered from its own command write-ahead log on restart (recover() sweeps non-terminal command states); it does not need to reconstruct device state, since it never owned it.
  • In a multi-Kernel deployment, one site's Kernel going down has no effect on any other site's Kernel: there is no shared state to become inconsistent.

Benchmarks pending

A real benchmark harness exists (backend/tests/benchmark/) and can measure device counts, telemetry throughput, and command latency at a given topology, but no baseline numbers are committed yet. This table reserves the shape for when they are:

TopologyDevicesTelemetry throughputCommand latency (p50/p99)
Single Kernel, single Workerpendingpendingpending
Single Kernel, N Workerspendingpendingpending
Multi-Kernel (per-site)pendingpendingpending

Next steps

Next steps

On this page