> ## Documentation Index
> Fetch the complete documentation index at: https://docs.anonalabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Backfill a year of history

> Queue the writes, keep serving, poll for the outcome. A blocking record waits on an LLM call; this does not.

[← All use cases](/use-cases/overview)

<div className="uc-examples"><a href="https://github.com/anonalabs/Anona-Memory-SDK/blob/main/examples/background_ingestion.py">background\_ingestion.py</a></div>

## The scenario

A plain `record` 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

```python theme={null}
queued = client.record(
    space_id=space,
    content="The incident review moved to Wednesdays.",
    background=True,
)
print("queued as", queued["job_id"])
```

Sub-second return instead of waiting on extraction.

## Step 2 — Send them in batches

```python theme={null}
batch = client.record_batch(
    space_id=space,
    items=[
        {"content": "Sprint 41 closed with 34 points."},
        {"content": "Sprint 42 planning is Thursday.", "user_id": "scrum-bot"},
    ],
)
print("accepted:", batch["accepted"])
```

`record_batch` is always asynchronous. Each item takes the same fields a single
write does, scope keys included.

## Step 3 — Poll for the outcome

```python theme={null}
def wait(job_id):
    while True:
        job = client.get_job(space_id=space, job_id=job_id)
        if job["status"] in ("completed", "failed"):
            return job
        time.sleep(5)

done = wait(batch["job_id"])
print("stored", done["memory_count"], "memories")
```

## Evals

1. Queue one write, poll to completion, assert `memory_ids` is non-empty.
2. Time a blocking `record` against a background one. The difference is why this
   exists.
3. Import a hundred items and check `memory_count` against what you sent —
   extraction can produce more memories than items, and that is expected.

## Guardrails

<Warning>
  **Set `timestamp` on every backfilled item.** Without it, a year of history
  imported this afternoon all happened this afternoon, and every
  [temporal question](/use-cases/what-was-true-back-then) becomes unanswerable.
  There is no way to fix this in bulk afterwards.
</Warning>

* **Throughput is bounded platform-side.** A large import takes real time; size
  your expectations from a measured batch rather than from the accept latency.
* **`accepted` is not `stored`.** It means the queue took them. The job is what
  tells you they landed.
* **A failed job needs handling.** Poll for `failed` as well as `completed`, or a
  silent import gap looks like a retrieval problem weeks later.

## The script

Complete and runnable:
[`background_ingestion.py`](https://github.com/anonalabs/Anona-Memory-SDK/blob/main/examples/background_ingestion.py).
