mirror of
https://github.com/lancedb/lancedb.git
synced 2026-10-13 23:32:27 +00:00
The consistency page said reads after any write carry a freshness floor, so you read your own writes without extra configuration, and that the floor follows the last write. The pinned client records a write's version as x-lancedb-min-version, which Sophon does not read (neither at 75f4bf28 nor on main); its time floor comes from the interval and from checkout_latest() and restore(); and its version watermark follows the x-lancedb-version a response reports. Whether that watermark covers a write depends on the version the write's response reports, which the code alone does not settle. The page now describes those three mechanisms and says how to be sure a read reflects your write: an interval of zero, or checkout_latest() after writing. The guarantees page keeps its read-your-writes promise for the embedded library, on the handle that wrote.
173 lines
7.2 KiB
Plaintext
173 lines
7.2 KiB
Plaintext
---
|
|
title: Consistency
|
|
sidebarTitle: "Consistency"
|
|
description: Learn about consistency settings and versioning in LanceDB tables.
|
|
icon: "water"
|
|
availability:
|
|
oss: available
|
|
enterprise: available
|
|
summary: >-
|
|
Read freshness can be set per connection in the embedded library and on a
|
|
deployment. On a deployment, the default freshness comes from its
|
|
configuration, and the connection setting can only make reads fresher.
|
|
---
|
|
import {
|
|
PyConsistencyStrong as ConsistencyStrong,
|
|
TsConsistencyStrong as TsConsistencyStrong,
|
|
RsConsistencyStrong as RsConsistencyStrong,
|
|
PyConsistencyEventual as ConsistencyEventual,
|
|
TsConsistencyEventual as TsConsistencyEventual,
|
|
RsConsistencyEventual as RsConsistencyEventual,
|
|
PyConsistencyCheckoutLatest as ConsistencyCheckoutLatest,
|
|
TsConsistencyCheckoutLatest as TsConsistencyCheckoutLatest,
|
|
RsConsistencyCheckoutLatest as RsConsistencyCheckoutLatest,
|
|
RsUpdateMakeUsersReader as RsConsistencyMakeUsersReader,
|
|
} from '/snippets/tables.mdx';
|
|
|
|
You can set `read_consistency_interval` on the connection to control how often reads check for updates from other writers.
|
|
|
|
There are three possible settings for `read_consistency_interval`:
|
|
|
|
1. **Unset (default)**: no automatic cross-process refresh checks.
|
|
2. **Zero seconds**: check for updates on every read (strongest freshness).
|
|
3. **Non-zero interval**: check for updates after the interval elapses (eventual refresh).
|
|
|
|
The value you set depends on your application's consistency needs and performance requirements.
|
|
For example, a real-time dashboard might require strong consistency, while a batch analytics job might be
|
|
fine with eventual consistency. Stronger consistency is not free — the smaller the interval, the more
|
|
often each read pays the cost of refreshing against object storage, which raises per-read latency and cost.
|
|
|
|
This setting works for both local ([LanceTable](/management/database#uris)) and remote
|
|
tables. It only affects read operations —
|
|
write operations are always consistent.
|
|
|
|
<Callout color="blue">
|
|
**Consistency in Remote Tables**
|
|
|
|
For remote tables (`db://` connections), `read_consistency_interval` is also
|
|
respected by the client. The interval is sent to the server as a freshness bound on each read:
|
|
|
|
- **Unset (default)**: no freshness bound is sent; reads are as fresh as the deployment's own setting, described below.
|
|
- **Zero seconds**: every read asks the server for the latest committed version.
|
|
- **Non-zero interval**: reads accept data at least as fresh as `now - interval`.
|
|
|
|
In addition, `checkout_latest` and `restore` set a time floor on that table handle: later
|
|
reads ask for data at least as fresh as that moment, or as the configured interval allows,
|
|
whichever is later. Each opened table handle keeps its own floor.
|
|
|
|
Each remote table handle also tracks the highest dataset version a response from the server has
|
|
reported and sends it back with every subsequent request, so successive reads on the same handle
|
|
never observe an older version even when a load balancer routes them to query nodes with
|
|
differently-cached views. `checkout_latest` resets this watermark.
|
|
|
|
A write also records its new version on the handle, but deployments do not use that record to
|
|
choose what a read sees, so the client alone does not guarantee that the next read reflects your
|
|
own write. To be sure it does, set the interval to zero, or call `checkout_latest` after writing.
|
|
|
|
Stronger consistency is not free — the smaller the interval, the more often each read pays the cost
|
|
of refreshing against storage, which raises per-read latency and cost.
|
|
|
|
In <Badge color="red">Enterprise</Badge> deployments, the server-side default freshness is still
|
|
controlled by the cluster-level `weak_read_consistency_interval_seconds` parameter; the client setting
|
|
tightens that bound on a per-connection basis. When the parameter is unset, every read is strongly
|
|
consistent; deployments installed from the Helm chart default it to 600 seconds.
|
|
|
|
<Tip>
|
|
30-60 seconds is a reasonable starting point for
|
|
`weak_read_consistency_interval_seconds`: it cuts unnecessary object-store
|
|
checks while keeping data fresh enough for most applications. This setting
|
|
only affects reads -- writes always remain strongly consistent.
|
|
</Tip>
|
|
</Callout>
|
|
|
|
## Configure Consistency Parameters {#configure-consistency-parameters}
|
|
|
|
To set strong consistency, set the interval to 0:
|
|
|
|
<CodeGroup>
|
|
<CodeBlock filename="Python" language="Python" icon="python">
|
|
{ConsistencyStrong}
|
|
</CodeBlock>
|
|
|
|
<CodeBlock filename="TypeScript" language="TypeScript" icon="square-js">
|
|
{TsConsistencyStrong}
|
|
</CodeBlock>
|
|
|
|
<CodeBlock filename="Rust" language="Rust" icon="rust">
|
|
{RsConsistencyStrong}
|
|
</CodeBlock>
|
|
</CodeGroup>
|
|
|
|
<Expandable title="In the Rust snippets, a `make_users_reader` helper is used to build Arrow input data.">
|
|
<CodeGroup>
|
|
<CodeBlock filename="Rust" language="Rust" icon="rust">
|
|
{RsConsistencyMakeUsersReader}
|
|
</CodeBlock>
|
|
</CodeGroup>
|
|
</Expandable>
|
|
|
|
For eventual consistency, use a non-zero interval:
|
|
|
|
<CodeGroup>
|
|
<CodeBlock filename="Python" language="Python" icon="python">
|
|
{ConsistencyEventual}
|
|
</CodeBlock>
|
|
|
|
<CodeBlock filename="TypeScript" language="TypeScript" icon="square-js">
|
|
{TsConsistencyEventual}
|
|
</CodeBlock>
|
|
|
|
<CodeBlock filename="Rust" language="Rust" icon="rust">
|
|
{RsConsistencyEventual}
|
|
</CodeBlock>
|
|
</CodeGroup>
|
|
|
|
|
|
In the embedded library, with the default unset interval, tables do not auto-refresh from other writers.
|
|
To manually check for updates, use `checkout_latest` / `checkoutLatest`:
|
|
|
|
<CodeGroup>
|
|
<CodeBlock filename="Python" language="Python" icon="python">
|
|
{ConsistencyCheckoutLatest}
|
|
</CodeBlock>
|
|
|
|
<CodeBlock filename="TypeScript" language="TypeScript" icon="square-js">
|
|
{TsConsistencyCheckoutLatest}
|
|
</CodeBlock>
|
|
|
|
<CodeBlock filename="Rust" language="Rust" icon="rust">
|
|
{RsConsistencyCheckoutLatest}
|
|
</CodeBlock>
|
|
</CodeGroup>
|
|
|
|
For reproducible reads, you can also pin a table to a specific snapshot with `checkout(...)` or
|
|
a tag, restore a table to a prior version, then return to the live table with
|
|
`checkout_latest` / `checkoutLatest`. See
|
|
[Versioning](/management/table#versioning) for the full version and tag workflow.
|
|
|
|
## Handle bad vectors {#handle-bad-vectors}
|
|
|
|
<Note>
|
|
This section is currently specific to the Python SDK.
|
|
</Note>
|
|
|
|
In LanceDB Python, you can use the `on_bad_vectors` parameter to choose how
|
|
invalid vector values are handled. Invalid vectors are vectors that are not valid
|
|
because:
|
|
|
|
1. They are the wrong dimension
|
|
2. They contain NaN values
|
|
3. They are null but are on a non-nullable field
|
|
|
|
By default, LanceDB will raise an error if it encounters a bad vector. You can
|
|
also choose one of the following options:
|
|
|
|
* `drop`: Ignore rows with bad vectors
|
|
* `fill`: Replace bad values (NaNs) or missing values (too few dimensions) with
|
|
the fill value specified in the `fill_value` parameter. An input like
|
|
`[1.0, NaN, 3.0]` will be replaced with `[1.0, 0.0, 3.0]` if `fill_value=0.0`.
|
|
* `null`: Replace bad vectors with null (only works if the column is nullable).
|
|
A bad vector `[1.0, NaN, 3.0]` will be replaced with `null` if the column is
|
|
nullable. If the vector column is non-nullable, then bad vectors will cause an
|
|
error
|