Skip to content

Commit 4c75cc2

Browse files
acoreyjjamesgpearce
authored andcommitted
key value mode
1 parent debc76e commit 4c75cc2

File tree

3 files changed

+367
-23
lines changed

3 files changed

+367
-23
lines changed

site/guides/06_integrations/1_cloudflare_durable_objects.md

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -190,14 +190,36 @@ tag = "v1"
190190
new_sqlite_classes = ["TinyBaseDurableObject"]
191191
```
192192
193-
Then create the persister using the recommended SQL storage:
193+
Then create the persister using the recommended SQL storage. The
194+
`createDurableObjectSqlStoragePersister` supports several persistence modes:
195+
196+
**JSON Mode (Default)**: Stores the entire Store as JSON in a single database
197+
row. This is efficient for smaller stores and uses fewer database writes, but
198+
may hit Cloudflare's 2MB row limit for very large stores.
199+
200+
```js yolo
201+
// ...
202+
createPersister() {
203+
return createDurableObjectSqlStoragePersister(
204+
createMergeableStore(),
205+
this.ctx.storage.sql,
206+
);
207+
}
208+
// ...
209+
```
210+
211+
**Key-Value Mode**: Stores each table, row, cell, and value as separate database
212+
rows. Use this mode if you're concerned about hitting Cloudflare's 2MB row
213+
limit with large stores in JSON mode. This mode creates more database writes
214+
but avoids row size limitations:
194215
195216
```js yolo
196217
// ...
197218
createPersister() {
198219
return createDurableObjectSqlStoragePersister(
199220
createMergeableStore(),
200221
this.ctx.storage.sql,
222+
'key-value',
201223
);
202224
}
203225
// ...
@@ -221,6 +243,21 @@ createPersister() {
221243
// ...
222244
```
223245
246+
- **Key-value mode with custom prefix**: You can use key-value mode with a
247+
custom storage prefix:
248+
249+
```js yolo
250+
// ...
251+
createPersister() {
252+
return createDurableObjectSqlStoragePersister(
253+
createMergeableStore(),
254+
this.ctx.storage.sql,
255+
{mode: 'key-value', storagePrefix: 'my_app_'},
256+
);
257+
}
258+
// ...
259+
```
260+
224261
- **Tabular mode**: For direct table-to-table mapping instead of JSON
225262
serialization:
226263
@@ -293,16 +330,23 @@ configuration options:
293330
294331
- **SQLite storage** (recommended): Uses SQL tables to store TinyBase data with
295332
structured tables for tables and values, including proper CRDT metadata. This
296-
provides better performance and pricing. The SQLite persister supports both
297-
JSON serialization mode (default) and tabular mode for direct table mapping.
298-
It also supports both regular Store and MergeableStore objects.
333+
provides better performance and pricing. The SQLite persister supports JSON
334+
serialization mode (default), key-value mode for avoiding the 2MB row limit,
335+
and tabular mode for direct table mapping. It also supports both regular Store
336+
and MergeableStore objects.
299337
300338
- **Key-value storage** (legacy): Has limitations on the data that can be stored
301339
in each key. The DurableObjectStoragePersister uses one key per TinyBase
302340
Value, one key per Cell, one key per Row, and one key per Table. The main
303341
caution is to ensure that each individual TinyBase Cell and Value data does
304342
not exceed the 128 KiB limit.
305343
344+
**When to use Key-Value Mode**: If you have a large TinyBase Store that might
345+
approach or exceed Cloudflare's 2MB row limit when serialized as JSON, use
346+
key-value mode. JSON mode uses significantly fewer database writes and is more
347+
efficient for smaller stores, but key-value mode provides better scalability
348+
for very large datasets by storing each piece of data in separate rows.
349+
306350
The WsServerDurableObject is an overridden implementation of the DurableObject
307351
class, so you can have access to its members as well as the TinyBase-specific
308352
methods. If you are using the storage for other data, you may want to configure

src/@types/persisters/persister-durable-object-sql-storage/docs.js

Lines changed: 61 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -107,21 +107,30 @@
107107
* MergeableStore objects. When used with a MergeableStore, it can persist the
108108
* complete CRDT metadata required for proper merging operations.
109109
*
110-
* The DurableObjectSqlStoragePersister uses SQL tables to store TinyBase data,
111-
* creating structured tables for tables and values with proper CRDT metadata
112-
* including timestamps and hashes for merging operations.
110+
* A database Persister uses one of three modes: either a JSON serialization of
111+
* the whole Store stored in a single row of a table (the default), a key-value
112+
* mode that stores each piece of data separately to avoid Cloudflare's 2MB row
113+
* limit, or a tabular mapping of Table Ids to database table names and vice-versa).
113114
*
114-
* A database Persister uses one of two modes: either a JSON serialization of
115-
* the whole Store stored in a single row of a table (the default), or a tabular
116-
* mapping of Table Ids to database table names and vice-versa).
115+
* **JSON Mode (Default)**: Stores the entire Store as JSON in a single database
116+
* row. This is efficient for smaller stores but may hit Cloudflare's 2MB row
117+
* limit for very large stores. Uses fewer database writes.
118+
*
119+
* **Key-Value Mode**: Stores each table, row, cell, and value as separate database
120+
* rows. Use this mode if you're concerned about hitting Cloudflare's 2MB row
121+
* limit with large stores in JSON mode. This mode creates more database writes
122+
* but avoids row size limitations.
123+
*
124+
* **Tabular Mode**: Maps TinyBase tables directly to database tables for
125+
* traditional relational database usage.
117126
*
118127
* The third argument is a DatabasePersisterConfig object that configures which
119128
* of those modes to use, and settings for each. If the third argument is simply
120129
* a string, it is used as the `storeTableName` property of the JSON
121-
* serialization.
130+
* serialization. If it is the string 'key-value', it enables key-value mode.
122131
*
123-
* See the documentation for the DpcJson and DpcTabular types for more
124-
* information on how both of those modes can be configured.
132+
* See the documentation for the DpcJson, DpcKeyValue, and DpcTabular types for more
133+
* information on how all of those modes can be configured.
125134
*
126135
* As well as providing a reference to the Store or MergeableStore to persist, you must
127136
* provide a `sqlStorage` parameter which identifies the Durable Object SQLite storage to
@@ -130,7 +139,7 @@
130139
* @param sqlStorage The Durable Object SQL storage to persist the Store to.
131140
* @param configOrStoreTableName A DatabasePersisterConfig to configure the
132141
* persistence mode (or a string to set the `storeTableName` property of the
133-
* JSON serialization).
142+
* JSON serialization, or 'key-value' to enable key-value mode).
134143
* @param onSqlCommand An optional handler called every time the Persister
135144
* executes a SQL command or query. This is suitable for logging persistence
136145
* behavior in a development environment.
@@ -184,6 +193,48 @@
184193
* }
185194
* ```
186195
* @example
196+
* This example creates a DurableObjectSqlStoragePersister object using key-value
197+
* mode to avoid Cloudflare's 2MB row limit for large stores.
198+
*
199+
* ```js yolo
200+
* import {createMergeableStore} from 'tinybase';
201+
* import {createDurableObjectSqlStoragePersister} from 'tinybase/persisters/persister-durable-object-sql-storage';
202+
* import {WsServerDurableObject} from 'tinybase/synchronizers/synchronizer-ws-server-durable-object';
203+
*
204+
* export class MyDurableObject extends WsServerDurableObject {
205+
* createPersister() {
206+
* const store = createMergeableStore();
207+
* const persister = createDurableObjectSqlStoragePersister(
208+
* store,
209+
* this.ctx.storage.sql,
210+
* 'key-value',
211+
* );
212+
* return persister;
213+
* }
214+
* }
215+
* ```
216+
* @example
217+
* This example creates a DurableObjectSqlStoragePersister object using key-value
218+
* mode with a custom storage prefix.
219+
*
220+
* ```js yolo
221+
* import {createMergeableStore} from 'tinybase';
222+
* import {createDurableObjectSqlStoragePersister} from 'tinybase/persisters/persister-durable-object-sql-storage';
223+
* import {WsServerDurableObject} from 'tinybase/synchronizers/synchronizer-ws-server-durable-object';
224+
*
225+
* export class MyDurableObject extends WsServerDurableObject {
226+
* createPersister() {
227+
* const store = createMergeableStore();
228+
* const persister = createDurableObjectSqlStoragePersister(
229+
* store,
230+
* this.ctx.storage.sql,
231+
* {mode: 'key-value', storagePrefix: 'my_app_'},
232+
* );
233+
* return persister;
234+
* }
235+
* }
236+
* ```
237+
* @example
187238
* This example creates a DurableObjectSqlStoragePersister object with tabular
188239
* mapping configuration for direct table-to-table persistence.
189240
*

0 commit comments

Comments
 (0)