# DO Storage Configuration ## SQLite-backed (Recommended) **wrangler.jsonc:** ```jsonc { "migrations": [ { "tag": "v1", "new_sqlite_classes": ["Counter", "Session", "RateLimiter"] } ] } ``` **Migration lifecycle:** Migrations run once per deployment. Existing DO instances get new storage backend on next invocation. Renaming/removing classes requires `renamed_classes` or `deleted_classes` entries. ## KV-backed (Legacy) **wrangler.jsonc:** ```jsonc { "migrations": [ { "tag": "v1", "new_classes": ["OldCounter"] } ] } ``` ## TypeScript Setup ```typescript export class MyDurableObject extends DurableObject { sql: SqlStorage; constructor(ctx: DurableObjectState, env: Env) { super(ctx, env); this.sql = ctx.storage.sql; // Initialize schema this.sql.exec(` CREATE TABLE IF NOT EXISTS users( id INTEGER PRIMARY KEY, name TEXT NOT NULL, email TEXT UNIQUE ); `); } } // Binding interface Env { MY_DO: DurableObjectNamespace; } export default { async fetch(request: Request, env: Env): Promise { const id = env.MY_DO.idFromName('singleton'); const stub = env.MY_DO.get(id); // Modern RPC: call methods directly (recommended) const result = await stub.someMethod(); return Response.json(result); // Legacy: forward request (still works) // return stub.fetch(request); } } ``` ## CPU Limits ```jsonc { "limits": { "cpu_ms": 300000 // 5 minutes (default 30s) } } ``` ## Location Control ```typescript // Jurisdiction (GDPR/FedRAMP) const euNamespace = env.MY_DO.jurisdiction("eu"); const id = euNamespace.newUniqueId(); const stub = euNamespace.get(id); // Location hint (best effort) const stub = env.MY_DO.get(id, { locationHint: "enam" }); // Hints: wnam, enam, sam, weur, eeur, apac, oc, afr, me ``` ## Initialization ```typescript export class Counter extends DurableObject { value: number; constructor(ctx: DurableObjectState, env: Env) { super(ctx, env); // Block concurrent requests during init ctx.blockConcurrencyWhile(async () => { this.value = (await ctx.storage.get("value")) || 0; }); } } ```