Docs
BlogHomeStart building

Design for the Limits

Write code that stays fast inside the platform's limits.


Every limit — plans, database, files, built-in features, spending caps — is listed once on Limits. This page is about writing code that fits them. The agent already follows these rules; they matter when you change code yourself.

#Database

Limit (from Limits)How to design for it
One row, string or value up to 2 MBKeep files in file storage and save only their key in the row
100 bound parameters per queryInsert many rows in chunks (with 5 columns, at most 20 rows per INSERT)
1,000 queries per request, 30 s per queryRead a page in one round trip (db.batch), paginate lists, never query inside a loop
About 300 queries a second per database copyIndex the columns you filter and sort on; cache the reads of a busy public page for a few seconds
10 GB per databaseArchive or delete old rows, or move to Turso

Schema changes are Drizzle migrations: change src/db/schema.ts, run npm run db:generate, and the next npm run dev applies the migration to the development database. Publishing applies it to the live one.

#Runtime

The app runs on Cloudflare Workers, not Node: no filesystem at runtime, no long-lived connections, and a request has a short time to answer. Recurring work is a scheduled job; live updates use the SDK's real-time rooms; long work (a large import, many e-mails) is split into jobs that each finish quickly. npm run check runs the build and the Workers checks Totalum runs before deploying.

#Built-in features

The app's calls to built-in features (AI, e-mail, scraping…) count against the plan's quotas and the project's budgets (Limits). Handle 429 answers: wait for Retry-After on a per-minute limit, and show a clear message for a monthly one (errorDetails.resetsAt). Never retry in a tight loop: a burst of requests can trip the emergency stop.