Kvindo™ Cloud Docs
A Valkey Replication is a managed, non-cluster Valkey deployment: exactly one primary plus N replicas over a single key space. Because every node holds the same key space, multi-key operations (MGET, MSET), MULTI/EXEC, Lua scripting and SELECT 0..15 all work. The sharded Valkey Cluster product cannot serve this: its own documentation states that Celery/Sidekiq-style brokers do not work in cluster mode and that no configuration changes fix it — those frameworks are exactly who this tier exists for.
• Exactly one primary plus N replicas — spec.instances holds 2 to 6 entries (1 replica minimum, 5 maximum); the primary is the single entry whose role is primary. There is no sharding, so the whole dataset must fit in one VM's RAM
• Failover is owned by Valkey Sentinel, never by the platform — Sentinel promotes a replica autonomously on the VMs themselves. The only platform-initiated switch is the declarative manual failover below
• Sentinel is mandatory, with no co-located option on purpose — sentinelInstances is required: exactly 1 or 3, never 2. There is no sentinel-less shape. A Sentinel sharing a VM with a data process loses its timer interrupt under exactly the load that makes failover necessary, enters TILT, and then stops acting and votes no while SENTINEL CKQUORUM still reports OK
• One or three Sentinels, never two — a promotion needs a majority of the voters, and a majority of two survives no failure at all, so exactly two Sentinels is rejected outright
• sentinel_redundancy is single-failure at three Sentinels and none at one — a single Sentinel is automated recovery, not high availability: it removes the human from the common case, but losing it removes failover entirely until it is restored. A one-Sentinel deployment also requires at least two replicas
• A manual failover is declarative and consumed once — set spec.requestedPrimaryInstanceId to the instance you want promoted (requires dedicated mode); the platform performs a graceful demote-then-promote, re-points the remaining replicas and clears the field. There is no automatic failback: a failback is simply a second failover
• Sentinel endpoints are reachable only from inside the VPC or over VPN — Sentinel VMs never receive a public IP, so a client outside the network has no discovery path at all
• status.primaryEndpoint is a snapshot, not a stable address — after a failover it can still point at the demoted node until the next reconcile, and a client that treats it as a fixed write address gets READONLY. Use Sentinel discovery in your client library instead
• Tuning lives in the shared parameter set, not in this spec — maxmemory*, io-threads, appendfsync, min-replicas-max-lag, databases, rdb-enabled and the AOF switch have no field here; they are owned by the Parameter Set, the very same resource the sharded cluster uses
| UI Name | API / kc name | Terraform name | Optional | Format | Default | Is read only | Description |
|---|---|---|---|---|---|---|---|
| Requested primary instance | spec.requestedPrimaryInstanceId |
spec.requested_primary_instance_id |
Yes | ULID — references one of spec.instances |
— | No | Declarative manual failover. Consumed once and then cleared; requires dedicated mode. Empty keeps the current topology, and there is no automatic failback |
| Parameters set | spec.parametersSetId |
spec.parameters_set_id |
Yes | ULID — references a ValkeyParametersSet | — | No | The shared parameter set, the same resource the sharded cluster uses. Owns every tuning knob this spec deliberately lacks |
| Valkey version | spec.valkeyVersion |
spec.valkey_version |
No | string — X.Y.Z |
— | No | No default in this API and not validated synchronously by it — the platform image currently prefetches only 8.1.9, so any other value fails once the request reaches the microservice rather than at submit time |
| Public IPv4 | spec.createPublicIpv4 |
spec.create_public_ipv4 |
Yes | boolean | false |
No | Gives the data instances a public IPv4. Sentinel VMs never get one |
| Instances | spec.instances |
spec.instances |
No | list of objects — 2 to 6 entries (1 primary + 1..5 replicas) | — | No | One entry per data VM. The dataset must fit in one VM's RAM — there is no sharding |
| Instance id | instances[].id |
instances[].id |
No | ULID | — | No | The entry's identity: reuse it across modifies to keep the same VM; a new id is a new VM |
| VPC subnet | instances[].vpcSubnetId |
instances[].vpc_subnet_id |
No | ULID — references a VPC Subnet | — | No | Subnet for this instance |
| VM offer | instances[].vmOfferId |
instances[].vm_offer_id |
No | string (≤32) — compute offer | — | No | Per instance, no platform default (e.g. g3-1c2-100). Size it for the whole dataset plus BGSAVE headroom. Editable after create, one node at a time: the VM is stopped, resized and started again, so that node is offline for the duration. If the node being resized is the current primary, a replica is promoted while it restarts |
| Volume offer | instances[].volumeOfferId |
instances[].volume_offer_id |
No | string (≤32) — disk offer | — | No | Per instance, no platform default (e.g. gp3-750). Editable after create — applied live, no restart (the disk's IOPS/throughput are re-applied in place). This is the deployment-wide volume offer in the console, so it also reaches the sentinel volumes |
| Volume size | instances[].volumeSizeGiB |
instances[].volume_size_gib |
No | integer — GiB, at least 20 | — | No | Per instance. Editable after create, GROW ONLY — a volume can be enlarged in place but never shrunk, because the layer below refuses a decrease (Size can not be decreased). Applied live; no restart |
| Sentinel instances | spec.sentinelInstances |
spec.sentinel_instances |
Yes | list of objects — 1 or 3 entries, never 2 | — | No | Required — Sentinel is mandatory. Every Sentinel must be able to reach the data VMs directly; per-node subnets are allowed |
| Sentinel id | sentinelInstances[].id |
sentinelInstances[].id |
No | ULID | — | No | The entry's identity, same reuse rule as a data instance |
| VPC subnet | sentinelInstances[].vpcSubnetId |
sentinelInstances[].vpc_subnet_id |
No | ULID — references a VPC Subnet | — | No | Must be the primary's subnet |
| VM offer | sentinelInstances[].vmOfferId |
sentinelInstances[].vm_offer_id |
No | string (≤32) — compute offer | g3-1c1-100 |
No | Pinned server-side: a Sentinel needs single-digit MB of RSS, and a larger offer only invites a data process onto the failover control plane |
| Volume offer | sentinelInstances[].volumeOfferId |
sentinelInstances[].volume_offer_id |
No | string (≤32) — disk offer | — | No | Per Sentinel |
| Volume size | sentinelInstances[].volumeSizeGiB |
sentinelInstances[].volume_size_gib |
No | integer — GiB | 10 | No | Sentinels store almost nothing |
This spec carries no tunable field at all — not maxmemory, io-threads, appendfsync, min-replicas-max-lag, not the AOF switch, and not databases or rdb-enabled either. Every one of them is a valkey.conf directive, so the shared Valkey Parameter Set owns them — the same resource the sharded cluster uses, because tuning belongs to a Valkey estate rather than to one product.
One primary, one replica and one Sentinel, on a single subnet, with tuning taken from an existing parameter set.
Terraform
Python SDK
kc CLI
Resource docs
Examples
More in this section