Overview
Concepts
Explore the illustrated introduction to Layer →
Wire protocol matching
Layer accepts the Turbopuffer HTTP wire protocol: the methods and paths a client calls, the JSON request fields it sends, and the response shapes and status codes it reads. For supported operations, an application can point its Turbopuffer client at Layer’s base URL and keep the same request body. See the API reference for authentication and client setup.
With Turbopuffer as the store, Layer forwards native requests after gateway
validation. With another store, Layer translates supported operations into
that store’s native calls. A valid but unsupported feature should return
422 UnsupportedByStore, naming the store, route, and feature, rather than
silently dropping part of the request.
Matching the wire does not promise identical index internals, latency, scores, or ranking across stores. In particular, full-text ranking is backend-specific. Layer’s additional request fields, routes, and response metadata are documented as gateway enhancements.
How we validate it
- API and client contracts. The SDK harness compares the gateway OpenAPI operations and generated Python client with the upstream API, and checks captured HTTP requests against documented examples using a mock server. These checks catch route, field, and serialization drift; they do not prove that a real backend returns the right results.
- Backend acceptance. Store-specific suites send requests through a real gateway and backend using generated clients. They check supported operations and explicit rejection of unsupported requests.
- Documented examples. A committed selection of upstream examples runs against a real gateway and store. Each request is classified as ok, unsupported, fail, or blocked by a prerequisite. A baseline change fails the check for review; matching a baseline can still preserve known failures. This is a selected test corpus, not proof that every upstream request or combination works.
The capability matrix is generated from backend declarations and checked for source drift. It states the contract; acceptance results are evidence of behavior. Both are needed to assess compatibility.
Gateway enhancements
Layer adds retrieval operations around the store while keeping one client endpoint. Hybrid text fusion combines retrieval legs, query routing selects a strategy, scans select or count matching rows, and federated queries combine named namespaces. The API reference calls out each backend’s limits at the relevant feature.
The Layer clients expose these additions;
plain HTTP can call the same API. Native requests and enhanced requests can
share the gateway endpoint. Where Layer needs bookkeeping attributes, it
reserves the _hevlayer_* prefix. Treat these fields as read-only; the
document model defines the contract.
Control loops
Layer uses a control loop as a core primitive for managing your indexes. It reconciles index state against metrics emitted by the search system, which is how Layer applies row-level transformations (UDFs) and keeps an index’s stable view current.
Related: UDFs, snapshots, stable watermark.
Kubernetes autoscaling
Because Layer is stateless, you can autoscale every tier independently. Karpenter handles node-level scaling, and KEDA scales pods against signals from an embedded PostgreSQL queue. The data in that queue is used for scaling decisions only — it carries no non-recoverable system state.
Scatter/gather
Layer can partition a single namespace into hash buckets, called shards, by assigning each row a reserved _hevlayer_shard attribute (xxh64 of its id, modulo the shard count). The gateway then scatters a query to every bucket in parallel, one _hevlayer_shard-filtered query per shard, and gathers the results: it merges and re-ranks the combined rows down to your requested top_k before returning them. Sharding stays invisible to the client — you issue one query and get one ranked result set. The same scatter/gather path backs scans (filter, full-text, and radius) and UDF discovery scans.
For an existing turbopuffer namespace adopted by Layer, initialize sharding with POST /v2/namespaces/{namespace}/init and a shard_count. The gateway writes a reserved namespace marker, stamps new writes immediately, and runs an embedded scan-and-patch backfill for rows that do not yet have _hevlayer_shard. Scatter/gather activates only after namespace metadata reports layer.shard_lag_rows: 0; until then queries and scans use the single-namespace path so unstamped rows are not missed.
Document cache
The Layer document cache does two jobs. Document reads are served pull-through: the gateway checks the cache first, and on a miss reads through to turbopuffer (or S3 for snapshots), returns the row, and backfills the cache best-effort. Pipeline chunk handoff uses the same store as the queue between CPU and GPU workers. Neither job makes it a hard dependency: document reads fall through to origin if the cache is unavailable, and chunk reads fall back to S3 backing (see Failure modes). One logical cache serves every path, with different uses (document fetch, pipeline chunks, snapshot field-values) separated into dedicated cache sets.
Glossary
| Concept | Meaning |
|---|---|
| Wire protocol | The HTTP methods, paths, request fields, response shapes, and status codes exchanged by client and server. |
| Wire feature | An individual operation or option whose backend support is declared in the capability matrix. |
| Gateway | The Layer service that receives client requests, validates them, and executes them against the configured stores. |
| VectorStore | A serving connection to the backend that stores and queries rows. |
| Warehouse | An upstream source connection, separate from the store serving retrieval requests. |
| Namespace | A named collection of rows addressed through /v2/namespaces/{namespace}. |
| Document / row | An ID and application attributes, optionally including vectors. |
| Scan | Row selection that returns matching IDs, field values, or a count; supported selectors depend on the backend. |
| Shard | A hash bucket within a namespace, identified by the reserved _hevlayer_shard attribute. |
| Scatter/gather | Running subqueries across shards or namespaces and combining their results into one response. |
| Leg | One subquery contributing to a hybrid or federated result. |
| RRF | Reciprocal rank fusion: combining ranked lists using each result’s position in its input lists. |
| Tokenizer policy | The rules that turn input text into retrieval tokens, including word boundaries, case normalization, and token limits. |
| Route | A retrieval strategy, such as hybrid_text, semantic, or fused, selected by the query router where supported. |
| Routing policy | The deterministic, versioned rules used to select an Auto route. |
| Deferral | An Auto response with executed: false: the application must supply an embedding before the selected route can execute. |
Pro runtime terms
| Concept | Meaning |
|---|---|
| Document cache | Layer-managed hot records keyed by namespace and document id, plus cache sets for pipeline chunks and snapshots. |
| Stable watermark | Epoch-ms cut tracked by the consistency watcher when turbopuffer reports up-to-date, or when a backing store without an index watermark settles its row_count across consecutive polls. |
| Ready signal | Whether a namespace is fully indexed: indexed / index_lag_rows on namespace metadata, reconciled from the latest snapshot when every row’s vector is indexed. |
| Pipeline | A PostgreSQL-backed state machine for CPU extraction and GPU embedding work. |
| Snapshot | A content-addressed S3 facet histogram written after a namespace is observed stable. |
| Facet listing | The distinct values for a field, precomputed in snapshots as fields[].values[].v or computed on demand by a values scan. |
| Facet count | The document count for a facet value, returned as fields[].values[].n in snapshots and values[].n in values scan results. |
| UDF | A stateless worker the gateway coordinates over existing rows to enrich, fan out, or re-upsert data. |
| Operator | The Kubernetes operator that reconciles Layer’s CRDs — functions, pipelines, scaling, and cluster config. |
| CRD | Custom Resource Definition: the Kubernetes-native resources the operator reconciles — functions, pipelines, scaling, and indexes. |
| PromQL | The Prometheus query language. The gateway proxies it to the embedded VictoriaMetrics so you can query metrics without a separate scraper. |