The scenario
A plainrecord waits for fact extraction — an LLM call — before it returns. On
a request path that latency belongs somewhere else, and for a bulk import it is
unusable.
Step 1 — Queue a single write
Step 2 — Send them in batches
record_batch is always asynchronous. Each item takes the same fields a single
write does, scope keys included.
Step 3 — Poll for the outcome
Evals
- Queue one write, poll to completion, assert
memory_idsis non-empty. - Time a blocking
recordagainst a background one. The difference is why this exists. - Import a hundred items and check
memory_countagainst what you sent — extraction can produce more memories than items, and that is expected.
Guardrails
- Throughput is bounded platform-side. A large import takes real time; size your expectations from a measured batch rather than from the accept latency.
acceptedis notstored. It means the queue took them. The job is what tells you they landed.- A failed job needs handling. Poll for
failedas well ascompleted, or a silent import gap looks like a retrieval problem weeks later.
The script
Complete and runnable:background_ingestion.py.