kdb as unified data plane
stackRFC001 — kdb as unified data plane
Abstract
kdb-next (TiKVbacked, RFC001 of kdb-next) evolui de "replacement relacional do kdbGo atual" para *ubstrate primário multimodel unificado da Koder Stack* Layers especializadas (relational, time-series, KV, vector, search, stream) compartilham o mesmo substrate distribuído (TiKV + MVCC + Raft + Percolator) e ganham ACID cross-model nativo. Componentes Koder param de manter Redis/ Timescale/Elasticsearch separados; passam a falar com kdb-next através de drivers SQL ou protocol-specific shims.
Três stores ficam *egitimamente fora*do kdb-next:
- *kdrive`*(object storage, S3
compat): blobs > 1 MB, petscale - *edis local*em hot paths que provadamente exigem < 1ms p99
- *RDT layer*(Yjs/Automerge) pra collaborative state com
consistência eventual
Pra *udo o resto*(sessões, rate-limit counters, métricas, search index, audit logs, telemetry, vector embeddings, stream events), kdb-next é o destino.
Motivation
O problema atual
A Koder Stack hoje (20260509) tem ~7 storage tiers diferentes em produção:
- *ostgres*(kdb 18.3) em LXC
kdb— relational principal - *imescaleDB*em LXC
kbull— time-series - *edis*em alguns LXCs (sessões kbot, hot caches)
- *inIO*em LXC
kdrive— S3-compat blobs - *db-next*em desenvolvimento (LXCs futuros) — relational
hyperscale
- *ilesystem*em vários componentes — flat-file state
- *n
memory*maps em alguns serviços — nãopersistent state
Cada tier tem:
- Backup separado, com falhas correlacionadas em incidentes
- Auth model próprio (Postgres roles, Redis ACLs, MinIO IAM)
- Monitoring/alerting separado
- Failure modes incompatíveis (Postgres ACID vs Redis eventually-
consistent vs filesystem unreliable)
- Migration path único por tier (mexer em schema → 7× operação)
Cross-tier transactions são *mpossíveis*— uma operação que escreve credentials no kdb e invalida cache no Redis pode falhar no meio: cache stale + DB consistent. Cada componente reinventa saga / outbox pattern.
A vision
kdb-next (TiKV) substrate unificado, com *ayers*específicas servindo cada padrão de acesso. Mesmo MVCC + Raft, mesmo backup, mesmo auth model, mesmo monitoring, *ransactions cross-model ACID nativo*
O pattern é *iDB ecosystem*aplicado à Koder Stack:
TiDB ecosystem: Koder Stack equivalente:
TiKV ─── KV kdb-kv (KV nativo, expor TiKV)
TiDB ─── SQL kdb-next (relational SQL)
TiFlash─── OLAP kdb-flash (column-store, futuro)
TiCDC ─── change kdb-cdc (Raft log → consumers)Plus layers específicas Koder:
kdb-ts time-series (hypertable-style sobre TiKV ranges)
kdb-vec vector (ANN sobre TiKV-stored embeddings)
kdb-search full-text (Lucene-style index, derivado via CDC)
kdb-stream pub/sub (Raft log → fan-out subscribers)Result: *m substrate, sete interfaces* ACIDcrosseverything.
Goals
- Substrate único pra *oda persistent data*em apps Koder (com 3
exceções listadas em §Non-goals)
- Multi
model (relational, KV, timeseries, vector, search, stream)sobre o mesmo TiKV
- ACID cross
model nativo (escrever em timeseries + atualizarcontador KV + emitir evento no stream = uma transação)
- Multi
tenantbydefault (alinhado com `policies/multitenant-by-default.kmd`)
- Multi
cluster + multiregion + active-active (alinhado comkdb-RFC-008+kdb-RFC-009) - HA (Raft replication, auto-failover)
- Read replicas (alinhado com
kdb-RFC-011) - Hyperscale (100M+ tenants target, alinhado com
kdb-RFC-001) - Operações simplificadas: 1 backup process, 1 monitoring stack,
1 auth model
Nongoals (stay outside kdbnext)
Estas três categorias *ão convergem*pro substrate, por design:
1. Object/blob storage
Bytes grandes (release artifacts > 1 MB, attachments, build outputs, user uploads, container images, video frames, audio waveforms) ficam em kdrive (MinIO ou sucessor S3-compat).
Razão técnica: TiKV não é otimizado pra blobs. Replicação Raft de um blob 100MB satura I/O sem ganho — Raft consensus pra dado que não muda é overkill. GC de blobs MVCC é complexo. Object store dedicado é pattern correto.
Coordenação: kdbnext armazena *etadata + ACL + signedURL config* kdrive serve bytes. É o pattern S3 + Postgres bem estabelecido.
2. Edge cache (sub-ms hot paths)
Onde p99 < 1ms é requisito real e não negociável:
- Auth token → user_id resolution (toda request passa por aí)
- Rate-limit counters (incrementar em < 100µs)
- Presence indicators (collaborative cursors, online users)
Estes ficam em *edis local in-process do componente* com keys prefixadas por tenant (tenant:<uid>:<key>).
kdbnext é *ource of truth* Redis é readthrough cache + write queue, com TTL agressivo (segundos) e invalidação pelo CDC quando kdb-next muda.
Critério: hot path deve ser *rovadamente*> 100× mais frequente que cold path **atender p99 < 5ms para justificar Redis. Caso contrário, kdb-next direto basta.
3. CRDT collaborative state
Live presence, OT cursors, real-time editing — modelo de consistência é eventual + merge functions. Forçar transações ACID adiciona latência demais e quebra o pattern.
Solução: Yjs/Automerge layer (inprocess percomponent, sincroniza P2P entre clients via WebSocket). Snapshot persistido em kdb-next periodicamente (cada N segundos ou no save explícito do user).
High-level architecture
┌──────────────────────────────────────────────────────────────────────┐
│ Application APIs │
│ (kode, hub, flow, kortex, gateway, jet, id, kbot, talk, drive, …) │
└────────────────────────────┬─────────────────────────────────────────┘
│
┌────────────────┼────────────────┐
▼ ▼ ▼
SQL driver KV driver TS driver
(relational (cache, hot (metrics,
+ transac- counters) audit, logs)
tions)
│ │ │
└────────────────┼────────────────┘
▼
┌────────────────────────────────────┐
│ kdb-next adapter layer │
│ - SQL parser/planner │
│ - KV expose │
│ - TS hypertable layer │
│ - Vec ANN layer │
│ - Search index (derived via CDC) │
│ - Stream (Raft log → fan-out) │
└────────────────┬───────────────────┘
▼
┌────────────────────────────────────┐
│ TiKV substrate │
│ - MVCC │
│ - Raft replication (3+ nodes) │
│ - Percolator distributed txn │
│ - PD (placement driver, multi- │
│ region geo-aware sharding) │
└────────────────────────────────────┘
│
▼
┌─────────────────┐ ┌─────────────────┐
│ kdrive │ │ Redis local │
│ (S3-compat blob)│ │ (hot cache, │
│ │ │ source-of- │
│ kdb-next holds │ │ truth in │
│ metadata + ACL │ │ kdb-next) │
└─────────────────┘ └─────────────────┘Layers detalhadas
Layer 1 — kdb-next SQL (relational)
Status: em desenvolvimento (RFC001 do kdbnext; shadow-active).
Surface: SQL completo, drivers Postgres-compatible (apps falam SQL via lib pgxpqetc. sem mudanças).
Use cases:
- User accounts (Koder ID)
- Repositories (Flow)
- Workspaces, memberships
- Credentials (FLOW-003 hierarchy)
- Permissions, ACLs
- Tudo que tem queries com JOIN, GROUP BY, transações
ACID: full MVCC, distributed transactions via Percolator.
Layer 2 — kdb-kv (KV nativo)
Status: planejado (este RFC).
Surface: API estilo Redis (GET/SET/DEL/EXPIRE/HGET/SADD) ou native TiKV client.
Use cases (que hoje usam Redis):
- Sessões SSO
- Rate-limit counters
- Background job queues (com transações pra garantir delivery)
- Distributed locks (TiKV native suporta isso)
- Session-presence (tracked com TTL)
Diferença vs Redis local: persistência + cross-region replication + ACID com outras layers. Latência: ~1-2ms vs ~50µs do Redis local.
*uando usar kdb-kv vs Redis local* ver §Non-goals item 2.
Layer 3 — kdb-ts (time-series)
Status: planejado (parcial em kdb-RFC-007).
Surface: hypertable-style API, similar ao TimescaleDB. Particionamento automático por tempo + tenant.
Use cases:
- Token usage tracking (rate_limit observations) — *aso direto que
motiva esta RFC*
- Métricas Prometheus (component health, request rates)
- Audit logs com retention
- Telemetry de apps clients (kode/app, kbot)
- Activity feeds (Koder ID profile activity)
Features:
- Continuous aggregates (rollups)
- Compression de chunks > 7 dias (factor ~10×)
- Retention policies per-tenant
- TimescaleDB-compat query syntax (gradual migration de kbull)
Layer 4 — kdb-vec (vector / ANN)
Status: planejado (futuro, sem RFC ainda).
Surface: API similar a pgvector ou Milvus.
Use cases:
- Embeddings de docs pra search semantic (Krep, Kortex)
- Embeddings de prompts/responses pra Claude history search
- Recommendations (Hub package similarity)
Trade-off: layer dedicada (Milvus) é mais performática em escala massive (>100M vectors); kdb-vec basta pra <10M. Reavalia quando hit.
Layer 5 — kdb-search (full-text + structured)
Status: planejado (depois de kdb-vec).
Surface: query API similar a Elasticsearch.
Implementação: index Lucene-style *erivado*de tabelas relational via CDC. Quando uma row no Flow muda, índice atualiza. Latência de indexação: ~ms (singleregion) ou ~100ms (crossregion).
Use cases:
- Full-text search no Hub (apps, skills)
- Code search complementar ao
koder-krep(que cobre on-disk grep) - Search em issues, PRs, comments do Flow
Layer 6 — kdb-stream (pub/sub + change capture)
Status: planejado.
Surface:
- Producer: TiKV Raft log → topic (toda mutation cabe em event)
- Consumer: subscribe a topic via gRPC streaming
Use cases:
- CDC pra fora (cliente integrações, ETL pra warehouse)
- Webhooks (Flow webhooks ficam aqui em vez de table polling)
- Notification fan-out (Hub release → notify followers)
- Build trigger queues (commit → CI runner)
Substitui Kafka pra cargas internas. Externos (clientes B2B com Kafka existente) podem consumir via mirror.
Multi-tenancy alignment
Esta RFC e policies/multi-tenant-by-default.kmd são *omplementares*
- A policy diz "todo dado tem
koder_user_id/workspace_id" - Esta RFC diz "e o substrate único onde cada layer implementa
isolamento na sua linguagem nativa é kdb-next/TiKV"
Cada layer implementa isolation conforme spec specs/multi-tenancy/contract.kmd:
| Layer | Isolation |
|---|---|
| kdb-next SQL | Postgres-style RLS via current_setting('koder.uid') |
| kdb-kv | Key prefix obrigatório (tenant:<uid>:) |
| kdb-ts | Hypertable index (koder_user_id, time) + RLS |
| kdb-vec | Filter por metadata {tenant: <uid>} em ANN |
| kdb-search | Index per-tenant ou global com filter mandatory |
| kdb-stream | Topic naming tenant.<uid>.<resource> |
Cross-tenant queries: *rror by default* Admin path explícito com audit.
Multi-region
Alinhado com kdb-RFC-008 (multiregion replication) e `kdbRFC-009` (active-active).
Topology esperada (long-term):
- 3+ regiões geográficas (ex: SP, EU, US)
- Cada tenant tem *ome region*(storage primary)
- Replicação assíncrona pra outras regiões (read
only crossregion) - Active-active permite escrever em qualquer região; conflitos
resolvidos via Lamport timestamps + LWW per
key (ou CRDTlike merges).
PD (Placement Driver) gerencia placement consciente de tenant home region.
HA
Alinhado com kdb-RFC-001 + kdb-RFC-011:
- 3+ Raft replicas por shard (default 3, configurável 5 pra crítico)
- Auto-failover < 5s
- Read replicas standby (kdb
RFC011) pra cargas pesadas de read - Backup contínuo via incremental WAL streaming pra object storage
Roadmap fasings
*ase atual = 0*(consolidação). kdb
next em shadowactive, RFC001 do kdbnext + RFC007 (timeseries) + RFC008 (multi-region) + RFC009 (activeactive) + RFC-011 (read replicas) já desenhados. Layers KV, vector, search, stream ainda em conceito.
Fase 0 — hoje (consolidação relational)
- kdb
next em shadowactive no monorepo - Postgres
kdbcorrente serve produção - 5 RFCs do kdb-next ratificadas (architecture, timeseries,
multi
region, activeactive, read-replicas)
Fase 1 — próximos 6 meses (kdb-next primary relational)
- Flip kdb-next pra primary em *odos*componentes que usam Postgres
- Foundation/id já tá nele; flow, hub, kortex seguem
- Aposentar kdb (Postgres) — preservado pra recovery, não rota ativa
Fase 2 — kdbts (timeseries unified)
services/ai/gatewaytoken-usage tracker (proposta inicial desteRFC) é o *aso piloto*
- Migrar kbull (TimescaleDB) pra kdb-ts
- Métricas Prometheus passam por kdb-ts
- Activity feeds, audit logs
Fase 3 — kdb-kv + Redis aposentadoria
- Sessions, rate
limit counters, queues migram pra kdbkv - Redis fica só onde *rovadamente*justificado por p99 < 1ms
(auth token resolution, hot rate
limit) — com kdbnext como source- of-truth
Fase 4 — kdbsearch + kdbstream + kdb-vec
- Search Hub passa pra kdb-search
- Webhook delivery passa pra kdb-stream
- Vector search semantic passa pra kdb-vec (ou Milvus se escala
exige)
Fase 5 — full convergência
- Único storage stack: kdb
next + kdrive + Redisemedgecases-específicos
- 1 backup process, 1 monitoring stack, 1 auth model
- Cross-model transactions usadas livremente
Tempo estimado realista: *-5 anos*com team focado. Comparáveis:
- TiDB ecosystem maturou em ~7 anos (2015 → 2022)
- Spanner ~5 anos antes do paper (2007 → 2012)
- FoundationDB ainda evolui após 2015
Promotion gates (per-layer)
Cada layer (kdbkv, kdbts, etc.) só vira default na Stack quando passar pelos * gates*de policies/self-hosted-first.kmd:
- *eature parity* cobre todos use cases do incumbent
- *erformance* bench a la
koder-benchmostrakdb-<layer>≥incumbent em workload representativo
- *tability* 30 dias em prd shadow-active sem regressão
- *apability* features novas que o incumbent não tem (ACID
cross
model, multiregion native) - *ritical-path readiness* smoke tests em todos consumers
passam
Gate fails → layer fica shadow, incumbent permanece. Não force flip.
Costs / risks
Risk 1 — engenharia massiva
Implementar 6 layers sobre TiKV é trabalho de anos. Time pequeno.
*itigação*
- Adoção incremental (RFC
001 do kdbnext já é essa direção) - Reuso de tech upstream (TiKV é battle-tested)
- Algumas layers (kdb
vec, kdbstream) podem ser deferred 2-3 anos - Spec aceita usar terceiros temporariamente quando layer ainda
não existe (Milvus pra vector enquanto kdb-vec não rola)
Risk 2 — vendor lock-in técnico
Stack Koder fica fortemente acoplada a TiKV. Se TiKV (PingCAP) sair do business, Koder herda manutenção do upstream.
*itigação*
- TiKV é Apache 2.0 license (não vendor-lock estrito)
- TiKV é CNCF Graduated (community-managed)
- Apesar disso, alternativas pro substrate (FoundationDB, etc.)
ficam documented em
policies/self-hosted-first.kmdcomo fallback option.
Risk 3 — performance ceiling local
Substrate distribuído > engine local em algumas cargas (Redis inprocess). Forçar tudo em kdbnext degrada hot paths.
*itigação*
- §Non-goals lista as 3 categorias que ficam fora
- Promotion gate #2 exige bench parity antes de flip
Risk 4 — operational complexity migration
Cada migration de layer requer dados-shadow + cutover + rollback plan. 6 migrations × 50 componentes = matrix big.
*itigação*
- RFC
001 do kdbnext já provou o padrão (shadow + diff + flip) - Migration tooling reusable (incus snapshots, mig-runners) já
existe na stack
- Faseamento conservador (1 layer por trimestre)
Open questions
- *kdb-vec` vs Milvus dedicated* ANN em scale > 100M vectors
é genuinamente domínio especializado. Vale construir kdb-vec ou preservar Milvus como exception permanente igual kdrive?
- *ctive
active conflict resolution* LWW (lastwrite-wins)per-key é suficiente, ou precisamos CRDTs serializáveis pra alguns dados (ex: contadores)?
- *onsumer migration tax* cada componente flip de Postgres →
kdb
next, Redis → kdbkv, Timescale → kdb-ts custa horas de refactor. Faseamento detalhado percomponente exige subRFCs.
- *ackup story* cross-model snapshot consistente é trivial
no TiKV (single MVCC timestamp). Mas restore pra um ponto
notempo cross-cluster precisa coordination — RFC dedicada provavelmente.
- *uthn/authz unified* hoje cada storage tier tem seu auth.
Kdb-next deveria delegar pra Koder ID nativamente? Quanto acoplamento?
Decision
*tatus: draft*até owner ratificar. Após ratificação:
- Vira referência canonical pra qualquer decisão de storage na Stack
- IAs e engs novos consultam-no antes de propor "vamos botar Redis
pra isso"
- Sub
RFCs detalham cada layer (kdbkv, kdbts, kdbvec, kdb-search,kdb-stream) — abertas conforme prioridade
- Roadmap entra em
meta/docs/stack/registries/storage-convergence.mdpra tracking de migration debt per-componente
Related work
infra/data/kdb/docs/rfcs/kdb-RFC-001— substrate architectureinfra/data/kdb/docs/rfcs/kdb-RFC-007— time-series storageinfra/data/kdb/docs/rfcs/kdb-RFC-008— multi-regioninfra/data/kdb/docs/rfcs/kdb-RFC-009— active-activeinfra/data/kdb/docs/rfcs/kdb-RFC-011— read replicaspolicies/multi-tenant-by-default.kmd— tenant isolationpolicies/hyperscale-first.kmd— implementation principlepolicies/self-hosted-first.kmd— promotion gate framework
Significance
Sem RFC, cada novo módulo da Stack escolhe storage isoladamente, acumulando débito técnico de divergência. Em 5 anos seriam 20+ storage tiers diferentes, multiplicando custo operacional e inviabilizando ACID cross-module.
Com RFC, a direção está pinada e qualquer escolha contrária precisa de justificativa explícita (e exception path em §Non-goals).
Esta é a equivalente da "always RDBMS" decision tomada por gigantes nos anos 2000 — exceto que hoje a apostamos é "always TiKV substrate" e ganhamos hyperscale + multi-model nativo.