Architecture Overview
Synchro uses an extension-based server architecture.
The authoritative server-side sync contract runs inside PostgreSQL. Host layers stay thin and replaceable. Native clients own local SQLite, queueing, scheduling, and safe apply.
The current release architecture is:
extensions/synchro-coreowns shared deterministic sync semanticsextensions/synchro-pgowns PostgreSQL-near execution, scope materialization, and synced CRUD applicationapi/gois one host layer for transport, auth integration, and HTTP translation- native clients own local SQLite, queueing, scheduling, and safe apply
- React Native is a bridge over the native clients, not an independent sync engine
Why this shape
Section titled “Why this shape”This architecture exists to keep:
- the server-side sync contract in the database layer
- the host layer thin and replaceable
- sync semantics close to the data
- native SDK behavior consistent
- the hot path low in round trips
Core design choices
Section titled “Core design choices”- deterministic server-defined scopes
- server-defined synced column sets for registered PostgreSQL tables
- extension-side change capture and materialization
- per-scope cursors and explicit rebuild
- full synced CRUD for synced tables
- the exact protocol version 3 portable type vocabulary in manifests and wire values; clients reject aliases, alternate casing, and physical database type names
- SQL migration based configuration, with structured defaults and custom SQL escape hatches
Architecture guides
Section titled “Architecture guides”The core architectural guidance is split into dedicated pages:
Scope model at a glance
Section titled “Scope model at a glance”The most important selective-sync rule is still:
- optimize for low row-change fanout, not low total scope count
Recommended baseline:
- private data can use the default identity scope
user:{user_id} - shared data lives in shared scopes such as
templates_public - one local SQLite table may be fed by both shared and private scopes
Row membership and client assignment are different operations. A membership function selects the scopes that contain a row. Connect and pull assign the authenticated user’s identity scope, registered shared scopes, explicit user grants, and the results of the registered assignment function. A custom scope name does not assign itself to a client.
This page is only the mental model. Detailed operational guidance, grouping rules, and anti-patterns live in Scope modeling.
Portable seeds at a glance
Section titled “Portable seeds at a glance”Portable seeds let you bundle:
- the canonical synced-table schema
- optional server-declared portable scopes
- continuation metadata so clients can sync forward after login
They are generated by trusted tooling and do not accept JWT input.
Detailed rules live in Portable seeds.
Auth integration at a glance
Section titled “Auth integration at a glance”The reference Go host layer supports:
- trusted upstream auth
- direct JWT validation
Use trusted upstream auth when the product API already authenticates requests and resolves canonical user identities.
Detailed wiring guidance lives in Auth integration.
Specification
Section titled “Specification”The detailed architectural contract is published in: