SDK Runtime Internals
What the RetainDB SDK does under the hood — caching, retries, and the write queue.
You don't need this page to use RetainDB. You need it when a question changes from "how do I call RetainDB?" to "why did the SDK behave this way?"
What happens on every call
The SDK is not a thin HTTP wrapper. It layers in:
- Automatic retries on transient failures (408, 429, 5xx)
- Request deduplication — identical in-flight reads are coalesced, not duplicated
- Search caching — repeated identical queries return cached results within a short TTL
- Write queue —
remember()and similar writes are batched and sent in bulk
All of this is on by default. You get production-grade behavior without configuration.
The write queue
Writes go into an in-memory queue and are flushed to the API in batches. In RetainDB, this drains automatically on beforeExit — no manual shutdown needed for long-running servers.
For short-lived scripts, flush before exiting:
await db.queue.flush();Search caching
Identical searches hit a local cache with a 30-second TTL. This is why a getContext call after a remember on the same query may return slightly stale results.
getContext always sets include_pending: true internally, which overlays writes that are still processing — so freshness is not a real problem in practice.
Deduplication
If the same search fires twice in the same tick (e.g. in a React render loop or a parallel fan-out), the SDK issues one request and returns the same result to both callers.
Retry behavior
| Status | Retried? |
|---|---|
| 408, 429 | Yes |
| 500, 502, 503, 504 | Yes |
| 400, 401, 403, 404 | No |
Backoff is exponential with jitter, capped at ~1.2 seconds between attempts.
When to care about this
- Short-lived jobs: call
db.queue.flush()before exit - Raw HTTP comparison: SDK results may differ from raw requests due to caching
- Migration debugging: if old code hit the API directly, new code may look different in your logs
Debugging order
- Confirm auth and
userIdare correct - Confirm the write happened (check
db.diagnostics.getLast(5)) - Confirm the read uses the right scope
- Only then look at caching or retry effects
Next step
Was this page helpful?
Your feedback helps us prioritize docs improvements weekly.