Published in openvibe-contracts v0.76.0 (docs/adr/ADR-035-postgresql-and-valkey.md), rendered as is.

ADR-035: PostgreSQL and Valkey as the data tier

Status: Accepted 2026-09-28, the owner's decision ("we should just get it over with now … so we don't waste time later"). Supersedes the "a service moves only on a measured trigger" rule of ADR-007's 2026-09-26 amendment. ADR-007's ownership rule and its 2026-09-24 runtime posture stay in force and bind every step below. Roadmap workstream WS-X2, requirement D48.

Context and current evidence

Decision

  1. PostgreSQL is the system of record for every service. One cluster serves the "data" role (ADR-034 section 12; roadmap WS-X1). It runs on the current host until a data server is bought, when the role moves by inventory.
  1. Valkey is the shared, non-authoritative store (rule 4 applies; Valkey replaces the "Redis" of rule 4):
  1. Backups.
  1. One async data layer in the SDK (openvibe-sdk/db), with PostgreSQL and SQLite adapters behind the same interface:

openvibe-sdk/cache, /queue and /pubsub wrap Valkey the same way.

  1. New services start on PostgreSQL and Valkey. Every product in roadmap section 4B does.
  2. Existing services migrate one at a time, smallest first, following expand/migrate/contract:
  3. Move the service's data access onto openvibe-sdk/db while it still runs on SQLite. The suite must pass unchanged.
  4. Create the PostgreSQL schema, then copy with verification: row counts and per-table checksums, under a short write freeze or dual writes.
  5. Switch reads and writes to PostgreSQL, keeping the SQLite file read-only for the N-1 window (ADR-016, 7 days) as the rollback.
  6. Then delete the SQLite file after a final backup.

Order: Wiki, Blog, News, Reviews, Deals, Coupons, Trade, Tips, VIP, Search, Sources, Codes, Host, AI, Events, Chat, Community, Billing, Media, Tools, Games, OpenRe, Network, Live. Each migration is its own change, with its own rehearsal on a copy of the production data.

  1. Sizing on the shared host, until the data role has its own machine:

These are revisited when the role moves.

  1. Observability. Exporters for PostgreSQL, PgBouncer and Valkey feed Prometheus. Alerts cover:

Alternatives considered

Migration consequences

Rollback

Acceptance tests

Amendment 2026-09-28 (same day): one dialect, async-first, every service

The owner confirmed after the costs were laid out: "everything should be async focused and highly optimized/efficient in the first place … migrate all of it". So:

  1. One SQL dialect. Services write PostgreSQL SQL only. The data layer has no SQLite adapter.
  1. A one-time import from SQLite. openvibe-sdk/db ships a verified importer from a service's SQLite file into its PostgreSQL schema:

Item 6's per-service steps become:

  1. the PostgreSQL schema;
  2. data access async on the layer;
  3. per-process state to Valkey;
  4. suites on PGlite and CI PostgreSQL;
  5. a rehearsal on a production copy;
  6. a short write freeze, the import and the switch;
  7. the SQLite file kept read-only for the N-1 window as the rollback, then archived and deleted.
  8. Every service migrates, in item 6's order. The roadmap's engineering standards (section 4B.7) bind each one: