PlanetScale + Liveblocks
PlanetScale provides a serverless MySQL database with horizontal scaling and branching. Using webhooks, you can set up one-way synchronization of your Liveblocks data to PlanetScale for reporting, search, audit logs, or app workflows.
How data sync works
Liveblocks webhooks trigger when certain events happen, such as when a collaborative document updates. Liveblocks can trigger an endpoint in your back end, and from here, you can fetch the latest data and write it to PlanetScale. Here’s an example of how it works with Liveblocks Storage.
Which data can be synced?
Various types of Liveblocks data can be synched to PlanetScale with webhooks.
| Name | Description | Relevant webhook | Relevant API |
|---|---|---|---|
| Rooms | Created rooms and metadata. | roomUpdated | getRoom |
| Active users | Currently connected users. | userEntered | getActiveUsers |
| Liveblocks Storage | Custom realtime document state. | storageUpdated | getStorageDocument |
| React Flow | Flowchart state. | storageUpdated | mutateFlow |
| Yjs | Y.Doc document state. | ydocUpdated | getYjsDocument |
| Tiptap/BlockNote/Lexical | Text editor state. | ydocUpdated | getYjsDocument |
| Threads | Comments, reactions, more. | threadCreated | getThread |
This is not an exhaustive list—around 15 related webhook events are available, along with many Node.js methods, Python functions, and REST API endpoints.
Setup
Quickstart for synching Liveblocks data to PlanetScale. In this example, we sync Liveblocks Storage data to PlanetScale, but you can use the same pattern with other APIs and webhooks to sync other types of data.
We have a full step-by-step guide available here, this page provides a quick summary.
Create the PlanetScale table
Use one row for each Liveblocks room.
Create a webhook endpoint
Add a back end endpoint in your app, for example at
/api/liveblocks-webhook.Subscribe to Storage updates
In the Liveblocks dashboard, navigate to the “Webhooks’ page inside a project,
and create a webhook endpoint for your endpoint URL—this requires you to host your local project. Subscribe tostorageUpdated, then copy the webhook secret.Verify the webhook event
In your endpoint, using
WebhookHandler, verify the webhook event with the webhook secret from the dashboard.Sync Storage to PlanetScale
Set up your Liveblocks and PlanetScale clients, before fetching the Storage document data with
getStorageDocumentand upserting the PlanetScale row withon duplicate key update.Data sync is set up!
Your Liveblocks data is now automatically synched to PlanetScale when the webhook event is fired.
Limits and troubleshooting
Storage or Yjs data is stale
storageUpdated and
ydocUpdated webhooks are throttled
because collaborative documents can be modified up to 60 times per second. Treat
PlanetScale as an eventually consistent mirror, not as the live editing channel.
Webhook verification fails
Check that LIVEBLOCKS_WEBHOOK_SECRET is the webhook secret for the webhook
endpoint that sent the event. Also make sure your endpoint passes the same raw
body string to
verifyRequest that it
received from Liveblocks.
PlanetScale writes fail
Keep DATABASE_URL on the server only. Use a database password with permission
to write the mirror tables. PlanetScale doesn’t support foreign keys by
default—if you need referential integrity, model it in application code.
Duplicate writes happen
Webhook deliveries can be retried. Use on duplicate key update upserts with a
stable primary key such as room_id, thread_id, or comment_id so repeated
deliveries update the same row.
Liveblocks REST requests fail
Check that LIVEBLOCKS_SECRET_KEY is a secret key from the same Liveblocks
project as the room. If the request still fails, return a non-2xx response so
the webhook can be retried.