A visual tour of the sync engine
Your app talks to buoyient. buoyient talks to your server. Your app never needs to worry about connectivity.
buoyient EngineClick through to see what happens when your app creates a new object, step by step.
service.createTodo(todo)serverId + version{serverId} placeholders resolved, request sent → SyncedConnectivity is configurable — The “Is the device online?” check uses real network connectivity by default, but you have two ways to customize it: pass ProcessingConstraints on a per-request basis to force online or offline behavior, or provide a custom ConnectivityChecker implementation to override the global connectivity logic for a service.
Every SyncableObject carries a sync status that tracks where it is in its journey from local to server.
When offline, operations queue up. When connectivity returns, buoyient drains the queue in order, resolving placeholders as it goes.
Queue is empty
Request order is strictly preserved across all services in your app — not just within a single service. This matters when services have dependencies: for example, if a user creates an Order offline and then applies a Payment against that order, buoyient guarantees the order creation request reaches the server before the payment creation request, even though they belong to different services.
When you create an object offline, it doesn't have a server ID yet. buoyient lets you reference it with a placeholder that gets resolved at sync time.
PUT /todos/{serverId}
{
"title": "Buy milk",
"version": {version}
}
PUT /todos/srv-a1b2c3
{
"title": "Buy milk",
"version": 42
}
Cross-service placeholders — Need to reference another service's server ID in an offline request? buoyient supports cross-service placeholder resolution too. For example, a Payment can reference an Order's server ID before the Order has synced — the placeholder is resolved automatically during sync-up.
When the server and local store diverge, buoyient does a field-level 3-way merge. Only truly conflicting fields need your attention.
Customizable strategies — The 3-way merge logic and conflict handling come with sensible defaults out of the box, but you can fully override and customize the behavior by providing your own SyncableObjectRebaseHandler implementation.