Yeah that's understandable, but I would've thought there's a way to do it locally, since the runtime
Yeah that's understandable, but I would've thought there's a way to do it locally, since the runtime is now open source and all that.
create cloudflare template with modified code, SQLite backend:Config1 to Config5 are all useless tables, and keeping rest of the code the same.Configs, and the hidden KV API table) and second request costs 8 reads, in the second reproduction there were 7 tables (Configs, Config1 to Config5, and hidden KV API table) and the second request costs 28 reads.<mobile-phone>-<OTP> and value being the timestamp or whatever info you want. When the request comes in you can check the specific OTP if it exists or not indicating validity, and search by prefix the phone number.npm create cloudflare@latest hello world template with DO, change to SQLite backend, with the following code: https://gist.github.com/NonSpicyBurrito/f4938faa7a779574d9af945d012f6703. Deploy, send two requests far enough apart so they can show up separately on dashboard, and observe DO metrics:rowsRead/rowsWritten it's what I would expect. I will share it with the DO team to see if they find anything.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. 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 below pricing.
wss:// used to work just fine. We only used 1 Durable Object Rpc to do a 50s form filing process using the remote browser. This worked great.puppeteer.connect:Requests that hit the Durable Objects in-memory cache or that use the multi-key versions of get()/put()/delete() methods are billed the same as if they were a normal, individual request for each key.https://developers.cloudflare.com/durable-objects/platform/pricing/#key-value-storage-backend
create cloudflareConfig1Config1Config5Config5ConfigsConfigs<mobile-phone>-<OTP>rowsRead/rowsWrittenimport { DurableObject } from 'cloudflare:workers';
export class MyDurableObject extends DurableObject<Env> {
constructor(ctx: DurableObjectState, env: Env) {
super(ctx, env);
ctx.blockConcurrencyWhile(async () => {
await ctx.storage.transaction(async () => {
const version = await ctx.storage.get('migrationVersion');
if (version === 1) return;
ctx.storage.sql.exec(`
CREATE TABLE Configs (
key TEXT NOT NULL,
value TEXT NOT NULL,
PRIMARY KEY (key)
)
STRICT;
`);
ctx.storage.sql.exec(`INSERT INTO Configs (key, value) VALUES (?, ?);`, 'foo', 'bar');
await ctx.storage.put('migrationVersion', 1);
});
});
}
async sayHello(key: string): Promise<string> {
const { value } = this.ctx.storage.sql.exec(`SELECT value FROM Configs WHERE key = ?;`, key).one();
return `Hello, ${value}!`;
}
}
export default {
async fetch(request, env, ctx): Promise<Response> {
const url = new URL(request.url);
if (url.pathname !== '/hello-world') return new Response(null, { status: 404 });
let id: DurableObjectId = env.MY_DURABLE_OBJECT.idFromName('hello-world');
let stub = env.MY_DURABLE_OBJECT.get(id);
let greeting = await stub.sayHello('foo');
return new Response(greeting);
},
} satisfies ExportedHandler<Env>;CREATE TABLE Configs (
key TEXT NOT NULL,
value TEXT NOT NULL,
PRIMARY KEY (key)
)
STRICT;
CREATE TABLE Config1 (
key TEXT NOT NULL,
value TEXT NOT NULL,
PRIMARY KEY (key)
)
STRICT;
CREATE TABLE Config2 (
key TEXT NOT NULL,
value TEXT NOT NULL,
PRIMARY KEY (key)
)
STRICT;
-- Config3, Config4, Config5