Principle:Vespa engine Vespa Subscription Registration
| Metadata | |
|---|---|
| Sources | Vespa |
| Domains | Configuration, Distributed_Systems |
| Last Updated | 2026-02-09 12:00 GMT |
Overview
Configuration subscription registration establishes a typed binding between a process and a named configuration resource, enabling processes to declare interest in specific config types and receive type-safe handles for later retrieval.
Description
In Vespa's distributed configuration system, every process that needs configuration must first subscribe to the specific configuration types it requires. Subscription registration is the foundational step of the config subscription lifecycle: it creates a typed binding between a running process and a named configuration resource identified by a configId.
The subscriber pattern decouples configuration production from consumption. A config server (or other source) produces configuration data, while client processes consume it through subscriptions. The subscriber does not need to know how or where config is produced -- it only declares what it wants (the config type) and which instance it wants (the configId).
Each call to subscribe returns a ConfigHandle -- a type-safe handle that can later be used to retrieve the actual configuration object. This handle-based design ensures that:
- Type safety is enforced at compile time through C++ templates
- Multiple configs can be subscribed to atomically before any are fetched
- Decoupling is maintained between the subscription phase and the consumption phase
The subscription phase has an important constraint: once nextConfig() or nextGeneration() is called, the subscription set becomes FROZEN. No further subscriptions can be added. This guarantees that all config types are known before the first fetch, enabling the system to deliver a consistent configuration snapshot across all subscribed types.
Usage
Use this principle when a Vespa C++ process needs to declare its configuration dependencies at startup. Subscription registration is always the first step in the config subscription lifecycle, performed before any config data is fetched or applied.
Typical scenarios include:
- A search node subscribing to document type, rank profile, and cluster configuration
- A container process subscribing to its application configuration
- Any Vespa service that needs to read configuration from the config server cluster
Theoretical Basis
The subscription registration pattern follows the Observer design pattern (also known as Publish-Subscribe). In this model:
- The Subject (config server) maintains configuration state
- The Observer (subscribing process) registers interest in specific state changes
- The Handle serves as the subscription token that binds observer to subject
The freeze-after-first-fetch constraint ensures snapshot isolation across multiple configuration types. Without this constraint, a process could observe an inconsistent configuration state where some configs are from generation N and others from generation N+1.
Formally, if a process subscribes to config types C1, C2, ..., Ck, the system guarantees that after nextConfig() returns true, all handles will reflect the same configuration generation g:
- gen(Ci) = g for all i in {1, ..., k}