Architecture
Overview
Quail is structured like a traditional query engine: it parses a query into a logical plan, optimizes it, lowers it to a physical plan, and executes the physical plan. Execution is pull-based (Volcano-style), with documents pipelining through operators in large batches sized to saturate the GPU. The two performance goals are to keep the GPU busy (minimize idle time between forward passes) and to minimize KV regret (document state that was evicted from GPU memory and needs to be recomputed).
Query lifecycle
- Quail parses the user's SQL (or Python builder query) into a logical plan.
- The session reads Arrow batches from each registered table and tokenizes the document columns.
- The planner proposes one or more physical plans with cost estimates. The cheapest one is selected.
- The runner executes the physical graph. Model nodes run on the GPU. Relational nodes run with Arrow on the CPU.
- The query returns the matching rows as a
pyarrow.Tableand an execution report with timing and token counts.
Packages
Each package imports only from the ones below it.
| Package | What it does | Source |
|---|---|---|
quail.frontend | SQL compiler and Python builder. | frontend/ |
quail.logical | Logical plan nodes and prompt binding. | logical/ |
quail.physical | Physical plan nodes. | physical/ |
quail.planner | Logical rules, filter and join ordering, KV retention. | planner/ |
quail.cost | Cost model over the model and device specs. | cost/ |
quail.execution | Session, runner, token store, results. | execution/ |
quail.backends | Quail's GPU code (backends/quail/executor/) and the vLLM and SGLang baselines. | backends/ |
quail.specs | Model and device constants. | specs/ |