You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
title: (Beta) SQLite storage backend & SQL API availabe on new Durable Object classes
10
+
description: |-
11
+
The new beta version of Durable Objects is available where each Durable Object has a private, embedded SQLite database. When deploying a new Durable Object class, users can [opt-in to a SQLite storage backend](/durable-objects/best-practices/access-durable-objects-storage/#sqlite-storage-backend) in order to access new [SQL API](/durable-objects/api/storage-api/#sqlexec) and [point-in-time-recovery API](/durable-objects/api/storage-api/#point-in-time-recovery), part of Durable Objects Storage API.
12
+
13
+
You cannot enable a SQLite storage backend on an existing, deployed Durable Object class. Automatic migration of deployed classes from their key-value storage backend to SQLite storage backend will be available in the future.
14
+
15
+
During the initial beta, Storage API billing is not enabled for Durable Object classes using SQLite storage backend. SQLite-backed Durable Objects will incur [charges for requests and duration](/durable-objects/platform/pricing/#billing-metrics). We plan to enable Storage API billing for Durable Objects using SQLite storage backend in the first half of 2025 after advance notice with the following [pricing](/durable-objects/platform/pricing/#sqlite-storage-backend).
16
+
8
17
- publish_date: "2024-06-24"
9
18
description: |-
10
19
[Exceptions](/durable-objects/best-practices/error-handling) thrown from Durable Object internal operations and tunneled to the caller may now be populated with a `.retryable: true` property if the exception was likely due to a transient failure, or populated with an `.overloaded: true` property if the exception was due to [overload](/durable-objects/observability/troubleshooting/#durable-object-is-overloaded).
Copy file name to clipboardExpand all lines: src/content/docs/durable-objects/api/alarms.mdx
+4-4Lines changed: 4 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,7 +8,7 @@ sidebar:
8
8
9
9
## Background
10
10
11
-
Durable Objects alarms allow you to schedule the Durable Object to be woken up at a time in the future. When the alarm's scheduled time comes, the `alarm()` handler method will be called. Alarms are modified using the [Transactional Storage API](/durable-objects/api/transactional-storage-api/), and alarm operations follow the same rules as other storage operations.
11
+
Durable Objects alarms allow you to schedule the Durable Object to be woken up at a time in the future. When the alarm's scheduled time comes, the `alarm()` handler method will be called. Alarms are modified using the [Storage API](/durable-objects/api/storage-api/), and alarm operations follow the same rules as other storage operations.
12
12
13
13
Notably:
14
14
@@ -28,7 +28,7 @@ Alarms are directly scheduled from within your Durable Object. Cron Triggers, on
28
28
29
29
Alarms can be used to build distributed primitives, like queues or batching of work atop Durable Objects. Alarms also provide a mechanism to guarantee that operations within a Durable Object will complete without relying on incoming requests to keep the Durable Object alive. For a complete example, refer to [Use the Alarms API](/durable-objects/examples/alarms-api/).
30
30
31
-
## Transactional Storage methods
31
+
## Storage methods
32
32
33
33
### getAlarm
34
34
@@ -110,7 +110,7 @@ export class AlarmExample {
110
110
}
111
111
asyncalarm() {
112
112
// The alarm handler will be invoked whenever an alarm fires.
113
-
// You can use this to do work, read from the Transactional Storage API, make HTTP calls
113
+
// You can use this to do work, read from the Storage API, make HTTP calls
114
114
// and set future alarms to run using this.storage.setAlarm() from within this handler.
115
115
}
116
116
}
@@ -120,4 +120,4 @@ export class AlarmExample {
120
120
121
121
* Understand how to [use the Alarms API](/durable-objects/examples/alarms-api/) in an end-to-end example.
122
122
* Read the [Durable Objects alarms announcement blog post](https://blog.cloudflare.com/durable-objects-alarms/).
123
-
* Review the [Transactional Storage API](/durable-objects/api/transactional-storage-api/) documentation for Durable Objects.
123
+
* Review the [Storage API](/durable-objects/api/storage-api/) documentation for Durable Objects.
The Transactional Storage API allows you to achieve consistent key-value storage.
9
+
import { Render } from"~/components";
10
10
11
-
Durable Objects gain access to a persistent Transactional Storage API via `state`, the first parameter passed to the Durable Object constructor.
11
+
The Storage API allows Durable Objects to access transactional and strongly consistent storage. A Durable Object's attached storage is private to its unique instance and cannot be accessed by other objects.
12
+
13
+
Durable Objects gain access to a persistent Storage API via `ctx.storage`, on the `ctx` parameter passed to the Durable Object constructor.
12
14
13
15
While access to a Durable Object instance is single-threaded, request executions can still interleave with each other when they wait on I/O, such as when waiting on the promises returned by persistent storage methods or `fetch()` requests.
14
16
15
-
The following code snippet shows you how to store and retrieve data using the Transactional Storage API.
17
+
The following code snippet shows you how to store and retrieve data using the Storage API.
16
18
17
19
```js
18
20
exportclassCounter {
@@ -39,13 +41,20 @@ export class Counter {
39
41
40
42
## Methods
41
43
42
-
The Transactional Storage API comes with several methods.
44
+
:::note[SQLite in Durable Objects Beta]
43
45
44
-
Each method is implicitly wrapped inside a transaction, such that its results are atomic and isolated from all other storage operations, even when accessing multiple key-value pairs.
46
+
The ew beta version of Durable Objects is available where each Durable Object has a private, embedded SQLite database. When deploying a new Durable Object class, users can [opt-in to a SQLite storage backend](/durable-objects/best-practices/access-durable-objects-storage/#sqlite-storage-backend) in order to access new [SQL API](/durable-objects/api/storage-api/#sqlexec). Otherwise, a Durable Object class has a key-value storage backend.
45
47
46
-
### get
48
+
:::
47
49
50
+
The Storage API comes with several methods, including key-value (KV) API, SQL API, and point-in-time-recovery (PITR) API.
48
51
52
+
- Durable Object classes with the default, key-value storage backend can use KV API.
53
+
- Durable Object classes with the [SQLite storage backend](/durable-objects/best-practices/access-durable-objects-storage/#sqlite-storage-backend) can use KV API, SQL API, and PITR API. KV API methods like `get()`, `put()`, `delete()`, or `list()` store data in a hidden SQLite table.
54
+
55
+
Each method is implicitly wrapped inside a transaction, such that its results are atomic and isolated from all other storage operations, even when accessing multiple key-value pairs.
@@ -105,7 +114,7 @@ Each method is implicitly wrapped inside a transaction, such that its results ar
105
114
106
115
* After any write, subsequent network messages may be slightly delayed. Some applications may consider it acceptable to communicate on the basis of unconfirmed writes. Some programs may prefer to allow network traffic immediately. In this case, set `allowUnconfirmed` to `true` to opt out of the default behavior.
107
116
108
-
* If you want to allow some outgoing network messages to proceed immediately but not others, you can use the allowUnconfirmed option to avoid blocking the messages that you want to proceed and then separately call the [`sync()`](/durable-objects/api/transactional-storage-api/#sync) method, which returns a promise that only resolves once all previous writes have successfully been persisted to disk.
117
+
* If you want to allow some outgoing network messages to proceed immediately but not others, you can use the allowUnconfirmed option to avoid blocking the messages that you want to proceed and then separately call the [`sync()`](/durable-objects/api/storage-api/#sync) method, which returns a promise that only resolves once all previous writes have successfully been persisted to disk.
109
118
110
119
* <code>noCache</code>boolean
111
120
@@ -188,7 +197,7 @@ The `put()` method returns a `Promise`, but most applications can discard this p
188
197
189
198
* Synchronizes any pending writes to disk.
190
199
191
-
* This is similar to normal behavior from automatic write coalescing. If there are any pending writes in the write buffer (including those submitted with [the `allowUnconfirmed` option](/durable-objects/api/transactional-storage-api/#supported-options-1)), the returned promise will resolve when they complete. If there are no pending writes, the returned promise will be already resolved.
200
+
* This is similar to normal behavior from automatic write coalescing. If there are any pending writes in the write buffer (including those submitted with [the `allowUnconfirmed` option](/durable-objects/api/storage-api/#supported-options-1)), the returned promise will resolve when they complete. If there are no pending writes, the returned promise will be already resolved.
192
201
193
202
### getAlarm
194
203
@@ -198,7 +207,7 @@ The `put()` method returns a `Promise`, but most applications can discard this p
198
207
199
208
#### Supported options
200
209
201
-
* Same options as [`get()`](/durable-objects/api/transactional-storage-api/#get), but without `noCache`.
210
+
* Same options as [`get()`](/durable-objects/api/storage-api/#get), but without `noCache`.
202
211
203
212
### setAlarm
204
213
@@ -216,9 +225,103 @@ The `put()` method returns a `Promise`, but most applications can discard this p
216
225
217
226
#### Supported options
218
227
219
-
*`setAlarm()` and `deleteAlarm()` support the same options as [`put()`](/durable-objects/api/transactional-storage-api/#put), but without `noCache`.
228
+
*`setAlarm()` and `deleteAlarm()` support the same options as [`put()`](/durable-objects/api/storage-api/#put), but without `noCache`.
229
+
230
+
### sql.exec
231
+
232
+
:::note[SQLite in Durable Objects Beta]
233
+
234
+
SQL API methods accessed with `ctx.storage.sql` are only allowed on [Durable Object classes with SQLite storage backen](/durable-objects/reference/durable-objects-migrations/#enable-sqlite-storage-backend-on-create-durable-object-class-migration) and will return an error if called on Durable Object classes with a key-value storage backend.
* The SQL query string to be executed. `query` can contain `?` placeholders for parameter bindings.
243
+
*`bindings`: any[] Optional
244
+
* Optional variable number of arguments that correspond to the `?` placeholders in `query`.
245
+
246
+
#### Returns
247
+
A cursor (`SqlStorageCursor`) to iterate over query row results as objects. `SqlStorageCursor` is a JavaScript [Iterable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_iterable_protocol), which supports iteration using `for (let row of cursor)`. `SqlStorageCursor` is also a JavaScript [Iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_iterator_protocol), which supports iteration using `cursor.next()`.
248
+
249
+
`SqlStorageCursor` supports the following methods:
250
+
251
+
*`next()`
252
+
* Returns an object representing the next value of the cursor. The returned object has `done` and `value` properties adhering to the JavaScript [Iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_iterator_protocol). `done` is set to `false` when a next value is present, and `value` is set to the next row object in the query result. `done` is set to `true` when the entire cursor is consumed, and no `value` is set.
253
+
*`toArray()`
254
+
* Iterates through remaining cursor value(s) and returns an array of returned row objects.
255
+
*`one()`
256
+
* Returns a row object if query result has exactly one row. If query result has zero rows or more than one row, `one()` throws an exception.
257
+
*`raw()`: Iterator
258
+
* Returns an Iterator over the same query results, with each row as an array of column values (with no column names) rather than an object.
259
+
* Returned Iterator supports `next()`, `toArray()`, and `one()` methods above.
260
+
* Returned cursor and `raw()` iterator iterate over the same query results and can be combined. For example:
261
+
262
+
```ts
263
+
let cursor =this.sql.exec("SELECT * FROM artist ORDER BY artistname ASC;");
264
+
let rawResult =cursor.raw().next();
265
+
266
+
if (!rawResult.done) {
267
+
console.log(rawResult.value); // prints [ 123, 'Alice' ]
* The column names of the query in the order they appear in each row array returned by the `raw` iterator.
278
+
*`rowsRead`: number
279
+
* The number of rows read so far as part of this SQL `query`. This may increase as you iterate the cursor. The final value is used for [SQL billing](/durable-objects/platform/pricing/#sqlite-storage-backend).
280
+
*`rowsWritten`: number
281
+
* The number of rows written so far as part of this SQL `query`. This may increase as you iterate the cursor. The final value is used for [SQL billing](/durable-objects/platform/pricing/#sqlite-storage-backend).
220
282
283
+
#### Examples
221
284
285
+
<Renderfile="durable-objects-sql" />
286
+
287
+
### sql.databaseSize
288
+
289
+
<code>ctx.storage.sql.databaseSize</code> : number
290
+
291
+
#### Returns
292
+
The current SQLite database size in bytes.
293
+
294
+
```ts
295
+
let size =ctx.storage.sql.databaseSize;
296
+
```
297
+
298
+
### Point in time recovery
299
+
300
+
For [Durable Objects classes with SQL storage](/durable-objects/reference/durable-objects-migrations/#enable-sqlite-storage-backend-on-new-durable-object-class-migration), the following point-in-time-recovery (PITR) API methods are available to restore a Durable Object's embedded SQLite database to any point in time in the past 30 days. These methods apply to the entire SQLite database contents, including both the object's stored SQL data and stored key-value data using the key-value `put()` API. The PITR API is not supported in local development because a durable log of data changes is not stored locally.
301
+
302
+
The PITR API represents points in times using "bookmarks". A bookmark is a mostly alphanumeric string like `0000007b-0000b26e-00001538-0c3e87bb37b3db5cc52eedb93cd3b96b`. Bookmarks are designed to be lexically comparable: a bookmark representing an earlier point in time compares less than one representing a later point, using regular string comparison.
* Returns a bookmark representing the current point in time in the object's history.
307
+
308
+
<code>ctx.storage.getBookmarkForTime(timestamp: number | Date)</code>: Promise\<string>
309
+
310
+
* Returns a bookmark representing approximately the given point in time, which must be within the last 30 days. If the timestamp is represented as a number, it is converted to a date as if using `new Date(timestamp)`.
* Configure the Durable Object so that the next time it restarts, it should restore its storage to exactly match what the storage contained at the given bookmark. After calling this, the application should typically invoke `ctx.abort()` to restart the Durable Object, thus completing the point-in-time recovery.
315
+
316
+
This method returns a special bookmark representing the point in time immediately before the recovery takes place (even though that point in time is still technically in the future). Thus, after the recovery completes, it can be undone by performing a second recovery to this bookmark.
317
+
318
+
319
+
```ts
320
+
let now =newDate();
321
+
// restore to 2 days ago
322
+
let bookmark =ctx.storage.getBookmarkForTime(now-2);
Copy file name to clipboardExpand all lines: src/content/docs/durable-objects/api/websockets.mdx
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -32,7 +32,7 @@ To learn more about WebSocket Hibernation, refer to [Build a WebSocket server wi
32
32
33
33
* Keeps a copy of `value` in memory (not on disk) to survive hibernation. The value can be any type supported by the [structured clone algorithm](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm), which is true of most types.
34
34
35
-
* If you modify `value` after calling this method, those changes will not be retained unless you call this method again. The serialized size of `value` is limited to 2,048 bytes, otherwise this method will throw an error. If you need larger values to survive hibernation, use the [Transactional Storage API](/durable-objects/api/transactional-storage-api/) and pass the corresponding key to this method so it can be retrieved later.
35
+
* If you modify `value` after calling this method, those changes will not be retained unless you call this method again. The serialized size of `value` is limited to 2,048 bytes, otherwise this method will throw an error. If you need larger values to survive hibernation, use the [Storage API](/durable-objects/api/storage-api/) and pass the corresponding key to this method so it can be retrieved later.
0 commit comments