Availability: Custom Write Checkpoints are available for customers on our Team and
Enterprise plans.
The alpha Checkpoint Requests API uses the term “custom checkpoint
requests” for asynchronous upload backends. Client support is currently available for Swift. This page retains the
previous “Custom Write Checkpoints” name for the source-side configuration.
uploadData call completes.
Problems occur if the persistence in the source database happens asynchronously. If the client’s upload is meant to mutate the source database (and eventually does), but this is delayed, it will effectively seem as if the client’s uploaded changes were reverted on the server, and then applied again thereafter.
Chained data pipelines are a common example of asynchronous uploads — e.g. data uploads are first written to a different upstream database, or a separate queue for processing, and then finally replicated to the ‘source database’ (to which PowerSync is connected).
For example, consider the following data pipeline:
- The client makes a change locally and the local database is updated.
- The client uploads this change to the server.
- The server resolves the request and writes the change into an intermediate database (not the source database yet).
- The client thinks the upload is complete (i.e. persisted into the source database). It requests a Write Checkpoint from the PowerSync Service.
- The PowerSync Service increments the replication
HEADin the source database, and creates a Write Checkpoint for the client. The Write Checkpoint number is returned and recorded in the client. - The PowerSync Service replicates past the previous replication
HEAD(but the changes are still not present in the source database). - It should be fine for the client to apply the state of the server to the local database. But the server state does not include the client’s uploaded changes mentioned in #2. This is the same as if the client’s uploaded changes were rejected (not applied) by the server. This results in the client reverting the changes in its local database.
- Eventually the change is written to the source database, and increments the replication
HEAD. - The PowerSync Service replicates this change and sends it to the client. The client then reapplies the changes to its local database.
Custom Write Checkpoints
Custom Write Checkpoints allow the developer to define Write Checkpoints and insert them into the replication stream directly, instead of relying on the PowerSync Service to create and return them. An example of this is having the backend persist Write Checkpoints to a dedicated table which is processed as part of the replication stream. The PowerSync Service then needs to process the (ordered) replication events and correlate the checkpoint table changes to Write Checkpoint events.Example Implementation
A self-hosted Node.js demo with Postgres is available here:Custom Write Checkpoints (Node.js + Postgres)
Implementation Details
This outlines what a Custom Write Checkpoints implementation entails.Custom Write Checkpoint Table
Create a dedicatedcheckpoints table, which should contain the following checkpoint payload information in some form:
Replication Requirements
Replication events for the Custom Write Checkpoint table (checkpoints in this example) need to enabled.
For Postgres, this involves adding the table to the PowerSync logical replication publication, for example:
Sync Rules Requirements
With storage version 4, each sync configuration can use only one event definition to produce custom checkpoints. Choose the event based on the clients that the configuration supports:- Use
checkpoint_requeststo support the Checkpoint Requests API. These records are temporary and can expire. - Use
write_checkpointsonly if every client uses the legacy Custom Write Checkpoints flow. These records are retained because legacy clients do not retry expired checkpoints automatically.
checkpoint_requests, the is_legacy field is optional. When it is omitted, PowerSync treats the payload as a checkpoint request that can expire. If the configuration supports only Checkpoint Requests, omit it:
write_checkpoints without an is_legacy field:
Rolling Out Checkpoint Requests
During a rolling rollout, older app versions may continue to create legacy checkpoints while newer versions create checkpoint requests. Configure only thecheckpoint_requests event and mark the legacy payloads so the PowerSync Service can apply the correct retention behavior:
- Set
is_legacytotruefor legacy checkpoint records. These records cannot expire because older clients do not retry them automatically. - Omit
is_legacyfrom checkpoint request records. The PowerSync Service can expire and delete these temporary records.
Application
Your application should handle Custom Write Checkpoints on both the frontend and backend.Frontend
Your client backend connector should make a call to the application backend to create a Custom Write Checkpoint record after uploading items in theuploadData method. The Write Checkpoint number should be supplied to the CRUD transactions’ complete method.
Backend
The backend should create a Write Checkpoint record when the client requests it. The record should automatically increment the Write Checkpoint number for the associateduser_id and client_id.
Postgres Example
With the following table defined in the database…checkpoints records: