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

# Architecture

> The path inside Brussle from your write to a queryable answer: the log, the reference index, the worker, the engine, and what each step records.

This page shows the path that a write takes inside Brussle. You do not need it to build on Brussle. Read it when you want to know why an answer is `pending`, when Brussle calls the engine, and what each step records.

```mermaid theme={"theme":{"light":"css-variables","dark":"css-variables"}}
flowchart LR
  db["your database"] -- "write" --> ingest["ingest"] --> log["write-ahead log"]
  log --> ref["reference index<br/>which documents read which"]
  ref --> worker["worker<br/>settle · skip unchanged · budget"]
  worker --> engine["engine<br/>jev or gpt-6-luna"]
  engine --> answers["answers + evaluations"]
  answers -- "query" --> app["your app"]
  answers -- "webhook" --> hooks["your endpoint"]
```

## The steps

1. **Write.** Your application writes documents to a namespace. Brussle stores each write in the namespace's log before it acknowledges the write. When the write returns, the documents are durable. A write can ask Brussle to wait for the answers of the documents that it wrote, with `wait_for`.
2. **Find.** The reference index records which answers read which documents. From the log, Brussle finds each answer that read a changed document. Those answers become `pending`. Answers that did not read the document are untouched.
3. **Settle.** Brussle waits for a burst of changes to end before it judges. For a change to a related document, the wait is the judgment's fan-out `debounce_ms`, 10 minutes by default, and at most `max_wait_ms`, 1 hour by default. See [freshness policies](/guides/freshness-policies#fan-out-when-a-referenced-document-changes).
4. **Skip or judge.** If nothing that an answer reads changed, Brussle reuses the earlier answer without an engine call. Otherwise it compiles the context from the recipe, checks the namespace's budget, and calls the engine.
5. **Record.** Each engine call becomes an [evaluation](/concepts/evaluations): the exact text that the engine read, the related documents and their revisions, the engine's output, and the question and engine versions. The answer becomes `fresh`.
6. **Serve.** Your application queries the answers, filters on them, and gets an event when a document enters or leaves a [subscription](/concepts/subscriptions).

## What each step means for you

* An answer is `pending` between steps 2 and 5. A read with `wait_ms` waits for it. A query with `answers: "fresh_only"` leaves it out. See [freshness](/concepts/freshness).
* Step 3 is why a read right after a change to a related document can still show `pending`. Set a shorter `debounce_ms` when you need the new answer sooner.
* Step 4 is why a write that changes nothing the recipe reads costs nothing.
* Step 5 is why you can explain any answer later: open its evaluation. See [what you can rely on](/behavior#the-exact-inputs-each-answer-read).

For the measured latency of each step, see [tradeoffs](/tradeoffs). For the limits, see [limits](/limits).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.