--- 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. **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, as `x-lancedb-min-read-version`. A deployment checks it against the version it has cached, so successive reads on the same handle do not observe an older version even when a load balancer routes them to query nodes with differently-cached views. `checkout_latest` resets this watermark. A successful write's response reports the version it committed, so it advances the same watermark: the next read on that handle asks for at least that version. The client also sends the version a write returned in a separate header, `x-lancedb-min-version`, which deployments do not use. How a deployment honors the read watermark depends on its version and configuration, so when a read must reflect your own write, 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 Enterprise 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. 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. ## Configure Consistency Parameters {#configure-consistency-parameters} To set strong consistency, set the interval to 0: {ConsistencyStrong} {TsConsistencyStrong} {RsConsistencyStrong} {RsConsistencyMakeUsersReader} For eventual consistency, use a non-zero interval: {ConsistencyEventual} {TsConsistencyEventual} {RsConsistencyEventual} 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`: {ConsistencyCheckoutLatest} {TsConsistencyCheckoutLatest} {RsConsistencyCheckoutLatest} 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} This section is currently specific to the Python SDK. 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