OriginChain
solution · real-time personalization

The same atomic write updates and serves.

A user clicks 'like.' Your model wants to personalise the next page based on that click. With most stacks, you get an embedding update delay. With OriginChain, you don't.

the read-your-writes problem

Two systems means a window.

Write the click to Postgres, push the embedding update to your vector DB, query the vector DB on the next request - and during the millisecond-or-more window between the two writes, retrieval doesn't see the click.

For batch jobs that doesn't matter. For personalisation it's the whole product.

click + retrieve, atomic
POST /v1/tenants/:t/batch
{
  "ops": [
    { "sql":    "INSERT INTO clicks ..." },
    { "vector": { "schema": "user_pref",
                  "put": [ { "id": "u_84", "vector": [...] } ] } }
  ]
}

POST /v1/tenants/:t/vector/search
{
  "schema": "items",
  "k": 12,
  "dense":  { "vector": "@user_pref:u_84", "metric": "cosine" }
}
the contract
01
Single-writer

The write is durable and visible to the writer immediately. No quorum, no replication ack.

02
WAL-frame atomic

Preference vector + click row + audit hit ride one frame. Either all land, or none.

03
Predicate-aware kNN

The next personalised retrieval sees the new state. No 'eventually consistent' explainer in your runbook.

tie to /ask

"Show me things like the one I just liked" works in NL because the substrate just saw the like. /ask can route the retrieval; the answer always sees the latest state.

deferred
  • post-1.0Multi-region replication. Single-region until then.
  • not usFederated user vectors across tenants.

See the vector + /ask surface.