Limits
Know the boundaries
Section titled “Know the boundaries”| Area | Current boundary |
|---|---|
| Workspace throughput | Each workspace has one writer: its Durable Object. |
| Retry deduplication | Receipts have no expiry. The operation hash is removed after half the history retention, 15 days by default; afterwards, reusing the id acknowledges the original write regardless of its body. Legacy upgrades and restores preserve a fixed boundary for missing receipts. |
| Reads | No fixed row cap; wide reads stream in keyset chunks of 1,000 rows. |
| Bulk writes | Any number of rows in one transaction; applied optimistically and queued offline like any write. |
| Relations | Relation filters and nested creates nest without limit, typed at every depth, and filters can be any length. |
| Live windows | No fixed row cap; every loaded page stays live and streams in keyset chunks of 1,000 rows. |
| File access | Per file: role(), fileCheck() or attachedTo() a row, decided by the workspace before bytes move. See File access. |
| File uploads | Any size: past 16 MiB, files go up as R2 multipart uploads (objects up to 5 TB). File bytes live in a separate R2 bucket. |
| Presence and broadcast | Ephemeral, over the workspace socket; socket messages of any size (large ones travel in parts), and a socket holds any number of live queries. Broadcast messages are not stored or replayed. |
| History retention | Deleted and overwritten values leave every TapeDB copy within the retention (30 days by default). Cloudflare keeps 30 days of Durable Object point-in-time recovery regardless; see Privacy & data. |
| Claim route | Rate-limited by default: 300 requests per IP and 30 per subject, refilling over 60 seconds; exact and global. Configurable with identity.limits. |
The API is frozen; see API stability for what may still change.