Proposal: Dynamic request batching interface for cells
- Dominant language
- Rust
- Stars
- 4.6k
- Forks
- 171
- PR merge metrics
- No merged PRs in 30d
Description
Current Durable Objects use a single `fetch(request)` handler.
Every incoming request runs in its own turn, executes separate SQLite transactions, and waits for its own durability proof before responding.
For write-heavy workloads like event ingestion, counters, and pipeline stages, handling requests one-by-one creates a bottleneck around database transactions and replication syncs. celld can innovate beyond the basic Durable Object model by supporting an optional dynamic batching handler, such as `batchFetch(requests)`.
#### Why dynamic batching
1. **Higher throughput under load.** When requests queue up for an active cell, celld can pass an array of pending requests to the cell in a single turn. The cell processes the batch, writes to SQLite once, and returns an array of responses.
2. **Lower I/O and replication overhead.** Instead of running 100 separate SQLite transactions and 100 replication syncs, a batch of 100 requests runs in one atomic transaction and proves durability once.
3. **Flexible latency and throughput trade-offs.** Callers keep using standard single `fetch(req)`. Celld aggregates requests dynamically only when concurrency exists, preserving low latency when idle while maximizing throughput under load.
4. **Better fit for pipelines.** Developers using cells as stream aggregators or write-ahead buffers get native support for bulk operations without writing custom queueing mechanisms in userland.
If a cell does not define a batch handler, it continues using standard `fetch()` with zero changes.
edit: I've pushed a POC of this here: https://github.com/denoland/celld/commit/4f3faa47425c063d79d9815f73e73118f54b4d34
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reviewing the existing fetch(request) handler path and the linked POC commit 4f3faa47425c063d79d9815f73e73118f54b4d34. Compare how queued requests, SQLite transactions, responses, and durability proofs are handled; done means an optional batchFetch(requests) path works while cells without it retain standard fetch() behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust, sqlite
- Domain
- backend, databases, distributed-systems
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100