Skip to main content

Spice v2.2.0 (Aug 25, 2026)

ยท 104 min read
Viktor Yershov
Senior Software Engineer at Spice AI

Spice v2.2.0 is now available! ๐Ÿš€

Spice v2.2.0 focuses on real-time data, performance, and stability. Cloud Connect links self-hosted runtimes to Spice.ai Cloud for management and observability. MySQL datasets and PostgreSQL catalogs can now stream source changes into accelerated datasets. Debezium sources can send CDC events directly without Kafka. Warm in-memory indexes improve vector and full-text search performance.

Highlights in v2.2.0 include:

  • Cloud Connect โ€” link self-hosted runtimes for BYOC (Bring Your Own Cloud) to Spice.ai Cloud for management and observability
  • MySQL CDC โ€” MySQL tables now stay in sync in real time using MySQL binlog replication, with no Kafka or Debezium infrastructure and no scheduled refreshes
  • PostgreSQL Catalog CDC โ€” accelerate an entire PostgreSQL database in real time with a few lines of configuration and no per-table setup
  • Faster Search โ€” vector and full-text search can now serve from an in-memory index by default, with no configuration change

What's New in v2.2.0โ€‹

Cloud Connectโ€‹

Spice Cloud Connect is a feature of Spice.ai Cloud.

Spice Cloud Connect links self-hosted runtimes for BYOC (Bring Your Own Cloud) to Spice.ai Cloud for management and observability. Run spice cloud link to enroll a standalone runtime.

Try it with the Cloud Connect on a Development Machine recipe.

MySQL Change Data Captureโ€‹

The MySQL Data Connector now supports refresh_mode: changes. The runtime loads an initial snapshot of the table. It then applies inserts, updates, and deletes from the MySQL binlog as they commit. The acceleration stays current without scheduled refreshes.

datasets:
- from: mysql:orders
name: orders
params:
mysql_host: localhost
mysql_db: mydb
mysql_user: replicator
mysql_pass: ${secrets:mysql_pass}
acceleration:
engine: cayenne
refresh_mode: changes
  • Failover-safe GTID positions: When the source server has GTID enabled, the runtime tracks the replication position as a GTID set. A GTID position stays valid across a replica promotion, so replication survives a failover to a new primary without a rebuild.

PostgreSQL Catalog CDCโ€‹

The PostgreSQL Catalog Connector is now Beta with new Catalog CDC acceleration support at Alpha.

A PostgreSQL catalog can now use refresh_mode: changes. One configuration replicates every table that the include patterns match. Queries then read fresh PostgreSQL data with no per-table setup.

catalogs:
- from: pg
name: pg
include:
- 'public.*'
params:
pg_host: localhost
pg_db: mydb
pg_user: postgres
pg_pass: ${secrets:pg_pass}
acceleration:
refresh_mode: changes

Known limitations while catalog CDC acceleration is Alpha: configuration may change; a table dropped and recreated in the source can serve rows captured before it was recreated (#12110); and a durable catalog acceleration can come back empty after a restart (#12729). Feedback is welcome in #11850.

Debezium CDC Without Kafkaโ€‹

Any Debezium source plugin can now stream change events directly into Spice, with no Kafka bus in between. A dataset with from: cdc:โ€ฆ accepts change events at POST /v1/datasets/{name}/cdc, in JSON or Avro. The existing Kafka path (from: debezium:โ€ฆ) is unchanged.

Faster Search with Warm In-Memory Indexesโ€‹

Search adds a warm in-memory tier for vector and full-text indexes. The runtime writes each change to the warm tier and to the durable store together. Queries read the warm tier first and fall back to the durable store. The warm tier covers vector indexes, full-text indexes, .vectors datasets, views, and chunked Elasticsearch vector columns.

More search improvements:

  • cosine_distance uses SIMD instructions through the simsimd library.
  • Full-text search applies stemming by default.
  • Full-text search pushes SQL filters down into the tantivy index.
  • A delete now removes the document from full-text and vector indexes. BM25 statistics no longer count superseded documents.
  • The runtime loads local rerankers from text-embeddings-inference models.
  • The runtime validates vector search parameters before it runs the SQL query.

Operations & Observabilityโ€‹

  • Query timeout: The new runtime.query.timeout setting bounds the duration of every query. An expired query fails with HTTP 504 or gRPC DEADLINE_EXCEEDED.
runtime:
query:
timeout: 30s
  • CPU sizing for Kubernetes pods without a CPU limit: A Spice runtime pod with a CPU request and no CPU limit now sizes itself to twice the request instead of every core on the node. Set SPICE_CPU_CORES=all (or runtime.cpu.cores: all) to burst to all cores, for example when a 0.5-core request runs on a 24-core node.
  • Trace IDs in logs: Every log record from a query carries the query's trace ID. Filter the logs by one ID to see everything that query did.
  • Improved dashboards: The Grafana and Datadog dashboards add new and improved panels, and support multi-replica and Kubernetes deployments.
  • Helm: The Helm chart supports a custom Deployment strategy and StatefulSet updateStrategy.
  • Dataset status: A non-accelerated dataset now shows the Error state when its source is unavailable, instead of appearing healthy while queries fail.

Other Notable Improvements and Bug Fixesโ€‹

  • Drasi (Alpha): The runtime forwards CDC changes and runtime tables to a Drasi source.
  • Microsoft SQL Server: Kerberos integrated authentication now works on Unix.
  • HTTP connector: OAuth2 client-credentials authentication.
  • Oracle DATE: Values lost their time of day. They now map to a timestamp.
  • Catalog exclude patterns: The Glue and Cayenne catalogs ignored exclude patterns. Both pattern lists now apply.
  • Spice Cayenne schema changes: Partitioned accelerations could report a source schema change as applied while partitions kept the old schema. This mismatch caused lossy casts or append failures. Cayenne now rejects in-place evolution for partitioned accelerations. The configured schema-change policy then handles the change.
  • Snowflake NUMBER values: The connector could remove fractional digits during schema discovery. It treated numeric metadata as absent and defaulted the scale to zero. It now preserves the source precision and scale.

See the Changelog for the full list of fixes.

SDK Updatesโ€‹

Updated SDKs release alongside v2.2.0:

  • spice.js v3.2.0 โ€” adds query cancellation (listActiveQueries/cancelActiveQuery), mTLS client certificates, HTTP fallback when Flight is unavailable, and typed parameter binding via Flight SQL prepared statements. Also fixes nsql() and search() response handling and named parameters over HTTP.
  • spicepy v4.0.0 โ€” adds streaming of large results, natural-language queries (nsql), vector and hybrid search, and query cancellation. Spice.ai Cloud users need this update: the legacy hostnames are retired in favor of region-specific endpoints.
  • spice-rs v3.2.0 โ€” adds search, NSQL, async queries, query cancellation, and mTLS.

Dependency Updatesโ€‹

Dependency / ComponentVersion
DataFusionv54.1
iceberg-rustv0.10.0
Tursov0.7.2
Rust toolchainv1.96.1

New Contributorsโ€‹

Contributorsโ€‹

Breaking Changesโ€‹

  • CPU sizing for Kubernetes pods without a CPU limit: A Spice runtime pod with a CPU request and no CPU limit now sizes itself to twice the request instead of every core on the node. Set SPICE_CPU_CORES=all (or runtime.cpu.cores: all) to keep the previous behavior, or set runtime.cpu.cores to a specific core count.
  • Partitioned DuckDB accelerations are removed: The DuckDB accelerator now rejects partition_by. Use the Cayenne or Arrow accelerator for partitioned datasets.
  • Adaptive Cayenne tuning requires an explicit opt-in: An unset cayenne_tuning now resolves to auto. Set cayenne_tuning: adaptive to enable the closed-loop controller.
  • ONNX ML inference is removed: The runtime no longer loads ONNX models, and it no longer serves the /v1/predict endpoints. Use an LLM model provider instead.
  • One process-wide Vortex segment cache: Cayenne tables now share one segment cache instead of one cache per table. Set cayenne_segment_cache_mb under runtime.params to size it. When unset, the cache takes 1/64 of the memory entitlement, clamped to 256 MiB - 2 GiB.
  • The Pingora cache engine is now a Spice.ai Enterprise feature: An OSS build with engine: pingora degrades to the Moka engine and logs the substitution.
  • Deprecated settings: pg_replication_temporary_slot is deprecated. cayenne_segment_cache_mb at the table level is deprecated โ€” set it under runtime.params instead. This release renames the MongoDB num_docs_to_infer_schema setting to schema_infer_max_records. The old name still works and warns.

Cookbook Updatesโ€‹

The Spice Cookbook includes more than 104 recipes to help you get started with Spice quickly and easily.

Upgradingโ€‹

To upgrade to v2.2.0, use one of the following methods:

CLI:

spice upgrade

Homebrew:

brew upgrade spiceai/spiceai/spice

Docker:

Pull the spiceai/spiceai:2.2.0 image:

docker pull spiceai/spiceai:2.2.0

For available tags, see DockerHub.

Helm:

helm repo update
helm upgrade spiceai spiceai/spiceai --version 2.2.0

AWS Marketplace:

Spice is available in the AWS Marketplace.

What's Changedโ€‹

Changelogโ€‹

  • feat(testoperator): --prepare-only / --skip-prepare for htap source reuse by @bjchambers in #11486
  • test(cluster): de-flake scheduler_failover (drop unreliable scheduler_node assertion) by @phillipleblanc in #11518
  • feat(cayenne): wire orphaned-DV cleanup knob to spicepod params + doc sync by @bjchambers in #11523
  • fix(cayenne): warn (not panic) on benign manifest/listing race; re-enable now-passing ignored tests by @lukekim in #11511
  • fix(datafusion): accurate projected scan byte size so hash joins build the smaller side by @sgrebnov in #11503
  • fix(cayenne): seed persisted num_rows for hash-join sizing by @sgrebnov in #11515
  • fix(cayenne): user-visible DELETE WHERE pk IN (...) reports the real row count by @lukekim in #11514
  • test(cayenne): CDC convergence/resurrection fuzz harness by @bjchambers in #11502
  • fix(cayenne): correctness & memory_limit fixes from perf audit (2 P0, 3 P1) by @lukekim in #11516
  • perf(cayenne): compaction IO-hygiene follow-ups โ€” input-page evict + O_DIRECT writer + bench by @lukekim in #11498
  • Update end_game.md by @bjchambers in #11535
  • chore: Vendor ttf-parser, lopdf, pdf-extract by @peasee in #11521
  • fix: Update tpch benchmark snapshots for federated/mysql[catalog].yaml by @app/github-actions in #11531
  • Fix s3 vectors API by @krinart in #11536
  • Update from spiceai/datafusion#177 by @Jeadie in #11541
  • perf(cayenne): off-write_lock N>1 mem-tier checkpoint + adaptive query-admission throttle by @lukekim in #11538
  • fix(flightsql): propagate bearer token to per-endpoint clients by @boittega in #11509
  • fix: Placeholder table initialization lock swap by @peasee in #11540
  • chore(cluster): bump ballista pin for the null-aware anti-join fix by @phillipleblanc in #11544
  • fix(runtime-tools): fix memory table identifier validation rejecting valid names by @Jeadie in #11546
  • test(chbench): enable 4-way mem-tier PK sharding on SF1000 memory-durability configurations by @sgrebnov in #11553
  • fix(reorder): reorder inner-join islands inside EXISTS / NOT EXISTS by @sgrebnov in #11552
  • feat(cayenne): enable orphaned-DV cleanup by default (per-table threshold 20) by @bjchambers in #11533
  • fix(postgres): delete old key on CDC primary-key updates by @phillipleblanc in #11551
  • Properly exclude vendored crates from make lint-rust-fix by @krinart in #11560
  • fix: arrow IndexedMemTable serves stale results after DML/retention/sync (fixes #11262) by @claudespice in #11532
  • perf(cayenne): concurrent per-shard mem-tier checkpoint encode (drain parallelism) by @lukekim in #11558
  • fix(physical-plan): estimate col=literal selectivity from NDV, not the flat 20% default (Datafusion) by @sgrebnov in #11562
  • fix: Read Postgres DB source error when available by @peasee in #11566
  • feat(cayenne): cold object-store tier with read-optimized clustering by @lukekim in #11543
  • Generic CDC replication-lag metric by @krinart in #11554
  • fix: ignore transitive quick-xml advisories (RUSTSEC-2026-0194/0195) in cargo-deny by @krinart in #11571
  • test(chbench): add cold-object-store-tier SF-1000 HTAP run; cap SF-1000 mem-tier at 1 GiB by @lukekim in #11573
  • fix: surface silent Turso read-path conversion failures (fixes #11276) by @claudespice in #11570
  • feat(testoperator): emit P99 + Max replication lag and staleness telemetry for HTAP by @sgrebnov in #11572
  • feat(runtime): cost-based eager aggregation, enabled by default (datafusion spiceai-54) by @bjchambers in #11446
  • Bump datafusion to include spiceai/datafusion#181 by @Jeadie in #11563
  • fix(cayenne): drain in-flight maintenance before in-process reopen (mutation_property flake) by @bjchambers in #11578
  • Unified JSON nesting by @krinart in #11555
  • feat(testoperator): capture under-load EXPLAIN plans as HTAP artifacts by @sgrebnov in #11576
  • feat(cayenne): freshness-SLO-driven adaptive mem-tier shrink (+ freshness diagnostics) by @lukekim in #11574
  • fix(cayenne): fold un-checkpointed mem-tier keys into the cold keyset rebuild by @lukekim in #11592
  • perf(cayenne): reuse the PK RowConverter across the sharded CDC apply by @lukekim in #11590
  • Add labels to spiceai-dev by @krinart in #11591
  • Rename mongo num_docs_to_infer_schema (deprecated) -> schema_infer_max_records by @krinart in #11593
  • fix(postgres): don't ACK replication slot past uncommitted envelopes on empty transactions by @bjchambers in #11582
  • refactor(connectors): extract abfs, adbc, cosmosdb, ducklake, gcs, git, github, glue, kafka, snowflake-native, spiceai into data-connectors crates by @Jeadie in #11407
  • Revert "Generic CDC replication-lag metric" by @lukekim in #11600
  • refactor(cayenne): remove orphaned-DV cleanup spicepod param, make it always-on by @bjchambers in #11575
  • fix(mongodb): substitute delete when UpdateLookup finds no document by @bjchambers in #11583
  • ci(chbench): SF1000 tuned+adaptive every 3h, other configs once daily by @lukekim in #11601
  • feat(cayenne): add integer support to maintained AVG by @bjchambers in #11564
  • Refresh spidapter Spice Cloud token from client credentials by @krinart in #11594
  • fix: cluster filtered COUNT(*) on append-only tables returns unfiltered total (fixes #11599) by @claudespice in #11603
  • fix(scylladb): error on lossy CQL decimal conversion instead of silent truncation/NULL (fixes #11267) by @claudespice in #11604
  • ci(chbench): drop postgres-arrow and tuned (non-memory) from scheduled HTAP runs by @lukekim in #11606
  • ci(chbench): lower tuned SF1000 mem-tier max age to 15s for scheduled HTAP runs by @lukekim in #11618
  • fix(cayenne): fold the un-checkpointed mem-tier into the persisted-bloom PK-index rebuild (SF-100 over-count) by @lukekim in #11609
  • Potential fix for 1 code quality finding by @lukekim in #11614
  • fix(postgres): shared replication slot drops WAL for partitioned tables (fixes #11290) by @claudespice in #11607
  • bench(chbench): add 4-slot CDC variant pod for SF-1000 memory (separate from default) by @bjchambers in #11605
  • fix(cayenne): don't serve drifted memory-CDC row count as Exact to COUNT(*) by @bjchambers in #11602
  • chore(deps): vendor pgwire-replication 0.3.2 by @bjchambers in #11617
  • Add SQL warehouse ID to integration workflow by @Jeadie in #11561
  • fix(search): cosine_distance returns NULL not NaN for zero-magnitude vectors by @claudespice in #11621
  • feat(spidapter): tuned + adaptive MongoDB CDC spicepods with scenario selection by @bjchambers in #11579
  • Potential fixes for 3 code quality findings by @lukekim in #11613
  • Potential fixes for 2 code quality findings by @lukekim in #11611
  • Potential fixes for 2 code quality findings by @lukekim in #11615
  • Potential fix for 1 code quality finding by @lukekim in #11612
  • feat(cayenne): split mem-tier into ingestion + immutable pieces; advance the replication slot on a cheap periodic seal (default 2s) by @lukekim in #11622
  • fix(mcp): encode catalog-qualified tool names without '/' (fixes #10894) by @claudespice in #11629
  • fix(refresh): apply refresh_sql override on manual refresh when source unchanged (fixes #11353) by @claudespice in #11626
  • fix: report empty accelerated schema instead of misleading missing-column error (fixes #10920) by @claudespice in #11625
  • fix(imap): store message date as millisecond Timestamp, not seconds in Date64 (fixes #11547) by @claudespice in #11624
  • test(bucket): guard frozen partition-hash output against silent ahash drift (addresses #11277) by @claudespice in #11623
  • Bump datafusion (spiceai/datafusion#182) and datafusion-table-providers (#27): fix q16 CollectLeft planning error and SQLite q6 wrong revenue by @Jeadie in #11598
  • fix(cluster): prevent executor flaps and distributed query stalls by @phillipleblanc in #11565
  • fix(cli): allow spice trace on dynamic MCP/custom tool_use tasks (fixes #10995) by @claudespice in #11630
  • docs: add clang/lld to arm64 Linux build prerequisites (fixes #11120) by @claudespice in #11632
  • perf(cayenne): mem-tier visible-batch memo + maintained MIN/MAX IVM by @lukekim in #11631
  • docs: consolidate agent instructions and fix stale references by @lukekim in #11634
  • build(deps): bump the github-actions-dependencies group across 2 directories with 7 updates by @app/dependabot in #11627
  • perf(flight): offload query-result IPC encoding off the IO runtime by @lukekim in #11608
  • feat(runtime): reservation-aware Cayenne CDC query-memory default (75%โ†’70%) by @lukekim in #11641
  • Revert "ci(chbench): lower tuned SF1000 mem-tier max age to 15s for scheduled HTAP runs" by @lukekim in #11648
  • fix(cayenne): don't bump mem-tier version on seal (QPH regression from #11622) by @lukekim in #11649
  • feat(cayenne): vendor versioned row_converter module (byte-compatible with arrow-row 58.3.0) by @phillipleblanc in #11654
  • fix(flightsql): advertise analyzed query schemas by @phillipleblanc in #11656
  • feat(cayenne): bounded append freshness โ€” segmented stream publishing + publish-triggered executor stats broadcast by @phillipleblanc in #11620
  • fix(postgres): decouple replication keepalive/feedback from apply backpressure by @bjchambers in #11653
  • fix: bump DataFusion for eager decimal SUM schema by @phillipleblanc in #11657
  • fix(cayenne): stop mem-tier snapshot storms under memory pressure and byte-range splitting of small snapshot scans by @sgrebnov in #11645
  • fix(ducklake): add opt-in automatic_migration to attach older catalogs (fixes #10899) by @claudespice in #11635
  • ci(e2e): tolerate empty-type DuckDB variant of the parquet-rename race by @claudespice in #11636
  • build(deps): bump the aws-sdk group with 3 updates by @app/dependabot in #11628
  • ci(chbench): FIFO-queue HTAP runs via concurrency queue: max; simplify dispatcher by @bjchambers in #11659
  • fix(bucket): guard against ahash AES-path re-bucketing of partition data (fixes #11277) by @claudespice in #11665
  • fix(cayenne): gate metastore reinsert_sequence schema behind a user_version (fixes #11291) by @claudespice in #11651
  • fix(cayenne): durable CDC delete keeps the pk IN (...) fast path (fixes #11633) by @lukekim in #11642
  • ci(chbench): make scheduled HTAP runs adaptive-only (retire tuned, convert cold tier to adaptive) by @lukekim in #11677
  • fix(imap): decode text body into content instead of storing raw MIME (fixes #11549) by @claudespice in #11667
  • feat(cayenne): end-to-end integrity checksums for WAL records and Vortex data files (fixes #11639) by @claudespice in #11646
  • feat(spidapter): date-prefix per-run MongoDB CDC databases by @bjchambers in #11658
  • test(cayenne): fuzz mem-tier CDC + seq-prefix bake; harden durable-path count exactness by @bjchambers in #11643
  • deps: bump spiceai/datafusion to pick up ORDER BY alias unparser fix by @Jeadie in #11655
  • fix(postgres_replication): size CDC change-batch builders to the transaction row count by @sgrebnov in #11675
  • Release notes for v2.1.0 by @Jeadie in #11429
  • perf(pgwire-replication): incremental zero-copy framing (FrameReader) + bounded message size by @lukekim in #11668
  • fix(cdc): memory-mode changes stream no longer fatally stops on a transient deferred-commit queue (fixes #11644) by @bjchambers in #11678
  • test: update snapshots from job 84685029883 by @Jeadie in #11569
  • fix: Distinguish no filters vs lit(false) for RefreshSql distributed accelerations by @peasee in #11596
  • Fix cargo-deny crossbeam-epoch advisory by @Jeadie in #11681
  • fix: Update benchmark snapshots for trunk run by @app/github-actions in #11666
  • chore(deps): upgrade Vortex to 0.76.0 by @lukekim in #11682
  • refactor: extract runtime-metrics crate, move ComponentType to runtime-api-types by @Jeadie in #11524
  • feat(cloud-connect): standalone instance adoption by @lukekim in #11060
  • docs: keep the feature set constant across a session (incremental-build hygiene) by @bjchambers in #11679
  • feat(mysql): binlog replication for refresh_mode: changes by @lukekim in #11672
  • feat(cdc): cap keys per durable delete plan + absorb fall-through metrics (#11673) by @bjchambers in #11680
  • ci(chbench): run scheduled SF1000-adaptive HTAP bench every 6h instead of 3h by @lukekim in #11698
  • fix: MySQL connector fails to convert unsigned integer types (fixes #8364) by @claudespice in #11691
  • observability(cdc): localize CDC back-pressure across the ingest pipeline by @bjchambers in #11610
  • fix(cache): cache empty (zero-row) SQL result sets by @bjchambers in #11699
  • Update spicepod.schema.json by @Jeadie in #11706
  • Add support for MysSQL in Ch-Bench by @krinart in #11700
  • observability(chbench): limit CH-BenCHmark logs to info and above by @bjchambers in #11711
  • perf(cdc): cache per-dataset metric labels to avoid per-event string copies by @bjchambers in #11712
  • feat(postgres): pgoutput binary-format CDC decoding + zero-copy decoder by @bjchambers in #11702
  • Update integration_models.yml by @Jeadie in #11715
  • fix(cayenne): zero-row append refresh fails with "No such file or directory" by @sgrebnov in #11710
  • perf(cdc): cut shared-slot Postgres replication pump per-event overhead by @bjchambers in #11709
  • fix(spicepod): reject unknown fields on columns[] config (fixes #10972) by @claudespice in #11719
  • feat(cayenne): tier-gated O_DIRECT compaction writer (EBS/NAS network storage) by @lukekim in #11696
  • fix(cayenne): harden Vortex compaction writes by @phillipleblanc in #11692
  • perf(vortex): push boolean NOT filters into the Vortex scan by @lukekim in #11721
  • chore(chbench): cap scheduled HTAP runs at 250K tpmC (rate 9250) by @sgrebnov in #11723
  • MySQL CH-benCHmark HTAP: SF1 + SF1000 adaptive configs by @krinart in #11722
  • feat(testoperator): TPC-DS SF100 federated cluster-bench spicepod + default spicehq nodegroup by @phillipleblanc in #11716
  • refactor(runtime): move AccelerationSource and Acceleration into runtime-acceleration by @Jeadie in #11530
  • remove(ml): delete model_components crate and ONNX/Tract ML inference by @Jeadie in #11684
  • ci: dedupe testoperator query_overrides run steps by @Jeadie in #11690
  • Update search snapshots by @Jeadie in #11714
  • refactor: use inherent is::<T>() on dyn TableProvider/dyn ExecutionPlan for type checks by @Jeadie in #11585
  • chore: remove unused BlueOak license allowance by @phillipleblanc in #11762
  • perf(vortex): remove per-file and per-segment allocations on the scan path by @lukekim in #11733
  • fix(ci): use GraphQL API to check isLatest in spiced_docker workflow by @Jeadie in #11735
  • fix(release): use release notes heading as GitHub release title by @Jeadie in #11744
  • feat(chbench): headline run summary + adaptive slot-topology variants by @bjchambers in #11734
  • fix(ci): update e2e CLI tests for Windows-no-runtime and chat error wording by @Jeadie in #11717
  • build(rust): upgrade toolchain to 1.96.1 by @lukekim in #11743
  • fix(deps): enable reqwest "query" feature for isolated crate builds by @claudespice in #11760
  • build: define clippy lints in [workspace.lints], opt in every crate by @bjchambers in #11676
  • refactor(runtime): parameterize table-provider unwrapping by inner-fn set by @Jeadie in #11759
  • fix(cayenne): retain source deletion index in scan memos to close ABA hazard (fixes #11303) by @claudespice in #11739
  • fix(mysql): refuse binlog resume across source layout drift by @phillipleblanc in #11761
  • perf: avoid unnecessary allocations on search hot paths by @phillipleblanc in #11767
  • feat(spidapter): support cluster_name for private nodegroup targeting by @phillipleblanc in #11740
  • feat(cayenne): finalize datalake (cold) tier v1 UX, credentials, and e2e integration test by @sgrebnov in #11731
  • perf(vortex): push CAST(CASE ... END) filters into the Vortex scan by @lukekim in #11729
  • docs: lead README with real-time analytics-node + CDC messaging (Spice 2.0) by @lukekim in #11774
  • chore(chbench): extend scheduled HTAP runs to 15m by @lukekim in #11773
  • perf(cayenne): lazy NDV โ€” compute on file spill, off the inline hot loop by @bjchambers in #11741
  • ci(rust): install 1.96.1 in workflows that pin the toolchain explicitly by @lukekim in #11769
  • perf(cdc): deferred parsing โ€” move Postgres CDC decode + build off the shared pump by @bjchambers in #11732
  • docs: correct sort-kernel SIMD note (AVX2, not AVX-512) by @lukekim in #11771
  • fix(cayenne): roll cold-tier files at cayenne_cold_target_file_size_mb by @sgrebnov in #11746
  • docs(cayenne): move the Cayenne technical reference into the repo by @bjchambers in #11775
  • perf(cayenne): unify upsert PK-key hashing on prehashed XXH3-128 digests by @bjchambers in #11736
  • perf: avoid unnecessary allocations on query hot paths by @phillipleblanc in #11768
  • Extended schema inference for mysql by @krinart in #11742
  • chore(hash-index): add SBBF probe/insert baseline benchmark by @lukekim in #11770
  • feat(cayenne): incremental datalake promotion, per-file PK blooms, physical GC by @sgrebnov in #11745
  • test(cayenne): limit property-test concurrency by @phillipleblanc in #11784
  • perf(cdc): lock-free per-member ack slots + coalescing for shared Postgres replication by @bjchambers in #11779
  • perf(chbench): speed up MySQL and Postgres seed loading by @bjchambers in #11782
  • fix(ci): download MinIO client from public-data mirror by @phillipleblanc in #11790
  • ci: developer sign-off attestation gating the merge queue by @lukekim in #11776
  • fix(tests): synchronize chat expect prompts correctly by @phillipleblanc in #11802
  • perf(chbench): default adaptive pod to 4-slot grouping + deep prefetch by @bjchambers in #11799
  • refactor(cli): replace open crate with in-tree system-open by @phillipleblanc in #11791
  • refactor(runtime): drop direct rustls-pemfile dependency by @phillipleblanc in #11792
  • Cache ListingTable file statistics to avoid per-query footer re-parse by @phillipleblanc in #11793
  • ci: inherit sign-off across clean base merges by @phillipleblanc in #11804
  • perf(cayenne): hash PK once and skip OwnedRow clone on present path by @bjchambers in #11805
  • fix(postgres catalog): register partitioned parent, not child partitions by @bjchambers in #11798
  • fix(postgres catalog): quote foreign-key target identifiers by @bjchambers in #11796
  • refactor(cayenne): rename remaining cold_* params to cayenne_datalake_* by @sgrebnov in #11795
  • build: add release-profiling Cargo profile for CPU profiling by @bjchambers in #11807
  • fix(ci): make CH-benCH template restore robust to leftover replication slots by @sgrebnov in #11811
  • perf(cayenne): remove eager-NDV escape hatch, speed up per-value NDV hashing by @bjchambers in #11806
  • Auto-refresh the Attestation check after signoff by @bjchambers in #11815
  • refactor(duckdb): remove partitioned DuckDB accelerator modes by @lukekim in #11808
  • feat(testoperator): add option to skip the HTAP analytic gate by @bjchambers in #11810
  • fix: prevent executor S3 region poisoning before object-store bind by @phillipleblanc in #11766
  • perf(cayenne): reuse per-batch scratch allocations in KeyBasedDeletionFilterStream by @bjchambers in #11817
  • Update openapi.json by @app/github-actions in #11816
  • build(deps): bump the github-actions-dependencies group across 2 directories with 5 updates by @app/dependabot in #11819
  • fix(task_history): capture ExplainAnalyze metrics from the executed plan by @phillipleblanc in #11794
  • feat: generic spiced env-var passthrough for HTAP testoperator runs by @bjchambers in #11824
  • feat(cayenne): datalake tier hardening + row-capped PK-bloom-backed promotion by @sgrebnov in #11812
  • chore: release finalization for v2.2.0 by @Jeadie in #11738
  • feat(cayenne): add memory mode (mode: memory) โ€” fully in-RAM accelerator by @lukekim in #11720
  • Fix secrets in .github/workflows/integration_models.yml. by @Jeadie in #11781
  • feat(runtime): add runtime.query.timeout parameter by @sgrebnov in #11822
  • feat(cloud-connect): align proto to canonical, fix enrollment ordering, add TLS e2e by @lukekim in #11829
  • docs(criteria): mark PostgreSQL Catalog Connector as Alpha by @bjchambers in #11785
  • test(cayenne): add regression tests for the mid-pass overwrite guard by @sgrebnov in #11844
  • perf(cayenne): light delta encoding + higher CDC coalescing defaults by @bjchambers in #11826
  • ci: run Cayenne doc PDF build only on trunk merges by @bjchambers in #11860
  • fix(cayenne): drain staged Stage-B publishes before cold promotion; add cold-tier fuzz coverage by @sgrebnov in #11847
  • feat(cayenne): atomic cross-partition append + delete/on-conflict atomicity by @lukekim in #11803
  • feat(cayenne): min/max maintained aggregates + N>1 CDC retract by @lukekim in #11862
  • perf(chbench): CSV-based seed loading for MySQL and Postgres by @bjchambers in #11843
  • fix(tests): re-enable prop_concurrent_cold_sqlite cayenne cold-tier fuzz test by @sgrebnov in #11871
  • fix(deps): replace yanked spin releases by @phillipleblanc in #11878
  • fix(cayenne): correct stale mem_checkpoint_lock comment by @bjchambers in #11872
  • Add run links to testoperator_dispatch.yml by @Jeadie in #11747
  • Cayenne serializable transactions: gated writes, per-key OCC, multi-table, FlightSQL, durable write-back by @phillipleblanc in #11870
  • fix(cayenne): partitioned datasets deadlock against the global encode budget and never become ready by @Jeadie in #11825
  • test(runtime): re-runnable turso file cleanup + bump turso to 0.7.0 by @lukekim in #11783
  • Use liteparse for PDF document parsing by @Jeadie in #11522
  • ci: add remote signoff workflow by @Jeadie in #11864
  • fix(cli): populate org in spice cloud apps --output json (fixes #11041) by @claudespice in #11867
  • fix(embeddings): restore params broken by #10853 by @Jeadie in #11788
  • Move cargo advisory checks to scheduled workflow by @Jeadie in #11879
  • perf(cayenne): bound cold-promotion Z-order sort into streaming byte-capped runs by @sgrebnov in #11890
  • fix(cayenne): write-back transaction atomicity โ€” stage (not publish) and read mem-tier rows by @phillipleblanc in #11889
  • fix(runtime-table-partition): restore sound modulo inequality partition pruning by @Jeadie in #11891
  • Replace dotenvy with in-repo dotenv crate by @phillipleblanc in #11894
  • Remove unnecessary allocations from results-cache and hot conversion paths by @phillipleblanc in #11895
  • Increase ready_wait timeout for chbench sf1000 cold-tier configs by @sgrebnov in #11900
  • fix(mysql): retry binlog checkpoint upsert on transient accelerator write lock by @krinart in #11876
  • fix(cayenne): gate freshness mem-tier shrink on apply backlog by @lukekim in #11893
  • fix(postgres catalog): honor unsupported_type_action for catalog-discovered tables by @bjchambers in #11875
  • fix(postgres): make TPC-H/TPC-DS benchmark CI actually run at SF1/SF10/SF100 by @bjchambers in #11883
  • feat(search): writethrough compound SearchIndex/VectorIndex with optional fallback by @Jeadie in #11892
  • Revert "perf(cayenne): light delta encoding + higher CDC coalescing defaults" by @bjchambers in #11910
  • perf(vss): SIMD-accelerate cosine_distance via simsimd by @Jeadie in #11748
  • Add run-name to signoff.yml by @Jeadie in #11912
  • fix(cayenne): serialize cold-tier mem-tier checkpoint by @sgrebnov in #11907
  • fix(postgres catalog): discover materialized views and foreign tables by @bjchambers in #11874
  • test(chbench): stronger content fingerprint + MySQL sidecar template caching by @krinart in #11901
  • test(chbench): align money columns to canonical DECIMAL schema (CMU BenchBase) by @sgrebnov in #11921
  • fix(cayenne): close per-key OCC missed-conflict holes and fused-txn IVM staleness by @lukekim in #11916
  • ci(attestation): fast-track pure reverts past developer sign-off by @bjchambers in #11913
  • fix(cloud-connect): accept the portal's 5-char adoption-code segments by @phillipleblanc in #11926
  • docs(layering): codify crate tiers + workspace layering guard by @bjchambers in #11919
  • refactor(cayenne): datalake tiering UX โ€” param rename + tracing by @sgrebnov in #11920
  • feat(params): typed component params via #[derive(TypedParams)] โ€” embeddings pilot by @Jeadie in #11809
  • Fix SQlite round type error. by @Jeadie in #11927
  • fix(signoff): let remote sign-off refresh the Attestation check in CI by @bjchambers in #11929
  • feat(testoperator): print rows around CH-benCH analytical-gate mismatches by @bjchambers in #11923
  • fix(postgres catalog): don't abort the whole catalog on one schema's discovery failure by @bjchambers in #11873
  • ci(signoff): target-lint changed crates before full local/remote gate by @lukekim in #11909
  • feat(runtime)!: always-on schema inference; remove schema_inference config by @lukekim in #11880
  • refactor(layering): extract ClickHouse into connector-clickhouse; add restricted_deps guard by @bjchambers in #11931
  • perf: remove unnecessary allocations on hot query, search, and metrics paths by @phillipleblanc in #11918
  • Release notes for v2.1.1 by @Jeadie in #11906
  • refactor(layering): prepare DynamoDB for extraction from runtime by @bjchambers in #11935
  • Coalesce Null primary keys in RRF. by @Jeadie in #11519
  • ci(e2e): strip ANSI before duckdb_append graceful-shutdown log whitelist by @phillipleblanc in #11937
  • feat(catalog): PostgreSQL catalog-level CDC acceleration (changes mode) by @bjchambers in #11897
  • chbench(mysql): parallel analytical gate, decimal-comparison fix, and reseed/CI hardening by @krinart in #11946
  • fix: array_any_value panic when output is hash-repartitioned (empty list elements) by @bjchambers in #11952
  • feat(layering): checkpoint sidecar as per-engine crates + DI the dynamodb connector by @bjchambers in #11938
  • chore(cluster): pin Ballista to upstream 54 merge tip by @phillipleblanc in #11941
  • feat(vortex): upgrade fork pins to Vortex 0.79.0 by @lukekim in #11950
  • chbench(htap): run mysql configs at the shared 9250 rate; 2x converge wait by @sgrebnov in #11956
  • fix(testoperator): HTAP drain gate false-fails on stale probe observations โ€” final snapshot decides convergence (fixes #11953) by @claudespice in #11966
  • feat(catalog): replica-identity-aware eligibility for PostgreSQL catalog CDC by @bjchambers in #11951
  • refactor(layering): extract DynamoDB into connector-dynamodb by @bjchambers in #11960
  • Add MemoryVectorIndex: in-memory external-store VectorIndex with brute-force exact k-NN by @Jeadie in #11908
  • ci(signoff): prefer lab SSH for remote sign-off; skip Rust when no .rs changes by @lukekim in #11977
  • Reapply #11826: light delta encoding + CDC coalescing (SF1000 convergence lever) โ€” gated on #11943 + SF1000 fingerprint run by @lukekim in #11944
  • docs: align component statuses with signed release criteria by @lukekim in #11970
  • fix: Spidapter flight auth passthrough by @peasee in #11976
  • Unified CDC config by @krinart in #11777
  • feat(cdc): Debezium plugin push ingest to Spice without Kafka by @lukekim in #11955
  • refactor(connectors): unify registration on the linkme slice; restore schema coverage by @bjchambers in #11972
  • GTID-based MySQL CDC by @krinart in #11813
  • test(mysql): ignore mysql_binlog_replication_end_to_end_cayenne by @sgrebnov in #11986
  • fix(cayenne): support Decimal128 in maintained SUM/AVG aggregates (fixes #11933) by @claudespice in #11979
  • feat(params): typed params for VectorStore and FtsStore engines by @Jeadie in #11954
  • chore(layering): remove orphaned dead code from connector extractions by @bjchambers in #11988
  • feat(cayenne): default-on adaptive cold layout from observed filters (F4) by @lukekim in #11973
  • fix: Fairly allocate partitions from scheduler assignment cycle only by @peasee in #11853
  • fix(cli): avoid escaped ANSI version notification by @ewgenius in #11996
  • MySQL Shared binlog connection by @krinart in #11814
  • feat(catalog): fail-loud + metrics + by-kind reporting for PostgreSQL catalog CDC (#11850) by @bjchambers in #11983
  • fix(cayenne): P1 audit โ€” subset compact, SMJ 2.5ร— HT, mem-tier pool account by @lukekim in #11991
  • Add OAuth2 client-credentials grant and configurable auth header to HTTP connector by @krinart in #11981
  • fix(telemetry): validate runtime.telemetry.metric_prefix against OTel name syntax by @ewgenius in #12002
  • fix(cayenne): purge CDC mem-tier on delete-all/TRUNCATE by @sgrebnov in #12009
  • Update signoff.yml. by @Jeadie in #11998
  • feat(dev): add scripts/signoff mine โ€” attestation status across your open PRs by @Jeadie in #11978
  • refactor(layering): extract MongoDB provider into connector-mongodb by @bjchambers in #11982
  • perf: remove three unnecessary allocations on the query hot path by @phillipleblanc in #12029
  • refactor(layering): evacuate cosmosdb/graphql/github/sharepoint providers into their connector crates by @bjchambers in #12024
  • fix(mysql-cdc): detect source reset on GTID resume by @sgrebnov in #12023
  • fix(smb): exclude final SESSION_SETUP response from preauth integrity hash (fixes #11148) by @claudespice in #12003
  • fix(postgres): validate pg_replication_slot names before CDC refresh by @ewgenius in #12001
  • fix(postgres): honor pg_connection_string for CDC (closes #11994) by @ewgenius in #12000
  • feat: Support OTLP Histogram ingest, unix nanos time by @peasee in #11992
  • feat(search): write-through warm + fallback compound index for FTS (#11886) by @Jeadie in #11971
  • docs: PR-description and code-comment conventions by @bjchambers in #12032
  • refactor(postgres cdc): consolidate every dataset onto the shared pump by @bjchambers in #12028
  • feat(cloud-connect): Standalone instance adoption connection by @peasee in #11980
  • fix(cdc): don't force the durable path on zero-row readiness heartbeats (fixes #12007) by @claudespice in #12030
  • Upgrade DataFusion to 54.1.0 by @krinart in #11974
  • perf(github): parallelize serial fetches (commits + workflow logs) by @lukekim in #12017
  • refactor(layering): evacuate odbc/scylladb/imap/git providers into their connector crates by @bjchambers in #11993
  • refactor(layering): carve runtime-component out of runtime, break the ArcRuntime cycle by @bjchambers in #12031
  • feat(mssql): enable tiberius integrated-auth-gssapi for Kerberos integrated auth on Unix by @v1gnesh in #11386
  • build(deps): bump the aws-sdk group across 1 directory with 5 updates by @app/dependabot in #11821
  • fix(cayenne): clear a committed CDC upsert's staging WAL at finalize (#12027) by @bjchambers in #12034
  • feat(catalog): deterministic instance-independent replication slot + fail-loud + restart recovery (#11850) by @bjchambers in #12026
  • Auto-cap DuckDB accelerator memory to prevent startup over-commit by @lukekim in #11985
  • perf(refresh): speed up dataset refresh at startup by @lukekim in #12015
  • fix(cayenne): don't create stray file: directory in memory mode (fixes #11922) by @claudespice in #11940
  • fix(aws): accept aws_session_token for temporary credentials (fixes #10932) by @claudespice in #12041
  • fix(mysql): verify an adopted layout against the event's own column types (fixes #11764) by @claudespice in #12048
  • fix(mysql): take the binlog rotate target from the ROTATE event, not its header offset (fixes #12042) by @claudespice in #12044
  • fix(search): check dataset readiness before embedding the query (fixes #10956) by @claudespice in #12043
  • fix(databricks): pin the authentication mode with databricks_auth_mode so an auto-loaded client secret can't switch U2M to M2M (fixes #11508) by @claudespice in #12040
  • fix(imap): narrow scans with IMAP SEARCH instead of refetching the mailbox (fixes #11548) by @claudespice in #12039
  • fix(cayenne): rank inference-derived sort columns below observed filter columns by @lukekim in #12049
  • perf(cayenne): warm-subset compaction + mem-tier memory_limit honesty by @lukekim in #12035
  • fix(cayenne): purge the mem-tier on delete-all for a table without a primary key (fixes #12072) by @claudespice in #12073
  • fix(accelerator): let an index declare a finalize failure fatal so a stale index can't report a successful refresh (fixes #12038) by @claudespice in #12050
  • fix(http): restore a join's embedded projection in HTTP subquery pushdown (fixes #11009) by @claudespice in #12054
  • fix(e2e): report a REPL that exits mid-script instead of passing the step (fixes #12057) by @claudespice in #12059
  • fix(imap): fetch the raw message only when a scan reads content (fixes #12045) by @claudespice in #12060
  • chore: Update Turso crate to 0.7.1 by @claudespice in #12062
  • feat(chbench): in-memory _bench_ts watermarks for the MySQL HTAP staleness probe by @sgrebnov in #12055
  • test(chbench): default MySQL adaptive spicepods to one shared binlog dump by @sgrebnov in #12076
  • feat(search): warm in-memory writethrough/fallback index for .vectors datasets and views by @Jeadie in #11914
  • fix(search): expunge superseded documents from full-text BM25 statistics (fixes #12053) by @claudespice in #12056
  • fix(write-back): gate durable write-back on a safe source delivery primitive (fixes #11915) by @claudespice in #12051
  • fix(cayenne): keep protected snapshots a position-delete rewrite never folded in (fixes #11477) by @claudespice in #12052
  • ci(signoff): fast-track Attestation for Dependabot and non-Rust PRs, and cut the local gate by @lukekim in #12081
  • fix(search): reach a compound's inner full-text tier when a change stream attaches (fixes #12061) by @claudespice in #12063
  • fix(accelerator): report PK equality pushdown Inexact so a point lookup can't return the whole table (fixes #12070) by @claudespice in #12071
  • fix(github): paginate issues and pull_requests on an immutable sort key so a row touched mid-scan isn't dropped (fixes #12067) by @claudespice in #12069
  • fix(otel): scope reserved metric column names to the data-point shape (fixes #12064) by @claudespice in #12065
  • fix(cayenne): sample the subset compaction append fence before the listing it guards (fixes #12074) by @claudespice in #12075
  • fix(search): drop a search hit whose row is not in the base table (fixes #12089) by @claudespice in #12094
  • feat(datasets): mark non-accelerated datasets Error when their source is unavailable by @krinart in #12079
  • fix(models): restore spice.ai/spiceai as a model source by @lukekim in #12092
  • fix(cayenne): bound the cold PK-index rebuild; build shard views in one pass by @sgrebnov in #12078
  • fix: Update Search integration test snapshots by @Jeadie in #12077
  • feat(catalog): view warnings, docs-linked messages, and clearer startup summary for PostgreSQL catalog CDC (#11850) by @bjchambers in #12022
  • fix(postgres): log the cumulative delivery wait in the sink-stall warning by @sgrebnov in #12093
  • refactor(cloud-connect): single-source the sealed-secret wire crypto in a shared crate by @peasee in #12124
  • build(deps): bump quinn-proto from 0.11.14 to 0.11.16 by @app/dependabot in #12037
  • perf(cayenne): demand-driven scan-view cache with access-based freshness (alternative to #11948) by @bjchambers in #12005
  • build: exclude libnfs from the nextest workspace run by @phillipleblanc in #12131
  • build(deps): bump the aws-sdk group across 1 directory with 3 updates by @app/dependabot in #12068
  • fix(search): keep CDC changes streams working when embeddings wrap a CDC source by @Jeadie in #12086
  • fix(cli): report a truncated release download as a failed download (fixes #12120) by @claudespice in #12121
  • fix(postgres): honor inline PEM pg_sslrootcert on the replication path by @phillipleblanc in #12128
  • refactor(layering): extract RuntimeStatus into a runtime-status crate by @bjchambers in #12115
  • fix(libnfs): model AUTH as an opaque type so its layout assertion holds by @phillipleblanc in #12132
  • feat(duckdb): on_full_refresh: replace_file โ€” full refresh into a new database file, atomically replaced by @lukekim in #12135
  • Add v2.1.2 release notes by @sgrebnov in #12146
  • feat(duckdb): 'on_full_refresh: checkpoint_file' to bound acceleration file growth by @sgrebnov in #12139
  • fix(lint): remove unused DuckDBTableWriter import in duckdb accelerator tests by @sgrebnov in #12158
  • fix(duckdb): drop a file-replacement test assertion that can never hold by @bjchambers in #12178
  • fix(cayenne): Remove redundant EmptyExec within UnionExec used by CayenneTableProvider::scan by @Jeadie in #12126
  • build(deps): bump async-openai for aggregated rate-limit logging by @phillipleblanc in #12149
  • perf(mysql): fast row-image decoder for CDC change builds by @sgrebnov in #12122
  • feat(catalog): pre-flight replication-slot-capacity check for PostgreSQL catalog CDC (#11850) by @bjchambers in #12114
  • fix(oracle): map DATE to a timestamp so the time-of-day is not silently truncated (fixes #12096) by @claudespice in #12097
  • fix(search): skip the warm vector index when nothing hydrates it (fixes #12101) by @claudespice in #12103
  • refactor(layering): extract the DataAccelerator contract into data-accelerator-api by @bjchambers in #12099
  • fix(cli): surface the registry error behind a failed spice add instead of blaming the archive (fixes #12116) by @claudespice in #12119
  • fix(ci): gate Rust checks on the lint config the gate itself reads (fixes #12111) by @claudespice in #12112
  • fix: Ensure executors report table statistics for distributed plan ordering by @peasee in #11854
  • fix: EMBED_UDF_NAME without models feature by @krinart in #12136
  • fix(openai): openai_responses_tools: web_search uses web_search, not web_search_preview by @Jeadie in #12142
  • fix(ci): cancel workflow runs left behind by superseded merge-queue batches (fixes #12170) by @claudespice in #12177
  • fix(runtime): return from a readiness wait when the runtime shuts down (fixes #12125) by @claudespice in #12165
  • perf(postgres): coalesce shared-slot CDC envelopes so a slow sink stops throttling the walsender by @bjchambers in #12147
  • fix(ci): make cargo_deny_advisories.yml parseable so the Rust advisory scan can run (fixes #12181) by @claudespice in #12182
  • fix(cluster): run GetTaskHistory under read-only SQL validation by @lukekim in #12174
  • fix(duckdb): count accelerated views in the coordinated memory budget (fixes #12123) by @claudespice in #12161
  • fix(ci): run the PR hygiene check on a GitHub-hosted runner by @claudespice in #12163
  • fix(cayenne): warm PK existence caches at first write; bound keyset memory during bulk load by @sgrebnov in #12133
  • ci: remote sign-off dispatches GitHub Actions only, never SSH to lab hosts by @lukekim in #12205
  • Standalone instances: spice connect enroll-only split + connect surface by @krinart in #12143
  • fix(search): Fix ordering to correct NDCG@k by @Jeadie in #12191
  • refactor(layering): carry component configuration into connectors and extract data-connector-api by @bjchambers in #12157
  • fix(logging): mute the candle embedding backend's GeLU notice below -vv by @phillipleblanc in #12194
  • test: redact connection context in federated explain snapshots by @bjchambers in #11800
  • Enable deletes for Index, SearchIndex, and VectorIndex by @Jeadie in #11961
  • feat(testoperator): trace probe latency breaches and percentiles under HTAP load by @sgrebnov in #12209
  • Add v2.1.1 and 2.1.2 as supported in SECURITY.md by @sgrebnov in #12190
  • fix(ci): seed the TPC-H Postgres benches from the fleet's dataset and schedule the catalog schema tests by @bjchambers in #12214
  • fix(cluster): restrict ExpandSecret to spicepod-referenced keys by @lukekim in #12156
  • test: redact endpoint-URL compute contexts in federated explain snapshots by @bjchambers in #12215
  • fix(testoperator): a fully-censored table floors worst-P99 at the discard cap by @lukekim in #12196
  • ci(e2e): tolerate any garbage type token in the duckdb_append parquet-rename race by @bjchambers in #12207
  • refactor(cloud-connect): update the proto contract for evolvability and versioning by @peasee in #12153
  • chore(cloud-connect): use port 443 for gateway addresses in the doc example and test fixtures by @phillipleblanc in #12252
  • fix(ci): authenticate the management API integration suite with secrets that exist (fixes #12184) by @claudespice in #12185
  • feat(search): add Recall@k, MRR@k, and Precision@k retrieval metrics by @Jeadie in #12193
  • fix(search): enable stemming by default for full-text search by @Jeadie in #12220
  • fix: Report query metrics when task history is disabled by @sgrebnov in #12227
  • fix(runtime): count accelerated views when gating the Cayenne compaction pool (fixes #12164) by @claudespice in #12171
  • fix(secrets): snapshot the store registry instead of holding its lock across awaits (fixes #12127) by @claudespice in #12166
  • fix(search): address Elasticsearch deletes by document _id (fixes #12267) by @claudespice in #12273
  • fix(postgres): deprecate pg_replication_temporary_slot, which could never work (fixes #12213) by @claudespice in #12265
  • fix(cayenne): always materialize a snapshot directory the catalog may reference (fixes #12208) by @claudespice in #12262
  • fix(duckdb): size the connection pool for accelerated views too (fixes #12160) by @claudespice in #12169
  • fix(ci): link brew formulas that are installed but unlinked in setup-cc by @claudespice in #12286
  • fix(runtime): size memory budgets from the process's own cgroup limit by @lukekim in #12263
  • Harden dataset availability checks against idle connection resets by @krinart in #12180
  • test(mysql): harden binlog CDC with dump-reconnect and full type-matrix coverage by @sgrebnov in #12264
  • fix: send enc_pubkey_pem on /renew for standalone runtime by @phillipleblanc in #12312
  • Connection-scale client modes for testoperator throughput and load tests by @lukekim in #12280
  • fix(search): remove all chunk documents when a chunked Elasticsearch index deletes a row (fixes #12088) by @claudespice in #12268
  • fix(duckdb): run spice_sys DuckDB sidecar writes on the blocking pool (fixes #12175) by @claudespice in #12204
  • fix(cayenne): the write-concurrency raise must respect the memory brake by @lukekim in #12317
  • feat(runtime): expose the memory numbers that explain an OOM as gauges by @lukekim in #12195
  • fix(flightsql): mark stamped statistics inexact when a LIMIT is pushed to the remote scan (fixes #12292) by @claudespice in #12293
  • fix(deps): bump wasmtime to 47.0.3 to clear RUSTSEC-2026-0222 (fixes #12295) by @claudespice in #12298
  • fix(telemetry): read the cgroup CPU quota along the whole cgroup path (fixes #12299) by @claudespice in #12300
  • refactor(layering): move the DataFusion helpers below runtime and derive the federation deny-list from a function registry by @bjchambers in #12210
  • fix(search): reject a persisted full-text index whose schema no longer matches the configuration (fixes #12274) by @claudespice in #12275
  • fix(spiced): keep dependency logging and chat progress alive when task history is off (fixes #12279) by @claudespice in #12281
  • fix(runtime): count a mid-stream response failure as a failure in the HTTP metrics (fixes #12284) by @claudespice in #12291
  • fix(cluster): mark a coordinator leaf scan's cached executor statistics inexact (fixes #12303) by @claudespice in #12304
  • fix(runtime): report a memory-pool refusal as ResourcesExhausted and answer it with 503 (fixes #12282) by @claudespice in #12289
  • fix(cayenne): enforce the sharded PK keyset byte budget; correct per-entry accounting by @lukekim in #12192
  • fix(runtime): carve the Cayenne compaction memory pool only when a dataset can compact into it (fixes #12320) by @claudespice in #12326
  • feat(spiced): report fatal signals before exit by @sgrebnov in #12334
  • bug: Filters on _match fail during planning by @Jeadie in #12247
  • bug: S3 metadata-filter conversion silently drops unconvertible AND/OR operands by @Jeadie in #12248
  • fix(ci): reject a failed sign-off on the head commit (fixes #12357) by @claudespice in #12362
  • ci: let signoff.yml sign off fork PRs by @Jeadie in #12025
  • fix(search): resolve an append stream through a vector scan (fixes #12313) by @claudespice in #12314
  • docs: Spice v2.1.3 release notes by @sgrebnov in #12378
  • bug: MemoryVectorIndex leaves external-store entries on delete. by @Jeadie in #12246
  • fix(cluster): keep the executor's cluster-service channel alive while idle (fixes #12301) by @claudespice in #12302
  • fix(https): reject OAuth2 params on structured HTTP file datasets (fixes #12315) by @claudespice in #12321
  • fix(scheduler): drive the interval-timing tests on a virtual clock (fixes #12323) by @claudespice in #12329
  • fix(ci): do not report a shutdown-cancelled sidecar task as a failure (fixes #12322) by @claudespice in #12331
  • fix(logging): let log colour follow the output sink (fixes #12327) by @claudespice in #12335
  • fix(cayenne): report the auto-tuned config once per resolution (fixes #12330) by @claudespice in #12341
  • chore: Update Turso crate to 0.7.2 by @claudespice in #12344
  • fix(runtime): stop retrying a dataset configuration failure that no retry can clear (fixes #12339) by @claudespice in #12345
  • build(deps): bump the github-actions-dependencies group across 3 directories with 9 updates by @app/dependabot in #12359
  • feat(llms): GLM 5.2 across 3+ nodes, context_length + paged_attention params, MXFP4 for DeepSeek-V4 by @lukekim in #11990
  • feat(runtime): size every CPU-derived pool from the CPU entitlement by @bjchambers in #12276
  • chore(ci): bump the spiceio setup action to v0.5.9 by @lukekim in #12391
  • feat(testoperator): serve /health and /v1/ready for the HTAP run by @lukekim in #12373
  • feat(catalog): durable storage modes for PostgreSQL catalog CDC, and let the catalog own its accelerated tables by @bjchambers in #12222
  • fix(runtime): correctly classify a memory-pool refusal as ResourcesExhausted (fixes #12380) by @sgrebnov in #12382
  • fix(ci): budget the sign-off run below the pool's job wall (fixes #12340) by @claudespice in #12343
  • fix(bench): install make before the seeded-database check; surface catalog error causes by @bjchambers in #12372
  • Clean up SQLite sidecar files in cold bloom catalog test by @sgrebnov in #12404
  • fix(ci): name an incoherent Cargo.lock before every cargo job fails on it (fixes #12375) by @grokspice in #12423
  • test(search): exercise the S3 Vectors warm-tier fallback path by @Jeadie in #12197
  • fix(ci): stop the spiced child E2E cleanup was leaking, scoped to this runner (fixes #12058) by @grokspice in #12431
  • perf(cayenne): give refresh_mode full its own write profile by @lukekim in #12338
  • fix(ci): skip the Attestation refresh when the sign-off SHA is no longer the PR head (fixes #12360) by @grokspice in #12433
  • fix(monitoring): correct p99 queries in the Datadog dashboard by @sgrebnov in #12444
  • fix(ci): tell an out-of-disk sign-off apart from a failing branch (fixes #12412) by @grokspice in #12426
  • feat(search): warm in-memory tier for chunked Elasticsearch vector columns by @Jeadie in #12082
  • Update spicepod.schema.json by @app/github-actions in #12451
  • fix(search): preserve field names with capitals and '.' by @Jeadie in #12389
  • fix(ci): size the cayenne property-test timeout ceiling to its measured runtime (fixes #12336) by @grokspice in #12438
  • fix(models): pass the pinned revision to a HuggingFace embedding model (fixes #12430) by @grokspice in #12446
  • fix(ci): make the out-of-disk sign-off verdict survive being out of disk (fixes #12427) by @grokspice in #12461
  • fix(ci): stop Enforce Pulls with Spice racing itself, and let a Dependabot PR pass it (fixes #12377) by @grokspice in #12466
  • docs: update v2.1.3 release notes for the Iceberg timestamptz fix (trunk sync) by @phillipleblanc in #12459
  • fix(ci): install protoc before building the spice CLI in the E2E CLI workflow by @phillipleblanc in #12449
  • fix(ci): reject an if: naming a context GitHub does not provide there (refs #12396) by @grokspice in #12468
  • fix(monitoring): align Datadog dashboard with OTel service instance identity by @ewgenius in #12454
  • chore(ci): bump the spiceio setup action to v0.5.10 by @lukekim in #12490
  • test(cayenne): query result correctness vs standalone engines and Spice accelerators by @lukekim in #12098
  • fix(elasticsearch): keep the response body out of errors on the row-data request paths (fixes #12409) by @grokspice in #12456
  • fix(ci): key the sign-off concurrency group on the commit, not the dispatch input (fixes #12472) by @grokspice in #12474
  • perf(ci): run the workspace unit-test gate in one cargo invocation by @bjchambers in #12437
  • feat(monitoring): Runtime Resources observability on Grafana dashboard by @ewgenius in #12441
  • fix(ci): report cache health on the build failures it explains (refs #12420) by @grokspice in #12471
  • fix: resolve fixed-offset timezones when writing Vortex files by @phillipleblanc in #12463
  • fix(search): stop re-parsing a dotted index key as relation.column (fixes #12462) by @grokspice in #12464
  • fix(ci): build the ADBC BigQuery driver with the Go version its go.mod requires by @grokspice in #12470
  • fix(llms): keep the Hugging Face cache token and harden the model E2E job by @grokspice in #12422
  • fix(ci): stop a cancelled Remote Sign-off from claiming the checks failed (fixes #12424) by @grokspice in #12425
  • fix(runtime): fail the write when an index cannot prepare its write window (fixes #12421) by @grokspice in #12448
  • fix(runtime): stop retrying a permanent configuration failure on the catalog and dataset load paths (fixes #12417) by @grokspice in #12443
  • chore(ci): bump spiceio setup action to v0.6.0 by @lukekim in #12522
  • fix(ci): say what was unready when a spiced readiness wait times out (refs #12473) by @grokspice in #12484
  • feat(cayenne): drive incremental vacuum from the maintenance tick by @lukekim in #12435
  • feat(ci): allow additional cargo features for spiceai-dev Docker builds by @ewgenius in #12198
  • fix(cli): authenticate the SQL REPL's nql line like the session's SQL (fixes #12491) by @grokspice in #12496
  • fix(search): keep the row's primary key out of Elasticsearch bulk-index failures (fixes #12370) by @claudespice in #12410
  • fix(cpu-budget): state a low CPU request plainly, and only below half the cores by @bjchambers in #12440
  • fix(models): reject a pinned Model2Vec revision instead of 401ing on it (fixes #12445) by @grokspice in #12475
  • fix(cli): keep a login credential on the origin it was minted for (fixes #12505) by @grokspice in #12508
  • bug: S3 vector indexing succeeds when the embedding column is absent by @Jeadie in #12249
  • bug: S3 Vectors advertises unsupported metadata predicates as exact pushdown (fixes #12243) by @Jeadie in #12250
  • fix(cli): treat a blank --api-key as no key at all (fixes #12498) by @grokspice in #12501
  • task: Add #[derive(TypedParams)] for secret stores. by @Jeadie in #12154
  • fix(runtime): report a deferred dataset that cannot build its connector (fixes #12414) by @grokspice in #12483
  • fix(mysql): pre-flight CDC replication privileges with an actionable error (fixes #11967) by @grokspice in #12485
  • fix(testoperator): reject a client fleet the HTTP executors cannot bound (fixes #12348) by @claudespice in #12349
  • fix(ci): commit the catalog schema snapshot baselines and stop the daily PR churn by @phillipleblanc in #12525
  • refactor(runtime): describe every table-provider wrapper layer once in a layer table by @phillipleblanc in #12200
  • Add testoperator dispatch support for search benchmarks and replace benchmarks_search.yml by @Jeadie in #12224
  • bug: RRF discards a candidate stream after an empty first batch (fixes #12239) by @Jeadie in #12384
  • fix(cli): stop the SQL REPL asking a runtime its queries never went to (fixes #12493) by @grokspice in #12494
  • test(runtime): run the metrics tests that are built but never run by @sgrebnov in #12510
  • fix(tests): assert the search cache status instead of wall-clock timings (fixes #12487) by @grokspice in #12488
  • fix(search): resolve a chunked index's entries from the authoritative store, not the read listing (fixes #12266) by @claudespice in #12411
  • fix(search): Improvements for search harness by @Jeadie in #12226
  • test(cayenne): cover the selective PK join and the inline/file tier boundary by @lukekim in #12517
  • fix(runtime): surface the unknown-connector suggestion, and report it once (fixes #12415) by @grokspice in #12469
  • fix(ci): publish no sign-off verdict when the run was signalled (fixes #12518) by @grokspice in #12544
  • refactor(layering): move the modules the accelerated table shares below runtime by @bjchambers in #12219
  • chore(ci): upgrade spiceio setup action to v0.7.0 by @lukekim in #12611
  • fix(runtime): keep the leading slash on an inferred local Iceberg warehouse root (fixes #12533) by @grokspice in #12540
  • fix(ci): let a cancelled sign-off correct only the failure it posted (fixes #12428) by @grokspice in #12432
  • fix(runtime): compare an append high-water mark inclusively on a day-granular time column (fixes #12492) by @grokspice in #12500
  • fix(runtime): report a dataset connector load failure once, not once per site (fixes #12365) by @grokspice in #12526
  • fix(workers): give the weighted-router test a noise margin it can survive (fixes #12537) by @grokspice in #12538
  • fix(runtime): reject a Hadoop table URL too short to name a namespace (fixes #12539) by @grokspice in #12542
  • fix(ci): probe a pinned Hugging Face revision at a URL the Hub has (fixes #12553) by @grokspice in #12554
  • feat(testoperator): pin the load phase to a target query rate by @lukekim in #12519
  • fix(cli): follow only same-origin redirects, so the API key cannot leave the origin by @grokspice in #12503
  • fix(ci): use spiceio and sccache for E2E macOS aarch64 builds by @lukekim in #12590
  • perf(cdc): build a drained CDC burst with one blocking-pool handoff by @sgrebnov in #12514
  • feat(cloud-connect): complete the spice connect surface โ€” install, codeless connect, remove by @peasee in #12159
  • fix(scripts): distinguish merge-queue PRs in signoff mine by @Jeadie in #12383
  • bug: HTTP RRF truncates each candidate leg before fusion by @Jeadie in #12386
  • fix(cayenne): pair the cold manifest with the warm snapshot a scan captured by @phillipleblanc in #12577
  • fix(deps): bump the Vortex pin and guard the task-cancellation regression by @phillipleblanc in #12548
  • chore(deps): bump datafusion and table-providers for the DuckDB timezone and retention fixes by @phillipleblanc in #12545
  • fix(cayenne): surface the real error for partitioned Cayenne writes by @Jeadie in #12535
  • fix(postgres): re-snapshot in-memory Cayenne on slot resume, and match the slot's lifetime to the accelerator's by @bjchambers in #12221
  • fix(cli): bound the Spice.ai login poll instead of retrying forever (fixes #12506) by @grokspice in #12523
  • fix(runtime): name a UTC timestamp column's zone in a spelling DuckDB knows (fixes #12528) by @grokspice in #12534
  • fix(mysql): raise net_write_timeout on the shared binlog dump session (fixes #12527) by @claudespice in #12586
  • fix(google-genai): read a Gemini SSE stream as bytes, so a split character survives (fixes #12597) by @claudespice in #12601
  • fix(mssql): follow an availability group's read-only routing redirect (fixes #11453) by @claudespice in #12607
  • test(cayenne): measure small-file fan-out against the seeded appends, not a listed count (fixes #12602) by @claudespice in #12613
  • fix(ci): keep the build cache's S3 endpoint out of the runtime under test (fixes #12624) by @claudespice in #12626
  • perf(ci): verify the CLI binary instead of building it again by @bjchambers in #12486
  • fix(postgres): publish a member's held CDC envelope before a bulk transaction (fixes #12311) by @claudespice in #12408
  • fix(cayenne): consolidate the two partition creators, fixing the accelerator's missing directory sync (fixes #12212) by @claudespice in #12619
  • fix(cayenne): run a backend-parameterized test on a stack its plan fits in (fixes #12436) by @grokspice in #12561
  • fix(ci): let only the merge queue pass Attestation without a sign-off (fixes #12679) by @grokspice in #12681
  • fix(ci): take the trusted sign-off helpers from the workflow's own commit (fixes #12657) by @claudespice in #12662
  • fix(ci): name the E2E jobs that did not succeed (fixes #12643) by @grokspice in #12649
  • fix(ci): give the openai model job a ceiling above its own setup (fixes #12644) by @grokspice in #12650
  • fix(ci): recognise the Flight bind wording so a foreign ready cannot pass (fixes #12642) by @grokspice in #12648
  • fix(ci): call an unreachable compiler cache infrastructure, not a failing branch (fixes #12556) by @grokspice in #12557
  • fix(search): clear a replacing index instead of keeping rows the source dropped (fixes #12066) by @grokspice in #12564
  • fix(ci): retry the sign-off status post, and say so when it never lands (fixes #12701) by @grokspice in #12704
  • build(deps): bump aws-smithy-runtime from 1.12.0 to 1.12.1 in the aws-sdk group across 1 directory by @app/dependabot in #12358
  • task: Add #[derive(TypedParams)] for LLMs. (fixes #12150) by @Jeadie in #12155
  • fix(ci): let a nightly's later test suites survive an earlier one's failure (fixes #12625) by @claudespice in #12627
  • fix(tests): wait for a partition to persist before snapshotting its plan (fixes #12645) by @grokspice in #12652
  • fix(object-store): bound an FTP and SFTP connection attempt end to end (fixes #12647) by @grokspice in #12655
  • test(iceberg): decide the Hadoop catalog test's backends by environment (fixes #12646) by @grokspice in #12665
  • fix(ci): give each E2E model job its own spiced ports (fixes #12419) by @grokspice in #12685
  • fix(cache): evict the Pingora cache down to max_size instead of only recording it (fixes #12688) by @grokspice in #12694
  • fix(cayenne): bound protected-snapshot compaction by the compaction memory pool by @sgrebnov in #12541
  • fix(ci): leave an incomplete sign-off pending, not failed (fixes #12741) by @grokspice in #12742
  • fix(telemetry): resolve duration histograms below a millisecond (fixes #12693) by @grokspice in #12699
  • fix(ci): bound every E2E job, so a wedged build cannot hold the queue (fixes #12717) by @grokspice in #12719
  • feat(testoperator): add new search benchmark datasets by @Jeadie in #12237
  • test(cayenne): name the small-file compaction tests after the path they take (fixes #12612) by @grokspice in #12740
  • fix(cli): bound an inference call by silence, not by total duration (fixes #12583) by @claudespice in #12589
  • fix(turso): store and read back the same set of types (fixes #12628) by @claudespice in #12633
  • fix(catalogs): keep a Glue database whose tables the include patterns select (fixes #12630) by @claudespice in #12638
  • fix(catalogs): apply a catalog's exclude patterns, not just its include (fixes #12636) by @claudespice in #12641
  • fix(cayenne): build a carry-forward rewrite from the classified manifest rows (fixes #12708) by @claudespice in #12711
  • fix(runtime): subtract an append dedup window as a multiset, not a set (fixes #12499) by @grokspice in #12513
  • bug: FTS exec drops absent columns and violates its declared schema (fixes #12228) by @Jeadie in #12245
  • bug: rrf() linear recency decay divides the document age by the decay window twice (fixes #12232) by @Jeadie in #12385
  • chore(deps): bump datafusion rev to spiceai-54 with outer-join unparser fix by @Jeadie in #12683
  • fix(ci): recognise sccache's startup-timeout wording as an unusable cache (fixes #12622) by @claudespice in #12788
  • fix(spiced): open the log with the startup banner by @bjchambers in #12615
  • fix(metrics): resolve S3 Vectors latency below a hundred milliseconds (fixes #12698) by @grokspice in #12702
  • fix(google-genai): bound one unterminated SSE event so a stalled endpoint cannot grow spiced (fixes #12600) by @grokspice in #12690
  • feat(cpu-budget): size a burstable pod from its CPU request, with an all-cores opt-out by @bjchambers in #12581
  • fix(ci): refuse a sign-off the branch's Makefile cannot run (fixes #12813) by @claudespice in #12815
  • test(postgres): say which readiness wait timed out and what it saw (fixes #12730) by @grokspice in #12731
  • fix(mssql): bound one connection attempt, so a stalled peer cannot pin a pool slot (fixes #12606) by @grokspice in #12733
  • fix(ci): ask whether the disk watcher runs before make writes to it (fixes #12734) by @grokspice in #12736
  • fix: delete three source files that no crate root declares (fixes #12735) by @grokspice in #12738
  • fix(telemetry): keep a startup-recorded gauge on the operator meter, so it reaches /metrics (fixes #12667) by @grokspice in #12754
  • fix(cloud-connect): pin rustls where the release call presents its identity (fixes #12760) by @grokspice in #12764
  • test(cloud-client): assert the redirect policy by behaviour against a live server (fixes #12509) by @grokspice in #12767
  • fix(search): decline a warm vector tier the accelerator cannot refill (fixes #12102) by @grokspice in #12768
  • fix(ci): build without the compiler cache when it cannot be reached (fixes #12770) by @grokspice in #12771
  • fix(json): end an array element where serde did, so bare scalars read (fixes #12782) by @grokspice in #12785
  • fix(cache): count an invalidation as an eviction, and export the counters before one fires (fixes #12687) by @grokspice in #12791
  • fix(ci): ask whether the runner can hold the build before starting one (fixes #12798) by @grokspice in #12799
  • fix(ci): size the cayenne property-test ceiling above the pool, not at it (fixes #12811) by @grokspice in #12814
  • fix(ci): bound every merge-queue-required job with timeout-minutes by @grokspice in #12817
  • deps: bump datafusion-table-providers to 894e279 (fixes #12585) by @bjchambers in #12663
  • fix(ci): take stale build output off the runners, not just report a full one (fixes #12800) by @grokspice in #12801
  • fix(cayenne): give the Turso metastore sidecars one pool over cayenne.db (fixes #12727) by @grokspice in #12804
  • fix(deps): drop the unreferenced ctor dev-dependency from data_components (fixes #12664) by @grokspice in #12819
  • fix(ci): decline a verdict when the sign-off run itself was signalled (fixes #12710) by @grokspice in #12724
  • fix(postgres): hold a resuming shared slot's ack floor for tables with no member by @bjchambers in #12676
  • refactor(layering): split the table-provider layers out of runtime by @bjchambers in #12661
  • build(deps): bump the github-actions-dependencies group across 3 directories with 7 updates by @app/dependabot in #12842
  • fix(spiced): make the crash handler more robust by @sgrebnov in #12834
  • fix(catalogs): apply the Cayenne catalog's include and exclude patterns (fixes #12766) by @grokspice in #12833
  • fix(search): decide a compound index's write fatality per half, not by OR (fixes #12826) by @grokspice in #12828
  • feat(cloud): organization context for spice cloud commands by @lukekim in #12515
  • perf(postgres catalog): skip metadata queries for schemas no include pattern can reach by @bjchambers in #12651
  • bug: S3 vector metadata conversion silently drops filterable metadata (fixes #12240) by @Jeadie in #12387
  • build(deps): bump nvidia/cuda from 13.3.0-cudnn-runtime-ubuntu24.04 to 13.3.1-cudnn-runtime-ubuntu24.04 in the docker-dependencies group by @app/dependabot in #12356
  • fix(runtime): keep serving when the working directory cannot be walked (fixes #6301) by @claudespice in #12803
  • fix(connectors): report an object-store timeout as a timeout, not as bad credentials (fixes #12793) by @claudespice in #12797
  • test(runtime): say which components were not ready when the wait times out (refs #12396) by @grokspice in #12827
  • fix(cayenne): measure tuner memory pressure as unreclaimable demand (fixes #12531) by @sgrebnov in #12623
  • Include v2.1.3 and 2.1.4 in SECURITY.md by @sgrebnov in #12497
  • fix(search): leave the stored rows in place when a delete cannot be applied (fixes #12822) by @grokspice in #12825
  • fix(google-genai): resume the SSE scan where it stopped, not at the buffer start (fixes #12689) by @grokspice in #12713
  • fix(json): report a malformed JSON array element instead of dropping the rest of the file (fixes #12755) by @claudespice in #12777
  • fix(runtime): honour a declared type's precision instead of narrowing it (fixes #12756) by @claudespice in #12774
  • fix(cayenne): drop the partition-value guard that key encoding made unreachable (fixes #12616) by @claudespice in #12753
  • fix(runtime): pin the catalog-acceleration contract in both feature configurations (fixes #12743) by @claudespice in #12752
  • fix(cli): report an answer the model stopped early, instead of printing it as whole (fixes #12596) by @grokspice in #12715
  • fix(runtime): scope query jobs and active queries to the principal that submitted them by @phillipleblanc in #12841
  • Compute all metrics@k for all 0 < k <= n during search quality metrics. by @Jeadie in #12521
  • task: Add a truncate to huggingface and file embedding providers by @Jeadie in #12620
  • fix(cache): never serve a result whose tables changed after it read them by @bjchambers in #12703
  • test(cayenne): cover datalake-tier statistics, pruning, and promotion triggers by @sgrebnov in #12847
  • docs(ci): warn that re-running enforce-pull-with-spice replays a stale payload (fixes #12809) by @grokspice in #12810
  • fix(cayenne): bound the maintained-aggregate index by memory budget, and let a stale registry recover by @lukekim in #12573
  • fix(runtime): only initialize accelerators for the datasets a reload applies by @phillipleblanc in #12872
  • feat: promote BYOC and Cloud Connect changes to trunk by @phillipleblanc in #12852
  • fix(flight): resolve per-request settings from the live app by @phillipleblanc in #12873
  • fix(cli): keep polling when the token exchange has not seen the auth code yet by @phillipleblanc in #12871
  • feat(cayenne): inline a small whole-table refresh into the metastore by @lukekim in #12367
  • ci: upgrade spiceio setup action to v0.8.0 by @lukekim in #12885
  • fix(runtime): measure the CDC prefetch backlog, and stop its byte counter wrapping by @lukekim in #12675
  • fix(turso): keep a reloaded file-accelerated dataset queryable by @phillipleblanc in #12882
  • fix(query): preserve expression ordering across partition wrappers by @Jeadie in #12854
  • fix(runtime): report every start-time-only runtime.* section a reload changes by @phillipleblanc in #12874
  • fix(search): handle null embeddings in vector writes and JIT search by @Jeadie in #12855
  • test(embeddings): truncate over-length inputs in the MiniLM embed spicepods by @Jeadie in #12856
  • fix(search): Improve search benchmarking DX and fix some vector index names by @Jeadie in #12892
  • test(search): dispatch all MTEB search variants by @Jeadie in #12850
  • fix(runtime): stop a superseded scheduler incarnation from claiming the heartbeat key by @phillipleblanc in #12851
  • fix: Ensure OTel ingest materializes missing/null dimension columns by @peasee in #12087
  • feat(cloud-connect): apply a component-only Spicepod deployment in place by @phillipleblanc in #12895
  • feat(cli): typed login sessions and explicit connect organization selection by @phillipleblanc in #12912
  • refactor: make each table wrapper a typed layer that answers where a walk goes by @bjchambers in #12891
  • feat(runtime): put every query's trace id on its log records by @lukekim in #12610
  • feat(cayenne): bound the SUM of the per-table PK keyset caches by @lukekim in #12802
  • fix(cache): read and expire a Pingora entry under one hold of its shard (fixes #12832) by @grokspice in #12839
  • fix: Update Search integration test snapshots by @Jeadie in #12707
  • fix(runtime): invalidate localpod children's cached results on parent refresh by @krinart in #12897
  • fix(cayenne): use valid snapshot IDs for deferred appends by @Jeadie in #12853
  • fix(ci): New branch for each push-snap-changes (only affects integration_search.yml) by @Jeadie in #12684
  • fix(search): make chunked embedding and offset columns nullable (#12778) by @Jeadie in #12783
  • feat(cayenne): charge scan materialization to the query memory pool by @lukekim in #12759
  • fix(cache): run the Pingora invalidation scan off the calling runtime worker (fixes #12806) by @grokspice in #12808
  • fix(cache): count the removals the Pingora engine performs itself (fixes #12792) by @grokspice in #12830
  • fix(cayenne): reserve append sequence for partitioned upsert appends (#12779) by @Jeadie in #12784
  • test(cayenne): prove the keyset degrade releases each shard as it converts by @lukekim in #12790
  • perf(postgres catalog): resolve a schema's table schemas in one query (#12106) by @bjchambers in #12886
  • fix(vortex): expose segment cache metrics on scrape by @phillipleblanc in #12944
  • refactor: point connector imports at the crates that actually own them by @bjchambers in #12925
  • fix(postgres): rebuild the acceleration when a replication slot's history is gone by @bjchambers in #12922
  • fix(cayenne)!: only an explicit cayenne_tuning: adaptive enables the closed loop by @lukekim in #12949
  • fix(dev-tools): show merge-queue and conflict state as labels in scripts/signoff mine by @Jeadie in #12924
  • test: cover warm-index delete paths across backends (#11964) by @Jeadie in #12635
  • fix(cayenne): fractional proptest scaling + batch timestamp-partition test inserts by @Jeadie in #12796
  • Helpful tool to track what users/bots have got done lately by @Jeadie in #12603
  • Release notes housekeeping by @krinart in #12977
  • build(deps): bump serde_with from 3.20.0 to 3.21.0 by @app/dependabot in #11969
  • refactor: make runtime's re-export shims crate-visible by @bjchambers in #12969
  • fix(runtime): surface OTel metric tables with duplicate columns, and count unsupported metric types as rejected by @peasee in #12923
  • fix: Update Search integration test snapshots by @app/github-actions in #12979
  • Make signoff.yml more searchable. by @Jeadie in #12392
  • bug: Support search UDTFs in SQL function components by @Jeadie in #12919
  • docs: document the stacked-PR workflow, with a tested restack helper by @bjchambers in #12951
  • fix(llms): fall back to pytorch_model.bin for embeddings without safetensors by @Jeadie in #12971
  • feat(monitoring): improve the Datadog dashboard for multi-replica and Kubernetes deployments by @sgrebnov in #12972
  • Charge the query memory pool for concurrent Vortex split decodes by @lukekim in #12940
  • docs(release-notes): write release notes in Simplified Technical English by @lukekim in #12947
  • refactor: narrow the DataConnector trait off the runtime's types by @bjchambers in #12993
  • fix(cayenne): compact a DDL-created partition on an interval, not only on write (fixes #12617) by @grokspice in #12757
  • fix(cayenne): hand out a pooled Turso connection in autocommit (refs #12820) by @grokspice in #12821
  • fix: fail the lint gate on a source file no crate root declares (fixes #12737) by @grokspice in #12744
  • fix(search): stage a full refresh of the memory vector tier, so dropped rows leave it (refs #12413) by @grokspice in #12823
  • fix(graphql): keep the configured schema when a page has no rows (fixes #13004) by @claudespice in #13016
  • fix(runtime): register task_history before embeddings/rerankers load by @Jeadie in #12978
  • test(postgres): converge the catalog on source DDL, and warn when it selects nothing by @bjchambers in #12988
  • fix(cayenne): budget for catalogs in the Cayenne memory classification by @bjchambers in #13027
  • fix(cayenne): hold primary keys committed while the existence index is checked out by @lukekim in #13019
  • feat(search): push SQL filters down into tantivy full-text search by @Jeadie in #12812
  • fix(cayenne): serve the maintained count Inexact while its delta is queued (fixes #12824) by @grokspice in #12829
  • fix: Update Search integration test snapshots by @app/github-actions in #13060
  • fix(testoperator benchmarks): benchmark fixes by @krinart in #13012
  • fix(runtime): stop query_active_count drifting up when queries share a request (fixes #12883) by @claudespice in #13034
  • chore(deps): bump model2vec-rs for fast WordPiece tokenizer by @Jeadie in #12986
  • ci(cayenne-doc): render diagrams locally with mermaid-cli, and fix the diagram that has been failing the build for a month by @bjchambers in #13063
  • feat(monitoring): improve results cache panels on the Datadog dashboard by @sgrebnov in #13066
  • feat(cayenne)!: one process-wide Vortex segment cache instead of a cache per table by @bjchambers in #12983
  • fix(connectors): keep the projected schema when a query returns no rows (fixes #13015) by @claudespice in #13078
  • fix(deps): bump the datafusion pin past the merged unparser fixes (fixes #12406) by @claudespice in #13083
  • fix(cache): compact a sliced result before caching it (fixes #12921) by @claudespice in #13043
  • refactor(cdc): give the sidecar checkpoint stores a below-runtime interface by @bjchambers in #13045
  • fix(cayenne): re-baseline the maintained row count when a promotion folds a delete tombstone (fixes #12846) by @claudespice in #12998
  • fix(acceleration): stop an engine-required type rewrite reading as a stale acceleration schema (fixes #13014) by @claudespice in #13074
  • fix(udfs): return NULL for a vector distance that is not defined (refs #11263) by @claudespice in #13091
  • fix(cayenne): refuse a data directory that contains the metastore (fixes #13055) by @claudespice in #13101
  • fix(json): report content after a JSON array instead of dropping it (fixes #12786) by @claudespice in #13097
  • fix(runtime): bound the spicepod apply so an unloadable dataset cannot wedge it (fixes #12862) by @claudespice in #13095
  • fix(catalogs): apply the Glue catalog's exclude patterns (fixes #12634) by @claudespice in #13103
  • fix(metrics): make component metrics and tests more robust by @sgrebnov in #13094
  • feat(cache)!: ship the Pingora cache engine as an Enterprise-only feature by @lukekim in #13000
  • fix: Update benchmark snapshots by @app/github-actions in #13056
  • fix(postgres): compare CDC positions against what the slot can stream, not what it retains by @bjchambers in #12990
  • docs(cayenne): compress the changelog, and give it a rule for what earns a row by @bjchambers in #13067
  • test: remove a test's container when it is done with it, including on failure by @bjchambers in #13123
  • fix(flight): record one metric sample per Flight RPC (fixes #12844) by @claudespice in #13112
  • feat(drasi): forward CDC changes and runtime tables to a Drasi source (Alpha) by @lukekim in #12653
  • fix(bench): time the engine instead of the results cache, and validate ClickBench by @lukekim in #13150
  • refactor(connector): retype the DataConnector surface to DatasetSpec by @bjchambers in #13096
  • bug: SQL-tier function body does not support named arguments (=>) for search UDTFs (fixes #12898) by @Jeadie in #12920
  • fix(cache): compact the sliced and wide results that compaction previously skipped by @sgrebnov in #13176
  • docs(stacked-prs): correct when a restack forfeits the sign-off by @bjchambers in #13130
  • fix(postgres): load a provably empty CDC acceleration through its snapshot bootstrap by @bjchambers in #13175
  • fix(cayenne): keep Arrow timestamp units (Vortex supports ns) by @lukekim in #13180
  • Cloud Connect: enrollment and identity foundation by @phillipleblanc in #13181
  • refactor(model): give the model-provider contracts a home below llms by @bjchambers in #13201
  • Fix runtime lint with zero features by @krinart in #13208
  • fix(benchmarks): BigQuery + Snowflake fixes + updated snapshots by @krinart in #13136
  • Revert "fix(search): decline a warm vector tier the accelerator cannot refill (fixes #12102)" (#12768) by @Jeadie in #13041
  • fix(snapshots): don't bootstrap the snapshot file_create just discarded by @lukekim in #13179
  • Declare the CPU entitlement to Vortex at startup by @sgrebnov in #13173
  • fix(mysql): fix net_write_timeout session syntax and extend transient replication errors by @ewgenius in #13178
  • fix(postgres): classify EOF and server termination errors as transient in CDC replication by @ewgenius in #13163
  • feat(testoperator): support customer-supplied datasets in run search by @Jeadie in #12982
  • Add PDF page splitter and FinanceBench staging job (#12858) by @Jeadie in #12984
  • fix(cayenne): frame the persisted PK bloom with the probe function that filled it (fixes #13137) by @claudespice in #13153
  • refactor(layering): move the connectors below the runtime by @bjchambers in #13166
  • feat(cli): manage the Cloud Connect service with launchd on macOS by @phillipleblanc in #13203
  • Support local rerankers from text-embeddings-inference by @Jeadie in #12929
  • fix(catalog): make the PostgreSQL catalog's errors and warnings actionable by @bjchambers in #13199
  • fix(cloud-connect): look again when a lock create reports the entry missing by @phillipleblanc in #13231
  • Skip DynamoDB in scheduled benchmarks by @ewgenius in #13222
  • Populate the file metadata cache with Vortex footers at write time by @sgrebnov in #13228
  • perf(cayenne): give the PK filter a cache-line layout, and the bit count it asks for by @bjchambers in #13219
  • fix(mysql): rebuild a purged-position acceleration atomically instead of emptying it (fixes #12967) by @claudespice in #13023
  • fix(cloud-connect): heartbeat restart-required, attachment by app id, and this crate's integration tests in the gate by @phillipleblanc in #13234
  • fix(search): join all of a dataset's vector indexes on one VectorScanTableProvider by @krinart in #13209
  • Validate vector search parameters before SQL query by @lesbass in #12253
  • feat(helm): support customizing Deployment strategy and StatefulSet updateStrategy by @sgrebnov in #13249
  • fix(postgres): recover from a replication slot lost while streaming, and state what each slot costs by @bjchambers in #13221
  • fix(cayenne): stop a partitioned acceleration reporting a schema change it never applied (fixes #12999) by @claudespice in #13057
  • feat(cloud-connect): name the local spicepod a cloud-managed instance serves or ignores by @phillipleblanc in #13262
  • fix(snowflake): keep NUMBER precision and scale during schema discovery by @phillipleblanc in #13272
  • fix(secrets): check secret references where the components resolve them by @peasee in #13265
  • docs(criteria): sign off the PostgreSQL Catalog Connector at Beta by @bjchambers in #13235
  • fix(cloud-connect): resolve locked service state through the retained directory descriptor (fixes #13204) by @claudespice in #13292
  • chore(deps): upgrade iceberg-rust to v0.10.0 by @krinart in #13189
  • fix(cloud-connect): fix Windows build of identity state-file helpers by @sgrebnov in #13308
  • fix(cayenne): normalize append de-duplication types by @ewgenius in #13200
  • feat(cli): unify Spice Cloud enrollment and service workflows by @phillipleblanc in #13326
  • feat(postgres): native upsert delivery for durable write-back by @Jeadie in #13323
  • feat(cli): create an unattached Cloud Connect project by @phillipleblanc in #13333
  • fix(cayenne): exclude protected snapshots above the delete fence from subset compaction by @krinart in #13343
  • fix(cli): resolve a Cloud Connect project's data-plane region from its config by @krinart in #13370
  • fix(cli): keep a granted Spice Cloud login when the identity endpoint is silent by @bjchambers in #13376
  • fix(duckdb): fix concurrent-query failures after a replace_file swap with multiple DuckDB files by @Jeadie in #13383

*Full Changelog: https://github.com/spiceai/spiceai/compare/v2.1.0...v2.2.0

Spice v2.1.5 (Aug 12, 2026)

ยท 5 min read
Viktor Yershov
Senior Software Engineer at Spice AI

Spice v2.1.5 is now available! ๐Ÿ› ๏ธ

Spice v2.1.5 is a patch release focused on dependable cached data and predictable operation under load. Cached queries now reflect data changes more reliably, Cayenne workloads stay within configured memory limits, health checks remain responsive while cached results are updated, and cache dashboards provide a more complete view of activity.

What's New in v2.1.5โ€‹

Cached Queries Stay Fresh as Data Changesโ€‹

Cached results are now cleared reliably after refreshes, writes, retention changes, and updates to dependent local datasets. Expired entries are removed promptly, and entries for data that is no longer part of a Cayenne dataset are not reused by later queries.

These improvements prevent a completed data change from being followed by an older cached answer. No configuration changes are required.

More Predictable Cayenne Behavior Under Heavy Loadโ€‹

Cayenne now keeps track of the memory needed to prepare query results, including when several parts of a query are prepared at once. Multiple accelerated tables also share available memory instead of each planning as though it were the only table in the deployment.

Large and concurrent workloads are therefore less likely to exhaust the available memory. When a query cannot fit within the configured limit, it fails cleanly instead of putting the entire service at risk. Operators can also limit how much work one dataset does at once when it needs a smaller memory footprint, without slowing every query.

Health Checks Remain Responsive During Cache Updatesโ€‹

Refreshing or writing a dataset with many cached results no longer holds up Spice while it finds old answers that need to be cleared. Health checks and other requests can continue during this work, reducing avoidable service restarts under load.

More Trustworthy Cache Dashboardsโ€‹

Cache dashboards now show total space, space in use, stored results, requests, and successful reuse whenever the dashboard is refreshed, including for new or lightly used datasets. Counts for expired results, automatic size cleanup, and cleanup after data changes are also reported consistently, so a zero value represents no activity rather than missing information.

Contributorsโ€‹

Breaking Changesโ€‹

No breaking changes.

Cookbook Updatesโ€‹

No new cookbook recipes.

The Spice Cookbook includes more than 100 recipes to help you get started with Spice quickly and easily.

Upgradingโ€‹

To upgrade to v2.1.5, use one of the following methods:

CLI:

spice upgrade

Homebrew:

brew upgrade spiceai/spiceai/spice

Docker:

Pull the spiceai/spiceai:2.1.5 image:

docker pull spiceai/spiceai:2.1.5

For available tags, see DockerHub.

Helm:

helm repo update
helm upgrade spiceai spiceai/spiceai --version 2.1.5

AWS Marketplace:

Spice is available in the AWS Marketplace.

What's Changedโ€‹

Changelogโ€‹

  • fix: arrow IndexedMemTable serves stale results after DML/retention/sync (fixes #11262) by @claudespice in #11532
  • fix(cache): evict the Pingora cache down to max_size instead of only recording it (fixes #12688) by @grokspice in #12694
  • fix(cache): count an invalidation as an eviction, and export the counters before one fires (fixes #12687) by @grokspice in #12791
  • fix(cache): never serve a result whose tables changed after it read them by @bjchambers in #12703
  • Remove unnecessary allocations from results-cache and hot conversion paths by @phillipleblanc in #11895
  • fix(cache): read and expire a Pingora entry under one hold of its shard (fixes #12832) by @grokspice in #12839
  • fix(runtime): invalidate localpod children's cached results on parent refresh by @krinart in #12897
  • fix(cache): run the Pingora invalidation scan off the calling runtime worker (fixes #12806) by @grokspice in #12808
  • fix(cache): count the removals the Pingora engine performs itself (fixes #12792) by @grokspice in #12830
  • feat(cayenne): charge scan materialization to the query memory pool by @lukekim in #12759
  • feat(cayenne): bound the SUM of the per-table PK keyset caches by @lukekim in #12802
  • Charge the query memory pool for concurrent Vortex split decodes by @lukekim in #12940
  • fix(vortex): invalidate retired segment cache entries by @phillipleblanc in #12943
  • fix(vortex): expose segment cache metrics on scrape by @phillipleblanc in #12944

*Full Changelog: https://github.com/spiceai/spiceai/compare/v2.1.4...v2.1.5

Spice v2.1.4 (Aug 5, 2026)

ยท 2 min read
Sergei Grebnov
Senior Software Engineer at Spice AI

Spice v2.1.4 is now available! ๐Ÿ› ๏ธ

Spice v2.1.4 is a patch release that improves DuckDB acceleration and runtime stability: datasets with UTC timestamp columns, such as Iceberg tables, now load successfully when accelerated with DuckDB, retention policies run reliably, and the runtime is more resilient under heavy query load.

What's New in v2.1.4โ€‹

DuckDB Acceleration Works with Iceberg Timestampsโ€‹

A dataset with a UTC timestamp column โ€” for example, any Iceberg timestamptz column โ€” could previously fail to load when accelerated with DuckDB, leaving the dataset unhealthy and unqueryable. These datasets now load and become ready normally, with no configuration changes needed.

Reliable Retention Policies on DuckDBโ€‹

Retention policies now apply cleanly on DuckDB-accelerated datasets, including policies that combine a time window with an additional condition. Expired rows are evicted on every retention interval, keeping accelerated data fresh and storage bounded.

Improved Runtime Stabilityโ€‹

The runtime is now more robust when queries are cancelled โ€” whether by a client disconnecting, a timeout, or a new refresh superseding an in-flight read. A rare crash in this path has been eliminated.

Contributorsโ€‹

Breaking Changesโ€‹

No breaking changes.

Cookbook Updatesโ€‹

No new cookbook recipes.

The Spice Cookbook includes more than 100 recipes to help you get started with Spice quickly and easily.

Upgradingโ€‹

To upgrade to v2.1.4, use one of the following methods:

CLI:

spice upgrade

Homebrew:

brew upgrade spiceai/spiceai/spice

Docker:

Pull the spiceai/spiceai:2.1.4 image:

docker pull spiceai/spiceai:2.1.4

For available tags, see DockerHub.

Helm:

helm repo update
helm upgrade spiceai spiceai/spiceai --version 2.1.4

AWS Marketplace:

Spice is available in the AWS Marketplace.

What's Changedโ€‹

Changelogโ€‹

  • chore(deps): bump datafusion and table-providers for the DuckDB timezone and retention fixes (2.1 backport) by @phillipleblanc in #12546
  • fix(deps): bump the Vortex pin to pick up the task-cancellation fix by @phillipleblanc in #12547

*Full Changelog: https://github.com/spiceai/spiceai/compare/v2.1.3...v2.1.4

Spice v2.1.3 (Aug 4, 2026)

ยท 5 min read
Sergei Grebnov
Senior Software Engineer at Spice AI

Spice v2.1.3 is now available! ๐Ÿ› ๏ธ

Spice v2.1.3 is a patch release focused on resource efficiency: explicit CPU sizing with the new runtime.cpu.cores setting, more query memory for Cayenne deployments, and improved memory and crash diagnostics. It also fixes Cayenne acceleration of Iceberg datasets with timestamptz columns and restores WHERE filters on federated LEFT/RIGHT JOIN queries.

What's New in v2.1.3โ€‹

CPU Sizing with runtime.cpu.coresโ€‹

The new runtime.cpu.cores setting controls how many cores the runtime targets. Thread pools, query partitioning, and accelerator concurrency are all derived from it.

runtime:
cpu:
cores: 4 # `auto` (default) detects. Accepts 4, 3.5, 3500m

Also available as --cpu-cores and SPICE_CPU_CORES (precedence: flag > environment > Spicepod).

This is most useful on large, shared nodes. A pod that sets resources.requests.cpu without a CPU limit exposes no cgroup quota, so the runtime sizes itself for every core on the node rather than its allocated share. Setting the entitlement aligns parallelism and memory footprint with the CPU the pod actually receives.

The effective value, its source, and the derived sizing are logged at startup and exported as the spiced_cpu_budget_cores gauge.

More Query Memory for Cayenne Deploymentsโ€‹

The Cayenne compaction memory pool is now reserved only for accelerations that can compact into it: file mode with a small-write refresh profile. Other deployments, including refresh_mode: full, keep the full memory limit available to queries โ€” up to 6.4 GiB on a 32 GiB limit, with no configuration change.

Memory budgets are now derived from the process's own cgroup limit rather than total host memory.

Diagnosticsโ€‹

Three new gauges report memory in use: query_memory_pool_used_bytes, cayenne_compaction_memory_pool_used_bytes, and process_resident_memory_bytes.

Memory pool refusals now return ResourcesExhausted and HTTP 503, distinguishing them from query errors.

Fatal native signals (SIGSEGV, SIGBUS, SIGILL, SIGFPE) report the signal, faulting address, and thread before exit, so a crash can be diagnosed from logs.

Fixed a bug where setting runtime.task_history.enabled: false also disabled every query metric โ€” query_duration_ms, query_execution_duration_ms, query_executions, query_failures, query_returned_rows, and query_returned_bytes. These are now reported regardless of the task history setting.

Cayenne Acceleration of Iceberg timestamptz Columnsโ€‹

Accelerating an Iceberg dataset with a timestamptz column using the Cayenne engine previously failed during the refresh write with an error resolving the time zone +00:00. Iceberg maps every timestamptz column to the fixed-offset Arrow time zone +00:00, which the file writer could not resolve when building column statistics. Fixed-offset time zones (ยฑHH:MM, ยฑHHMM, and ยฑHH) are now resolved wherever time zones are handled, so these datasets accelerate correctly.

Federated Outer Join Filtersโ€‹

A federated query combining a LEFT JOIN with a WHERE filter on the left table previously returned all rows instead of the filtered rows: when the query was pushed down to the data source or accelerator, the filter was folded into the JOIN ON clause, where it no longer filters the left side (RIGHT JOIN was affected symmetrically). Filters now stay on the side of the join they came from, so these queries return the correct rows.

Contributorsโ€‹

Breaking Changesโ€‹

No breaking changes.

Cookbook Updatesโ€‹

No new cookbook recipes.

The Spice Cookbook includes more than 100 recipes to help you get started with Spice quickly and easily.

Upgradingโ€‹

To upgrade to v2.1.3, use one of the following methods:

CLI:

spice upgrade

Homebrew:

brew upgrade spiceai/spiceai/spice

Docker:

Pull the spiceai/spiceai:2.1.3 image:

docker pull spiceai/spiceai:2.1.3

For available tags, see DockerHub.

Helm:

helm repo update
helm upgrade spiceai spiceai/spiceai --version 2.1.3

AWS Marketplace:

Spice is available in the AWS Marketplace.

What's Changedโ€‹

Changelogโ€‹

  • feat(runtime): size every CPU-derived pool from the CPU entitlement by @bjchambers in #12276
  • fix(runtime): carve the Cayenne compaction memory pool only when a dataset can compact into it by @sgrebnov in #12326
  • fix(runtime): size memory budgets from the process's own cgroup limit by @lukekim in #12263
  • fix(telemetry): read the cgroup CPU quota along the whole cgroup path by @sgrebnov in #12300
  • feat(runtime): expose the memory numbers that explain an OOM as gauges by @lukekim in #12195
  • fix(runtime): report a memory-pool refusal as ResourcesExhausted and answer it with 503 by @sgrebnov in #12289
  • fix(cayenne): the write-concurrency raise must respect the memory brake by @lukekim in #12317
  • feat(spiced): report fatal signals before exit by @sgrebnov in #12334
  • fix: report query metrics when task history is disabled by @sgrebnov in #12227
  • chore(deps): repoint vortex at the 2.1 fixed-offset timezone fix by @phillipleblanc in #12455
  • chore(deps): bump datafusion rev for outer-join unparser fix by @Jeadie in #12460

*Full Changelog: https://github.com/spiceai/spiceai/compare/v2.1.2...v2.1.3

Spice v2.1.2 (Jul 28, 2026)

ยท 3 min read
Sergei Grebnov
Senior Software Engineer at Spice AI

Spice v2.1.2 is now available! ๐Ÿ› ๏ธ

Spice v2.1.2 is a patch release focused on improving the DuckDB data accelerator. It upgrades the DuckDB engine to v1.5.5 and introduces the on_full_refresh parameter, giving file-mode DuckDB accelerations compact, predictable disk usage across repeated full refreshes.

What's New in v2.1.2โ€‹

Bounded DuckDB Acceleration File Growth with on_full_refreshโ€‹

File-mode DuckDB accelerations using refresh_mode: full now reclaim disk space on every refresh, keeping the database file compact and disk usage predictable for long-running deployments. Each full refresh bulk-loads a fresh copy of the data, and the new on_full_refresh modes ensure the space held by prior copies is returned rather than accumulating in the file.

The new on_full_refresh acceleration parameter controls how disk space is reclaimed after each full refresh:

acceleration:
engine: duckdb
mode: file
refresh_mode: full
params:
duckdb_file: /data/shared.duckdb
on_full_refresh: replace_file # default: reuse_file
  • reuse_file (default): Existing behavior โ€” refresh into the existing database file.
  • replace_file: Each full refresh streams data into a fresh staging database file, carries over every other object sharing the file (other datasets' tables, views, indexes, and Spice metadata), checkpoints it, and atomically replaces the configured file. Queries are never interrupted โ€” in-flight queries drain against the old file while new queries see the new file โ€” and space is fully reclaimed on every refresh.
  • checkpoint_file: After each refresh, run a CHECKPOINT in place, escalating to FORCE CHECKPOINT when concurrent transactions block the plain attempt (waiting for in-flight transactions; never aborting them).

DuckDB 1.5.5โ€‹

The DuckDB engine is upgraded from v1.5.3 to v1.5.5, bringing the latest upstream stability fixes.

Contributorsโ€‹

Breaking Changesโ€‹

No breaking changes.

Cookbook Updatesโ€‹

No new cookbook recipes.

The Spice Cookbook includes more than 100 recipes to help you get started with Spice quickly and easily.

Upgradingโ€‹

To upgrade to v2.1.2, use one of the following methods:

CLI:

spice upgrade

Homebrew:

brew upgrade spiceai/spiceai/spice

Docker:

Pull the spiceai/spiceai:2.1.2 image:

docker pull spiceai/spiceai:2.1.2

For available tags, see DockerHub.

Helm:

helm repo update
helm upgrade spiceai spiceai/spiceai --version 2.1.2

AWS Marketplace:

Spice is available in the AWS Marketplace.

What's Changedโ€‹

Changelogโ€‹

  • feat(duckdb): on_full_refresh: replace_file โ€” full refresh into a new database file, atomically replaced by @lukekim in #12135
  • feat(duckdb): 'on_full_refresh: checkpoint_file' to bound acceleration file growth by @sgrebnov in #12139

*Full Changelog: https://github.com/spiceai/spiceai/compare/v2.1.1...v2.1.2

Spice v2.1.1 (Jul 21, 2026)

ยท 3 min read
Jack Eadie
Token Plumber at Spice AI

Spice v2.1.1 is now available! ๐Ÿ› ๏ธ

Spice v2.1.1 is a patch release focused on reliability and performance. It resolves a possible deadlock that affected datasets with partitioned Cayenne accelerators, caches empty SQL result sets so repeat queries are served from cache, speeds up repeated queries on multi-file datasets, and restores Bedrock embedding provider parameters.

What's New in v2.1.1โ€‹

Cayenne Partitioned Dataset Deadlock Fixโ€‹

Cayenne datasets configured with partition_by could deadlock during their initial refresh and never become ready. Non-partitioned tables and small partitioned tables were unaffected. The root cause was a deadlock between the partition routing and the global Vortex encode budget introduced in v2.1.0.

Cayenne Zero-Row Append Refresh Stabilityโ€‹

An idle append refresh, one where no source rows are newer than the current max(time_column), wrote no Vortex files, so the expected snapshot directory was never created. The subsequent fsync on that directory failed with ENOENT, marking the dataset unhealthy. The fix skips the snapshot sequence record and protected-snapshot publish when the write carried no rows.

Caching of Empty Result Setsโ€‹

The SQL results cache now stores empty (zero-row) result sets. Queries that legitimately return no rows (e.g. WHERE 1=0, LIMIT 0) are now served from the results cache on subsequent requests instead of being re-executed against the source, reducing planning and query latency for these patterns.

Faster Repeated Queries on Multi-File Datasetsโ€‹

Object store datasets using parquet now cache Parquet footer statistics across queries. This reduces the frequency of Parquet footer parsing during planning, subsequently heavily reducing planning latency for certain query patterns (e.g. COUNT(*)).

Embedding Parameter Regression Fixesโ€‹

v2.1.0 introduced explicit definitions across embedding component parameters (i.e. .embeddings[].params). This introduced regressions for AWS Bedrock parameters truncation and truncation_mode that caused panics.

Contributorsโ€‹

Breaking Changesโ€‹

No breaking changes.

Cookbook Updatesโ€‹

No new cookbook recipes.

The Spice Cookbook includes more than 100 recipes to help you get started with Spice quickly and easily.

Upgradingโ€‹

To upgrade to v2.1.1, use one of the following methods:

CLI:

spice upgrade

Homebrew:

brew upgrade spiceai/spiceai/spice

Docker:

Pull the spiceai/spiceai:2.1.1 image:

docker pull spiceai/spiceai:2.1.1

For available tags, see DockerHub.

Helm:

helm repo update
helm upgrade spiceai spiceai/spiceai --version 2.1.1

AWS Marketplace:

Spice is available in the AWS Marketplace.

What's Changedโ€‹

Changelogโ€‹

  • fix(cache): cache empty (zero-row) SQL result sets by @bjchambers in #11699
  • fix(cayenne): zero-row append refresh fails with "No such file or directory" by @sgrebnov in #11710
  • feat(file): cache ListingTable file statistics to avoid per-query footer re-parse by @phillipleblanc in #11793
  • fix(embeddings): restore params broken by #10853 by @Jeadie in #11788
  • fix(cayenne): partitioned datasets deadlock against the global encode budget and never become ready by @Jeadie in #11825

Full Changelog: https://github.com/spiceai/spiceai/compare/v2.1.0...v2.1.1

Spice v2.1.0 (Jul 9, 2026)

ยท 36 min read
Jack Eadie
Token Plumber at Spice AI

Spice v2.1.0 is now available! ๐ŸŽ‰

Spice v2.1.0 is the next minor release of Spice, headlined by high-throughput Cayenne CDC, scaling and resilience improvements to PostgreSQL logical replication, expanded distributed query with Iceberg catalog scans and broadcast joins, and the upgrade to DataFusion v54 (including v53), Arrow v58.3, and Vortex v0.74. The release also adds experimental adaptive self-tuning for the Cayenne accelerator, distributed GLM inference, and a range of security, search, and connector improvements.

Highlights in v2.1.0 include:

  • High-Throughput Cayenne CDC โ€” in-memory CDC tier, dedicated compaction runtime, and write-path optimizations that cut replication lag on high-volume CDC workloads
  • PostgreSQL Replication at Scale โ€” multiple changes-mode datasets share a single replication slot, unchanged-TOAST recovery, and resilient reconnects across rolling deploys
  • Distributed Query โ€” distributed Ballista scans of Iceberg catalog tables, broadcast joins for small dimension tables, and shared scheduler job state with failover
  • DataFusion v54 โ€” upgrade to DataFusion v54 (folding in v53), Arrow v58.3, and Vortex v0.74, bringing faster joins, scans, and planning
  • Adaptive Self-Tuning (Experimental) โ€” opt-in closed-loop tuning and maintained aggregates that adapt Cayenne to hardware, schema, and live workload

What's New in v2.1.0โ€‹

High-Throughput Cayenne CDCโ€‹

A major focus of v2.1 is Spice Cayenne write-path throughput for change-data-capture (HTAP) workloads:

  • In-Memory CDC Tier: A new in-memory CDC tier and follow-ups cut replication lag on hot upsert tables, with bounded mem-tier checkpointing and O(1) per-scan deletion views, plus a two-phase off-fence checkpoint on the ingest path.
  • Dedicated Compaction Runtime: A dedicated compaction runtime with CDC pipelining and protected snapshots isolates compaction from query and ingest paths, with parallelized deletion-vector writes, per-batch directory-barrier coalescing, and size-aware parallel encode for protected-snapshot compaction.
  • Incremental Protected Snapshot Compaction: Incremental compaction of protected snapshots (used in Cayenne's merge-on-read deletion index) reduces disk usage and improves query performance.
  • Smaller WAL & Metadata-Only Publish: cayenne_insert_record table IDs are stored as 16-byte raw-UUID BLOBs, cutting CDC WAL volume ~34%; upsert commits publish metadata-only, dropping per-key insert records; transient staged CDC deltas are light-encoded.
  • Delta-Write Encoding Levels: A new cayenne_delta_encoding setting (default auto) selects delta-write encoding, and cayenne_compression_strategy: zstd is now fully wired.
  • In-Memory CDC Sharding: PK-hash intra-apply sharding parallelizes in-memory CDC apply.
  • Scan Safety Under Write: In-flight scans are ref-counted so snapshot GC can't delete Vortex files mid-read; in-RAM scan parallelism, query admission control, and sound scan output ordering improve read behavior under sustained CDC.

Delta-write encoding effort and Vortex compression are tunable per accelerator. cayenne_delta_encoding: auto (the default) size-gates fresh CDC/append writes โ€” small deltas use a light scheme and are re-encoded during compaction โ€” or pin an explicit level 0..10 (7 is the full default cascade); cayenne_compression_strategy selects the Vortex compression:

acceleration:
engine: cayenne
refresh_mode: changes
params:
cayenne_delta_encoding: auto # 'auto' (default), or pin a level 0..10 (7 = full cascade)
cayenne_compression_strategy: zstd # 'btrblocks' (default) or 'zstd'

Change Data Capture & HTAPโ€‹

PostgreSQL logical replication (CDC, refresh_mode: changes, introduced in v2.0) gets significant scaling and resilience work in v2.1:

  • Shared Replication Slot: Multiple refresh_mode: changes PostgreSQL datasets on the same connection can name the same pg_replication_slot to share a single replication slot, walsender decoder, and publication, with decoded changes multiplexed by (schema, table) to each dataset. This collapses the slot count from one-per-dataset to one โ€” staying well under Postgres's default max_replication_slots = 10.
datasets:
- from: postgres:public.orders
name: orders
params:
pg_db: mydb
pg_replication_slot: spice_cdc # shared slot name
acceleration:
refresh_mode: changes
- from: postgres:public.customers
name: customers
params:
pg_db: mydb
pg_replication_slot: spice_cdc # same name -> one slot, walsender & publication
acceleration:
refresh_mode: changes
  • Unchanged-TOAST Recovery: Under REPLICA IDENTITY FULL, when an UPDATE leaves a large TOASTed column unchanged, pgoutput sends an "unchanged" marker; Spice now fills that value from the old tuple โ€” its old value is its current value โ€” so updates no longer error or drop columns. Without an old tuple, the error persists with a hint to enable REPLICA IDENTITY FULL.
  • Transient Walsender Contention: Slot-contention errors during rolling deploys โ€” SQLSTATE 55006 ("replication slot is active for PID") and 53300 ("requested standby connections exceeds max_wal_senders") โ€” are now classified as transient and retried with backoff instead of fatally terminating the stream. Replication connections are also released at shutdown start (not process exit), freeing walsender seats for replacement instances.
  • Strict CDC Param Validation: PostgreSQL CDC parameters are strictly validated rather than silently defaulted.
  • Debezium Schema Evolution: Fixes for Debezium schema-evolution support, including tombstone-message handling and sign-extension of minimal-width base64 decimals.

Distributed Queryโ€‹

Distributed Query gains:

  • Distributed Iceberg Catalog Scans: Ballista distributes scans of Iceberg catalog tables across executors.
  • Broadcast Joins: Small dimension tables are broadcast to executors for distributed joins.
  • Shared Scheduler Job State with Failover: Ballista job state is shared so the scheduler can fail over without losing in-flight work.

Performance & Query Engineโ€‹

Apache DataFusion is upgraded to v54, folding in v53, alongside Arrow v58.3 and Vortex v0.74 (with a pin bump adding intra-file decode split and a per-execution kernel cache). Two DataFusion releases land in this upgrade:

  • DataFusion v54 (release notes): adds LATERAL joins, SQL lambda functions (x -> expr with array_transform/array_filter/array_any_match), spilling nested-loop joins, and a faster arrow-avro reader. Performance work includes morsel-driven Parquet scans (up to ~2x faster for skewed scans), 20-50x faster sort-merge semi/anti/mark joins, redundant-sort-key pruning, NDV-based cardinality estimation, and inner_product/cosine_distance functions.
  • DataFusion v53 (release notes): adds LIMIT-aware Parquet row-group pruning, broader filter pushdown through joins and UNION, nested-field pushdown (get_field into the scan), faster query planning (some plans dropping from ~4-5ms to ~100us), and 42 faster built-in functions.

Federation deny-list enforcement and catalog DDL are restored after the DataFusion upgrades, and a cost-based left-deep join reordering rule is added for Cayenne acceleration.

AI & LLMโ€‹

  • Native GLM Support with Distributed Inference: Native GLM model support with surfaced reasoning_content, including tensor-parallel GLM inference. Load a GLM model with model_type: glm4 (glm4moe and glm4moelite are also supported):
models:
- name: glm
from: huggingface:huggingface.co/THUDM/glm-4-9b-chat
params:
model_type: glm4

For large models, GLM inference can be distributed across nodes (tensor parallelism) via the mistral.rs pure-TCP ring all-reduce backend โ€” no NCCL/system dependency. This is a Spice.ai Enterprise feature requiring the distributed build. Run the same model on each node, changing only node_rank:

models:
- name: glm
from: huggingface:huggingface.co/THUDM/glm-4-9b-chat
params:
model_type: glm4
distributed_backend: ring
nodes: 10.0.4.21,10.0.4.22 # ordered host/IP per rank; the ring backend currently requires exactly 2
node_rank: 0 # rank of THIS node in [0, world_size); rank 0 serves the API. Set node_rank: 1 on 10.0.4.22
  • NSQL Context Endpoint: A new GET /v1/nsql/context endpoint returns the SQL dialect, dataset schemas (with optional sample rows), and registered functions that Spice injects into natural-language-to-SQL (POST /v1/nsql) requests โ€” useful for inspecting or caching exactly what the model sees:
# Inspect the context injected into /v1/nsql requests (examples_limit default 3, max 100)
curl "http://localhost:8090/v1/nsql/context?include_examples=true&examples_limit=3"

Returns the dialect, per-dataset schema (keys, indexes, searchable columns), the registered function inventory, and sample rows (abbreviated):

{
"context": "# Spice.ai NSQL Context",
"instructions": [
"Write SQL for the Spice runtime, which uses Apache DataFusion with the SQL parser configured for the PostgreSQL dialect.",
"Use table and column descriptions, primary keys, foreign keys, unique constraints, and indexes when choosing joins and filters."
],
"sql": {
"engine": "Apache DataFusion",
"version": "54.0.0",
"dialect": "PostgreSQL",
"parser": "DataFusion SQL parser configured with PostgreSQL dialect"
},
"datasets": [
{
"name": "sales.orders",
"table": "orders",
"description": "Customer orders",
"columns": [
{ "name": "order_id", "data_type": "Int64", "nullable": false, "primary_key": true, "indexed": true },
{ "name": "customer_id", "data_type": "Utf8", "nullable": false, "vector_search": true, "full_text_search": true }
],
"primary_key": ["order_id"],
"foreign_keys": [
{ "columns": ["customer_id"], "foreign_table": "spice.sales.customers", "foreign_columns": ["id"] }
]
}
],
"functions": {
"summary": "Spice SQL runs on Apache DataFusion ... Run SELECT * FROM list_udfs() to inspect the full registered function inventory",
"search": [
{ "name": "vector_search", "syntax": "vector_search(dataset, 'query text'[, column])" },
{ "name": "text_search", "syntax": "text_search(dataset, 'query text'[, column])" }
]
},
"samples": [
{ "title": "Example rows for `sales.orders`", "content": "| order_id | customer_id |\n| --- | --- |\n| 42 | CUST-1 |" }
]
}

Search & Vectorsโ€‹

  • S3 Vectors Pagination: QueryVectors paginates for top-K up to 10,000.
  • Elasticsearch kNN Candidate Pool: The default kNN candidate pool is raised from 10 to 1000 for better recall.

SQL & Query Engineโ€‹

  • FlightSQL Substrait Plans: CommandStatementSubstraitPlan support.
  • Large Result Streaming: Flight streaming is optimized for large result sets.
  • Write Authorization: The SQL tool allows writes for ReadWrite API keys.
  • Schema Evolution Policies: on_schema_change supports widening-only evolution and a drop_and_recreate policy.

Security & Connectorsโ€‹

  • Kafka mTLS: Mutual TLS configuration is surfaced in the Kafka data connector.
  • Secret Resolution at Startup: Secret references are checked and reported at startup.
  • DuckDB HNSW: Upgrade to DuckDB v1.5.3 with the statically linked VSS (HNSW) vector extension.

Adaptive Self-Tuning (Experimental)โ€‹

The Spice Cayenne accelerator gains experimental opt-in self-tuning. cayenne_tuning: auto derives configuration from the detected hardware and inferred schema, while adaptive additionally runs a per-table closed-feedback controller that adapts flush caps, the in-memory CDC tier, compaction cadence, and write concurrency toward operator SLOs (replication lag, freshness, query latency, queries-per-hour). Cayenne can also maintain aggregates incrementally โ€” with predicate-aware delta serving and incremental retraction โ€” and fold whole-table SUM/AVG/COUNT/MIN/MAX from statistics. These features are experimental and disabled by default.

datasets:
- from: postgres:public.orders
name: orders
acceleration:
engine: cayenne
refresh_mode: changes
params:
cayenne_tuning: adaptive # 'auto' (static, env- + schema-derived) or 'adaptive' (closed-loop)

Observabilityโ€‹

  • Per-Dataset Query Attribution: The query_executions metric gains a datasets dimension.
  • HTAP Diagnostics: Improved HTAP replication diagnostics on non-convergence.
  • Cayenne Write Observability: Write-phase observability for the in-memory CDC tier.

Notable Bug Fixesโ€‹

  • Cayenne Utf8View: The Utf8View read schema avoids a hash-join offset overflow.
  • Cayenne metastore: cayenne_metastore: turso is honored for partitioned tables and the dataset checkpoint.
  • Dual-write detection: Dual-write accelerated tables are detected behind the metadata-enrichment wrapper.
  • digest_many collisions: Values are length-prefixed so column boundaries can't collide.
  • Turso WAL checkpoint: WAL checkpoints route through the native Turso connection.
  • TLS status probe: The status check probes the metrics endpoint over HTTPS when TLS is enabled.
  • Search snippet offsets: Character chunk offsets persist so search snippets aren't shifted or garbled.
  • Async query chunk offsets: /v1/queries chunk row_offset uses the cumulative offset rather than chunk_index * chunk_size.

Dependency Updatesโ€‹

Dependency / ComponentVersion
DataFusionv54
Arrow (arrow-rs)v58.3
Vortexv0.74
iceberg-rustv0.9.1
DuckDBv1.5.3
Rust toolchainv1.95.0

Contributorsโ€‹

Breaking Changesโ€‹

No breaking changes.

Cookbook Updatesโ€‹

No new cookbook recipes.

The Spice Cookbook includes more than 100 recipes to help you get started with Spice quickly and easily.

Upgradingโ€‹

To upgrade to v2.1.0, use one of the following methods:

CLI:

spice upgrade

Homebrew:

brew upgrade spiceai/spiceai/spice

Docker:

Pull the spiceai/spiceai:2.1.0 image:

docker pull spiceai/spiceai:2.1.0

For available tags, see DockerHub.

Helm:

helm repo update
helm upgrade spiceai spiceai/spiceai --version 2.1.0

AWS Marketplace:

Spice is available in the AWS Marketplace.

What's Changedโ€‹

Changelogโ€‹

  • Make DuckDB schema cast logic more robust by @sgrebnov in #10991
  • perf(cayenne): reduce allocation overheads in hot paths by @lukekim in #10950
  • improve error message for 'params.spiceai_region' by @Jeadie in #10954
  • fix(acceleration): rename WriteMode variants to fix #10960 by @phillipleblanc in #10974
  • add Scylla, bigquery and turso to throughput benchmarking by @Jeadie in #11006
  • deps(ballista): pull in shuffle-on-object-store correctness fixes (datafusion-ballista PRs #42 + #43) by @phillipleblanc in #10919
  • fix(kafka): seek to sidecar offsets via post_rebalance callback on restart by @ewgenius in #11007
  • Propagate source comments into schema metadata by @lukekim in #10944
  • feat(chbench-driver): better alignment to BenchBase by @sgrebnov in #11012
  • fix: handle EXISTS/NOT EXISTS subqueries in federation analyzer by @sgrebnov in #10996
  • Enable filter pushdown in spicepod defined UDTFs by @Jeadie in #11004
  • Refactor spice dataset configuration command by @Jeadie in #10999
  • fix: ensure HashJoinExec partition counts match when join input is statically empty by @phillipleblanc in #11025
  • feat(chbench): Improve OLTP throughput and reduce PostgreSQL CDC overhead by @sgrebnov in #11018
  • feat(cluster): add distributed query observability metrics by @phillipleblanc in #10990
  • fix: delegate truncate in PolyTableProvider to inner write provider by @claudespice in #11036
  • Remove default runtime features - enable explicitly in spiced by @phillipleblanc in #11037
  • fix: preserve field and schema metadata in Vortex physical schema calculation by @claudespice in #11013
  • Expose metadata descriptions via PostgreSQL UDFs by @lukekim in #11032
  • fix: route Turso WAL checkpoint through native turso connection (fixes #10657) by @claudespice in #11048
  • fix: add missing truncate delegation and guards for wrapper TableProviders by @claudespice in #11014
  • Update DataConnector statuses by @krinart in #11052
  • remove redundant readonly checks by @Jeadie in #10975
  • Fix Unity Catalog connector compatibility with OSS Unity Catalog by @ewgenius in #11026
  • refactor(cdc): reduce CDC sub-batch splits for interleaved upsert/delete workloads by @sgrebnov in #11051
  • feat(cayenne): allow inline writes with pending deletions (deletes/upserts) by @sgrebnov in #11031
  • fix(sql-tool): defer read-only gate to caller's API key role by @phillipleblanc in #11040
  • fix: map Gemini Recitation finish reason to ContentFilter by @claudespice in #11046
  • feat(cayenne): fast-path CDC deletes by extracting PK values from filters by @sgrebnov in #11049
  • fix(cluster): gate scheduler readiness on executor partition loads by @phillipleblanc in #10992
  • fix(snowflake): enforce function deny-list in federation pushdown by @claudespice in #11057
  • perf(cdc): Last-write-wins dedup in group_into_sub_batches to reduce sub-batch splits by @sgrebnov in #11059
  • [Bug] Timing between reconnect and AllocateInitialPartitions leaves connection without flight_sql_client by @Jeadie in #10805
  • Define 'trait QueryEngine' to refactor runtime crate by @Jeadie in #11028
  • fix(snowflake): apply Spice function deny-list in extracted connector crate by @claudespice in #11071
  • perf(cayenne): keep CDC upsert PK keysets resident to avoid per-batch full-table rebuilds by @lukekim in #11074
  • fix(postgres-replication): emit recovery log + reduce reconnect-warn volume by @claudespice in #11084
  • fix metadata on search indexing by @Jeadie in #11080
  • perf(cayenne): scale CDC inline flush caps with memory + storage class by @lukekim in #11087
  • feat(cayenne): merge-on-read position deletes for PK upsert tables + memory-pool accounting by @lukekim in #11085
  • Support tuple-IN composite PK extraction in Cayenne delete fast-path by @sgrebnov in #11093
  • feat(cluster): report per-executor table statistics so distributed JoinSelection can size joins by @phillipleblanc in #11089
  • feat(cluster): NDV-aware executor stats so CDC q18 join swap fires by @phillipleblanc in #11098
  • Improve HTAP replication diagnostics on non-convergence by @sgrebnov in #11100
  • Normalize DataType::Null to Int32 in acceleration schema for duckdb by @krinart in #11062
  • Fix debezium schema evolution support by @ewgenius in #11095
  • feat(cayenne): incremental write-path executor statistics for distributed join sizing by @phillipleblanc in #11104
  • fix(cache): periodic moka maintenance to drain invalidation predicates (#11077) by @phillipleblanc in #11106
  • fix: validate Snowflake account identifiers and auth config by @Jeadie in #11024
  • fix: trace external mcp server tool calls by @ewgenius in #11058
  • Remove unwrap from test code; drop clippy::unwrap_used suppressions by @phillipleblanc in #11108
  • Upgrade to DuckDB 1.5.3 + statically link the VSS (HNSW) extension by @sgrebnov in #11107
  • Fix fetched_at for HTTP connector by @Jeadie in #11116
  • fix(search): propagate LIMIT to base TableScan in VectorScanTableProvider (fixes #8368) by @claudespice in #11124
  • feat(runtime): add spicebench feature to register the Cayenne catalog connector by @phillipleblanc in #11122
  • fix(cayenne): tombstone inline-checkpointed rows on upsert to prevent duplicate PKs by @sgrebnov in #11129
  • Remove possibility of a deadlock in RuntimeStatus by @krinart in #11114
  • Fix Windows build: vendored-vss duckdb-rs + adapt to table-providers mongodb API by @phillipleblanc in #11140
  • localpod: synchronize child refreshes when parent uses in-memory (arrow) accelerator by @phillipleblanc in #11139
  • Add datasets dimension to the query_executions metric by @phillipleblanc in #11138
  • fix(spiceai): keep correlated subqueries out of JOIN ON for Spice Cloud federation by @phillipleblanc in #11143
  • fix(duckdb): normalize timestamp columns to microsecond precision (fixes #10627) by @claudespice in #11145
  • feat(cayenne): sharded parallel Vortex encode with key/time clustering by @lukekim in #11144
  • fix(cluster): prevent DoPut write pipeline self-deadlock under ingest backpressure by @phillipleblanc in #11160
  • feat(chbench): configurable HTAP concurrency, DuckDB query overrides, and OLTP rate control by @sgrebnov in #11162
  • fix(http): preserve non-JSON response rows instead of crashing nested decomposition (fixes #11155) by @claudespice in #11161
  • Use declared schema in DynamoDB/MongoDB/Debezium by @krinart in #11066
  • fix(cluster): prevent partitioned datasets from staying Refreshing by @phillipleblanc in #11157
  • fix(runtime): don't list postgres as a valid accelerator engine when postgres-accel is disabled by @sgrebnov in #11169
  • fix(spark): recover stale or broken Spark Connect sessions on failure by @lukekim in #11171
  • fix(secrets): don't abort secret lookup precedence walk on a failing store by @phillipleblanc in #11175
  • feat(cayenne): bound aggregate write concurrency, conservative defaults, and write/read observability by @lukekim in #11170
  • feat(unity_catalog): support Unity Catalog credential vending for Delta Lake tables by @phillipleblanc in #11180
  • fix(secrets): keep failed secret stores registered so lookups report the init root cause by @phillipleblanc in #11181
  • fix(debezium): sign-extend minimal-width base64 decimals instead of zero-padding by @claudespice in #11184
  • fix(deps): update hickory-resolver to 0.26 (evicts hickory-proto 0.25.x) by @phillipleblanc in #11183
  • refactor(secrets): derive secret store metadata from a single registry table by @phillipleblanc in #11188
  • perf(cayenne): cut CDC replication lag on hot upsert tables by @lukekim in #11191
  • feat(cayenne): async inline-fallback (per-tombstone published flag) + 64c/256GB tuning by @lukekim in #11194
  • Add HTTP connector mTLS support by @lukekim in #11127
  • feat(snowflake): push AT TIME ZONE as CONVERT_TIMEZONE and pin session to UTC by @lukekim in #11190
  • feat(cdc): make cdc_max_coalesce_age_ms a real apply-loop linger by @sgrebnov in #11196
  • feat(cayenne): delta-write encoding levels (cayenne_delta_encoding, default auto) + make compression_strategy=zstd real by @lukekim in #11199
  • Add NSQL context endpoint by @lukekim in #11075
  • fix(federation): respect the Spice function deny-list across all SQL connectors; dialect-aware DuckDB pushdown by @claudespice in #11186
  • fix: surface unknown/applied cayenne_* runtime.params at startup (fixes #10970) by @claudespice in #11133
  • perf(cayenne): plain-fsync ordering tier on the staged-commit hot path by @lukekim in #11198
  • fix(kafka): decode JSON payloads to Arrow directly โ€” fixes lossy Decimal128 + removes double-parse (#11192) by @claudespice in #11207
  • feat(cayenne): self-tuning accelerator โ€” hardware + schema + closed-loop adaptive (auto/adaptive modes) by @lukekim in #11213
  • perf(cayenne): CDC throughput โ€” SF-100 @10K txn/s toward <5s lag + 5K QPH by @lukekim in #11206
  • fix(cluster): distribute accelerated tables wrapped by metadata/index providers by @phillipleblanc in #11226
  • Improve Cayenne adaptive tuning and schema safety by @lukekim in #11237
  • feat: Add cayenne_file_pruning param by @peasee in #11239
  • Debezium connector - handle tombstone messages in kafka topic, with schema evolution enabled by @ewgenius in #11197
  • feat(cayenne): broadcast small-dimension joins to executors by @phillipleblanc in #11245
  • fix: scope request context across the managed query runtime by @phillipleblanc in #11253
  • fix: Strip inference columns from table schema on query by @peasee in #11251
  • fix(flightsql): don't drop un-pushed FilterExec predicates in distributed pushdown rules by @claudespice in #11256
  • feat(postgres): share one replication slot across multiple changes-mode datasets by @phillipleblanc in #11255
  • Upgrade to DataFusion v53.1, Arrow v58.3, Vortex v0.74, and dependencies by @lukekim in #11118
  • feat(connectors): support file_format: vortex everywhere parquet is supported by @lukekim in #11282
  • perf(cayenne): metadata-only publish โ€” drop per-key insert records on upsert commit by @lukekim in #11260
  • fix(kafka): harden fetch_latest_message for multi-partition topics by @ewgenius in #11285
  • perf(cayenne): bound mem-tier checkpoint churn + O(1) per-scan deletion view by @lukekim in #11249
  • fix(udfs): length-prefix digest_many values so column boundaries can't collide (fixes #11272) by @claudespice in #11288
  • fix: restore federation deny-list enforcement regressed by the DataFusion 53 upgrade by @claudespice in #11294
  • fix(postgres): recover unchanged-TOAST columns from the old tuple; classify walsender contention as transient by @phillipleblanc in #11293
  • feat: deepen extended schema inference and wire it into cayenne compaction sharding/sorting by @lukekim in #11284
  • perf(cayenne): in-memory CDC tier follow-ups + write-phase observability by @lukekim in #11278
  • Support per-dataset CDC tunable overrides by @sgrebnov in #11295
  • feat(cayenne): harden adaptive auto-tuner (controller hygiene, mem-tier actuator, delete/burst signals, single opt-in) by @lukekim in #11302
  • fix(cayenne): scan inlined-view capture starvation under sustained CDC (analytical QPH) by @lukekim in #11299
  • fix(vortex): don't row-evaluate hash-join dynamic filters in the scan by @sgrebnov in #11307
  • fix(deps): bump rust-postgres crates (RUSTSEC-2026-0178/0179) by @lukekim in #11313
  • fix: strict validation of Postgres CDC params instead of silent defaults (fixes #11274) by @claudespice in #11304
  • fix(duckdb): always quote on-refresh sort columns so reserved-word names don't break refresh by @claudespice in #11305
  • feat(flightsql): fall back to original connection when endpoint location is unreachable by @melks in #11287
  • perf(cayenne): light-encode transient staged CDC deltas by @lukekim in #11311
  • feat(acceleration): widening-only schema evolution via on_schema_change by @lukekim in #11261
  • deps(vortex): bump pin to spiceai-53 HEAD โ€” intra-file decode split + per-execution kernel cache by @lukekim in #11314
  • feat(github): enhance GitHub component validation and error handling by @lukekim in #11259
  • feat(cayenne): goal-driven adaptive tuning toward operator SLOs (lag, freshness, query latency, QPH) by @lukekim in #11310
  • fix(cayenne): broadcast-join rewrite must bail on ambiguous columns, NULL-equal joins, and residual filters by @claudespice in #11252
  • Add Cayenne maintained aggregates by @lukekim in #11235
  • perf(cayenne): single-hash composite deletion filter via KeyDeletionIndex::get_batch by @phillipleblanc in #11325
  • fix(Vortex): decline only the InList membership conjunct of hash-join dynamic filters by @sgrebnov in #11335
  • fix: scope SQL UDF arg inlining to args-table columns (fixes #11273) by @claudespice in #11337
  • fix(refresh): restore S3 ETag/Version refresh-skip behind provider wrappers by @phillipleblanc in #11339
  • fix(cayenne): ref-count in-flight scans so GC can't delete Vortex files mid-read by @phillipleblanc in #11321
  • fix(runtime): retry object-store dataset load when source files are not yet available by @phillipleblanc in #11342
  • feat(s3): default to path-style for dotted bucket names on standard AWS by @phillipleblanc in #11347
  • fix(runtime): resolve accelerated table through metadata-enrichment wrapper by @phillipleblanc in #11345
  • fix: detect dual-write accelerated tables behind the metadata-enrichment wrapper by @claudespice in #11351
  • feat(cayenne): incremental seq-prefix bake โ€” shrink the merge-on-read deletion index by @lukekim in #11326
  • fix(adbc): prevent Spice-specific UDFs from being pushed down to ADBC sources by @krinart in #11297
  • fix: Query Redshift schema details from svv_redshift tables by @peasee in #11362
  • perf(cayenne): tune Turso connection PRAGMAs + jitter metastore retries by @lukekim in #11359
  • Upgrade to DataFusion 54 by @sgrebnov in #11360
  • feat(runtime): dedicated CDC-apply tokio runtime + per-runtime tokio metrics by @lukekim in #11370
  • fix(cayenne): spill oversized hash joins via sort-merge to avoid OOM by @lukekim in #11371
  • fix(cayenne): honor cayenne_metastore: turso for partitioned tables and the dataset checkpoint by @phillipleblanc in #11365
  • perf(cayenne): in-RAM scan parallelism, query admission control, skip no-op deletion encode, sound scan output_ordering by @lukekim in #11332
  • fix(catalog): restore DDL after DataFusion 54 broke transparent catalog-provider downcasts by @phillipleblanc in #11375
  • feat(flightsql): infer schema via SELECT * LIMIT 1 when GetTables is unimplemented by @melks in #11286
  • fix(cayenne): Utf8View read schema avoids hash-join offset overflow by @lukekim in #11379
  • feat(cluster): support distributed (Ballista) scans of Iceberg tables by @phillipleblanc in #11378
  • feat(optimizer): cost-based left-deep join reordering for Cayenne acceleration by @sgrebnov in #11377
  • cli - fix service-account auth in spice cloud * commands by @ewgenius in #11316
  • fix: Support external Redshift table schema inference and Hive external type parsing by @peasee in #11399
  • feat(llms): native GLM support โ€” opt-in flash-attn + surface reasoning_content by @lukekim in #11400
  • feat(s3_vectors): paginate QueryVectors for topK up to 10,000 by @bjchambers in #11405
  • fix: surface .env parse errors with line numbers instead of silently skipping by @Oxygen56 in #11306
  • fix(status): probe metrics endpoint over https when TLS is enabled by @phillipleblanc in #11393
  • fix(mcp): record task_history spans for tool calls proxied through /v1/mcp by @phillipleblanc in #11397
  • Properly handle date_trunc in BigQueryDialect by @krinart in #11416
  • fix(snowflake): honor column scale in Int64 timestamp arm and cast TIME by @claudespice in #11418
  • fix: /v1/queries chunk row_offset uses cumulative offset, not chunk_index * chunk_size (fixes #11271) by @claudespice in #11398
  • feat(cayenne): incremental retraction for maintained aggregates + anchor bench by @lukekim in #11389
  • feat(cluster): support distributed (Ballista) scans of Iceberg catalog tables by @phillipleblanc in #11419
  • Simplify chat/responses models by @Jeadie in #10997
  • feat(llms): distributed tensor-parallel GLM inference via mistral.rs ring backend by @lukekim in #11406
  • Optimize Flight streaming for large result sets by @lukekim in #11420
  • fix(deps): evict rustls 0.21 / rustls-webpki 0.101.7 (GHSA-82j2-j2ch-gfr8) by @phillipleblanc in #11428
  • feat(cayenne): in-memory CDC intra-apply sharding (PK-hash shards) by @lukekim in #11421
  • fix(cayenne): shard CDC upserts with pending deletions so the N>1 slot-ack advances by @lukekim in #11445
  • fix(cluster): keep built-in avg over Spark avg (distributed aggregate state schema mismatch) by @phillipleblanc in #11434
  • feat(views): support params.file_format for embedding chunking by @Jeadie in #11424
  • fix: offload blocking sync calls off the primary async runtime by @phillipleblanc in #11435
  • fix(udfs): rebind dot_product alias to Spice's inner_product on DataFusion 54 by @lukekim in #11443
  • feat(secrets): add full-fidelity reference iteration and a resolution-status API by @phillipleblanc in #11195
  • fix: Deny unsupported array functions for Postgres pushdown by @peasee in #11450
  • fix(cli): spice query honors --http-endpoint instead of failing on a Flight connect by @phillipleblanc in #11452
  • fix(cayenne): coordinate query-pool + in-memory CDC tier budgets to prevent adaptive OOM by @lukekim in #11449
  • Surface mTLS config in Kafka data connector by @v1gnesh in #11372
  • feat(secrets): check and report secret references at startup by @phillipleblanc in #11457
  • Default cayenne_force_view_types to false by @sgrebnov in #11459
  • fix: resolve table-reference qualification in results-cache invalidation (fixes #11266) by @claudespice in #11460
  • feat(cayenne): metadata aggregate pushdown โ€” fold whole-table SUM/AVG/COUNT/MIN/MAX from statistics by @bjchambers in #11414
  • fix(search): restore numeric trunc and fix SortPreservingMergeExec planning error (DF54) by @Jeadie in #11415
  • fix(cluster): route Ballista shuffle/temp to the data PVC by @phillipleblanc in #11454
  • fix(search): default Elasticsearch kNN candidate pool to 1000 instead of 10 (fixes #11264) by @claudespice in #11467
  • feat(acceleration): add on_schema_change drop_and_recreate policy by @lukekim in #11462
  • feat(cayenne): predicate-aware maintained aggregates serve filtered analytical queries from the CDC delta by @lukekim in #11458
  • feat(cluster): shared Ballista job state with scheduler failover by @phillipleblanc in #11436
  • feat(cayenne): extend HLL NDV sketching to string and date columns by @bjchambers in #11468
  • fix(search): persist character chunk offsets so search snippets aren't shifted/garbled (fixes #11269) by @claudespice in #11479
  • feat(cayenne): storage-aware adaptive CDC tuning โ€” calibration probe, IMDS, I/O-cliff fast path, infeasible-SLO feedback by @lukekim in #11463
  • fix(cayenne): LIMIT N under-delivers on key-deletion tables by @lukekim in #11490
  • fix(cayenne): live/tier-accurate join build-side stats (merge-on-read deletes + never-shrink NDV) by @lukekim in #11496
  • perf(cayenne): kernel-space I/O hygiene โ€” compaction fadvise + staged-commit barrier reduction by @lukekim in #11495
  • feat(cayenne): feed maintained-aggregate IVM from the staged-disk CDC path by @lukekim in #11491
  • feat(cayenne): global adaptive-tuning SLOs with per-dataset overrides; QPH global-only by @lukekim in #11497
  • Update search snapshots by @sgrebnov in #11473
  • fix: Support reading column types longer than 128 chars in Redshift by @peasee in #11500
  • fix(cluster): distributed (Ballista) query-execution config + scheduled SF10 bench by @phillipleblanc in #11478
  • fix(http): retry transient response-body read failures; de-flake backoff test by @claudespice in #11482
  • Re-land orphaned deletion-vector cleanup during retention deletes by @lukekim in #11501
  • fix(cayenne): re-upsert over a pending delete tombstone records an insert-record (overwrite resurrection) by @bjchambers in #11469
  • fix: Flight DoPut silently dropped client batches on early sink completion by @claudespice in #11507
  • Upgrade OpenTelemetry to 0.32 and reqwest to 0.13 by @phillipleblanc in #11506
  • fix(queries): run async /v1/queries jobs under the submitting request context by @phillipleblanc in #11505
  • fix(cayenne): restore append-only current-snapshot compaction by @Jeadie in #11439
  • perf(cayenne): orphaned deletion-vector cleanup off the write path, behind a knob by @bjchambers in #11517
  • fix(datafusion): accurate projected scan byte size so hash joins build the smaller side by @sgrebnov in #11503
  • fix(cayenne): user-visible DELETE WHERE pk IN (...) reports the real row count by @lukekim in #11514
  • fix(cayenne): seed persisted num_rows for hash-join sizing by @sgrebnov in #11515
  • fix(cayenne): correctness & memory_limit fixes from perf audit (2 P0, 3 P1) by @lukekim in #11516
  • feat(cayenne): wire orphaned-DV cleanup knob to spicepod params + doc sync by @bjchambers in #11523
  • Fix s3 vectors API by @krinart in #11536
  • fix: Placeholder table initialization lock swap by @peasee in #11540
  • chore(cluster): bump ballista pin for the null-aware anti-join fix by @phillipleblanc in #11544
  • fix(runtime-tools): fix memory table identifier validation rejecting valid names by @Jeadie in #11546
  • Bump datafusion to include spiceai/datafusion#181 by @Jeadie in #11563
  • Update deny.toml by @krinart in #11571
  • Bump datafusion (spiceai/datafusion#182) and datafusion-table-providers (#27): fix q16 CollectLeft planning error and SQLite q6 wrong revenue by @Jeadie in #11598

Full Changelog: https://github.com/spiceai/spiceai/compare/v2.0.0...v2.1.0

Spice v2.0.1 (Jun 17, 2026)

ยท 4 min read
Phillip LeBlanc
Co-Founder and CTO of Spice AI

Spice v2.0.1 is now available! ๐Ÿ› ๏ธ

Spice v2.0.1 is a patch release focused on reliability and performance. It speeds up Apache Iceberg reads and fixes bugs across AWS S3 and object-store datasets, data acceleration, distributed query, and authenticated access.

What's New in v2.0.1โ€‹

Faster Iceberg Reads with Parallel File Scanningโ€‹

The Apache Iceberg reader now scans data files in parallel (#11331), improving read throughput and latency for Iceberg tables that span many files.

AWS S3 & Object-Store Reliabilityโ€‹

Three fixes improve S3 and object-store dataset behavior:

  • Refresh-skip restored (#11339): ETag/Version-based refresh-skip works reliably again, so unchanged S3 objects are no longer re-downloaded on every refresh.
  • Retry when source files are not yet available (#11342): an object-store dataset whose source files are not present at startup now retries and becomes ready once the data appears, instead of failing permanently.
  • Path-style addressing for dotted bucket names (#11347): on standard AWS, buckets whose names contain dots now default to path-style addressing, avoiding TLS wildcard certificate errors under virtual-hosted-style HTTPS.

Data Acceleration & Distributed Query Fixesโ€‹

Two fixes ensure accelerated datasets behave correctly in more configurations:

  • Acceleration endpoints (#11345): /v1/datasets/{name}/acceleration/refresh (and the related update-refresh-sql, partition-filters, and snapshots endpoints) now work for all accelerated datasets, fixing cases where some incorrectly reported Table is not accelerated.
  • Distributed clusters (#11226): the distributed query coordinator now serves accelerated data from executors for all accelerated datasets, instead of falling back to reading from the source for some.

Authenticated Query Fixesโ€‹

With authentication enabled, queries now consistently run as the requesting user (#11253), so per-user behavior such as results caching is correctly scoped to each user.

Contributorsโ€‹

Breaking Changesโ€‹

No breaking changes.

Cookbook Updatesโ€‹

No new cookbook recipes.

The Spice Cookbook includes more than 100 recipes to help you get started with Spice quickly and easily.

Upgradingโ€‹

To upgrade to v2.0.1, use one of the following methods:

CLI:

spice upgrade

Homebrew:

brew upgrade spiceai/spiceai/spice

Docker:

Pull the spiceai/spiceai:2.0.1 image:

docker pull spiceai/spiceai:2.0.1

For available tags, see DockerHub.

Helm:

helm repo update
helm upgrade spiceai spiceai/spiceai --version 2.0.1

AWS Marketplace:

Spice is available in the AWS Marketplace.

What's Changedโ€‹

Changelogโ€‹

Full Changelog: https://github.com/spiceai/spiceai/compare/v2.0.0...v2.0.1

Spice v2.0-stable (Jun 5, 2026)

ยท 94 min read
Phillip LeBlanc
Co-Founder and CTO of Spice AI

53 releases since Spice 1.0-stable, Spice.ai OSS has reached the 2.0-stable milestone! ๐ŸŽ‰

Spice v2.0.0 is the next major release of Spice and a major milestone in the project's development, advancing Spice from a single-node engine into a distributed data and query platform built for enterprise AI agents. These agents need low-latency, governed access to data spread across many production systems, and because they generate their own queries autonomously, that access has to be sandboxed, observable, and able to absorb occasional heavy analytical queries without overwhelming the underlying systems. The release is headlined by multi-node distributed query, now generally available โ€” multi-active, highly-available, and object-store-native, built on Apache Ballista โ€” distributing both query execution and ingestion across executors with data-local routing and per-executor statistics for distributed join planning. Alongside it, the Spice Cayenne data accelerator is generally available, built on the Vortex compressed columnar format, with a high-throughput CDC write path, MERGE INTO, SQL-defined partitioning, inline writes, a dedicated compaction runtime, and write-path statistics for distributed join sizing. The engine also moves to DataFusion v52 with sort pushdown, a rewritten merge join, and dynamic filters, and the Spice CLI is rewritten in Rust as a single self-contained binary.

v2.0 also expands real-time and write-path capabilities across the platform: native CDC from MongoDB Change Streams and PostgreSQL WAL logical replication, durable Kafka CDC offsets, DML write-back for PostgreSQL, Snowflake, DynamoDB, Arrow, and DuckLake, DDL and MERGE INTO for Iceberg catalogs, mutual TLS across server endpoints and outbound connectors, HashiCorp Vault and Azure Key Vault secret stores, user-defined functions, hybrid search with Elasticsearch and DuckDB HNSW vector indexes, provider-aware LLM prompt caching, and the Responses API across all model providers.

Highlights in v2.0.0 include:โ€‹

  • Spice Cayenne (GA) โ€” generally available on the Vortex compressed columnar format, with WAL-staged writes, inline low-latency writes, fast-path CDC deletes, merge-on-read position deletes, composite & SQL-defined partitioning, MERGE INTO, dedicated compaction runtime, and join-sizing statistics maintained on the write path
  • Multi-Active HA Distributed Query (GA) โ€” multi-node distributed query built on Apache Ballista, with object-store-native clustering, dynamic cluster sizing, distributed ingestion, data-local query routing, per-executor table statistics for distributed join planning, and async queries via /v1/queries
  • Mutual TLS (mTLS) โ€” public mTLS for HTTP and Flight, TLS cert hot-reload, and mTLS client certificates for FlightSQL and Spice.ai connectors
  • Enterprise Authentication & Authorization โ€” OIDC bearer-token verification and Cedar-based authorization policy with per-principal row- and column-level filtering
  • New Secret Stores โ€” HashiCorp Vault and Azure Key Vault
  • CDC Sources โ€” native MongoDB Change Streams, PostgreSQL WAL logical replication, and durable Kafka CDC offsets โ€” no Debezium or Kafka middleware required
  • DML & DDL โ€” INSERT/UPDATE/DELETE write-back for PostgreSQL, Snowflake, DynamoDB, and Arrow; CREATE TABLE/DROP TABLE and MERGE INTO for Iceberg catalogs
  • User-Defined Functions โ€” SQL UDFs in spicepods, remote UDFs over HTTP, and optional geospatial ST_* UDFs
  • On-Demand Dataset Loading & Unified Query Cancellation โ€” faster startup and end-to-end cancellation across HTTP, Flight, FlightSQL, and MCP
  • Dynamic HTTP Connector โ€” OAuth2 refresh tokens, pagination, dynamic headers, subquery-driven parameters, and rate-control state persisted across restarts
  • Storage-Profile Accelerator Tuning & refresh_mode: snapshot โ€” storage-aware acceleration defaults and point-in-time snapshot acceleration
  • Search & Vectors โ€” Elasticsearch data connector with native hybrid search, DuckDB HNSW vector engine with a statically linked VSS extension, multi-vector MaxSim embeddings, and a rerank() UDTF
  • AI & LLM โ€” provider-aware prompt caching, Responses API across all providers, MCP Streamable HTTP transport, and a searchable LLM tool registry
  • New Data Connectors โ€” Elasticsearch (Alpha), GCS (Alpha), Azure Cosmos DB (Alpha), Git (RC), ADBC, DuckLake (Beta), and catalog connectors for PostgreSQL, MySQL, MSSQL, and Snowflake
  • Rust CLI โ€” single-binary spice CLI with spice query async REPL, shell completions, and --output=json
  • Dependency upgrades including DataFusion v52.5, DuckDB v1.5.3, Arrow v57.2, iceberg-rust v0.9.1, Turso v0.6.1, and Vortex v0.69

Spice v2.0 includes several breaking changes. Review the breaking changes section before upgrading.

Distribution Changesโ€‹

AI/ML support including local LLM/ML model and hosted LLM inference is now included in the default Spice build and image. The separate models build variant has been removed.

With models now included by default, the data-only distribution (without AI/ML support) is only published in nightly builds. Official production-ready data-only distributions are available exclusively through Spice Cloud and the Enterprise release.

A new Network Attached Storage (NAS) distribution with built-in SMB and NFS data connector support is also available in nightly builds and with Spice.ai Enterprise.

Distribution / VariantOpen SourceSpice CloudEnterprise
Defaultโœ…โœ…โœ…
DataNightly onlyโœ…โœ…
NAS (SMB + NFS)Nightly onlyโŒโœ…
Metal (macOS)โœ…โœ…โœ…
CUDA (Linux)Nightly onlyโœ…โœ…
Allocator variantsNightly onlyโœ…โœ…
ODBC connectorLocal build onlyโœ…โœ…

Native Windows builds are no longer provided; use WSL for local development. For more details, see the Distributions documentation.

What's New in v2.0.0โ€‹

Spice Cayenne Reaches General Availabilityโ€‹

The Spice Cayenne data accelerator is generally available in v2.0, with a major focus across the release candidates on write-path throughput, correctness, and distributed operation.

Write path & ingest:

  • Staged Append Writes: WAL-based staged append writes prevent partial writes and data loss on stream errors โ€” batches commit atomically.
  • Inline Writes: Small writes are serialized as Arrow IPC and committed directly into the Cayenne metastore, bypassing the staged Vortex write path for low-latency ingest. Inline upserts atomically rewrite existing inline rows, inline data stays query-visible via an in-memory union scan, and rows are checkpointed to Vortex when thresholds are reached. Inline writes now also proceed with pending deletions in flight, and inline flush caps scale with available memory and storage class.
  • Fast-Path CDC Deletes: DELETE statements whose filters identify primary keys directly โ€” including composite keys expressed as (k1, k2) IN ((...), (...)) โ€” skip the table scan entirely.
  • Merge-On-Read Position Deletes: Primary-key upsert tables use position deletes with memory-pool accounting, avoiding full-table rewrites on update-heavy workloads.
  • Resident Upsert Keysets: CDC upsert primary-key keysets stay resident between batches, avoiding per-batch full-table rebuilds.
  • CDC Sub-Batch Efficiency: Interleaved upsert/delete workloads produce fewer sub-batch splits, with last-write-wins deduplication applied within batches.
  • Dedicated Compaction Runtime: Background compaction runs on a dedicated thread pool with CDC pipelining and protected snapshots, isolating compaction work from query and ingest paths.

Query & planning:

  • Join Filter Propagation: Filters propagate across equi-join keys, with range fallback for large join filters and IN-list rewrites.
  • Write-Path Join-Sizing Statistics: Cayenne maintains live row counts and HyperLogLog-based distinct-value estimates on the write path, so distributed JoinSelection can correctly size joins without rescans.
  • Scan-Result Cache: A new scan-result cache accelerates hot reads, with parallel Vortex partition writes and lock-free deletion caches with bloom-prefiltered probes.

SQL & catalog:

  • MERGE INTO: Upsert-style MERGE INTO for Cayenne catalog tables, distributed across executors in cluster mode.
  • PARTITION BY in SQL: Define partitioning directly in CREATE TABLE ... PARTITION BY (...); metadata is persisted in the catalog and survives restarts.
  • Composite Partitioning: partition_by: [col1, col2] with hierarchical path-like keys.
  • File-Based Retention Deletes: Time-based retention uses file-level deletes for both position-based and primary-key tables.

Correctness: Synchronized partition commits, correct NULL-sentinel handling for nullable partition expressions, tombstoned inline-checkpointed rows on upsert (preventing duplicate primary keys), and live reads through expired protected snapshots.

Multi-Active HA Distributed Query (GA)โ€‹

Spice.ai Enterprise feature. See High Availability.

Distributed Query is generally available. Built on Apache Ballista, it distributes query execution across multiple active executor nodes with no single point of failure, reading directly from object storage rather than relying on a central cluster.

Distributed query supports two execution modes:

  • Synchronous: Queries for accelerated datasets are distributed across executors and results stream back in real-time โ€” best for interactive, latency-sensitive queries.
  • Asynchronous: Queries submitted via the HTTP /v1/queries API materialize results to object storage for later retrieval โ€” best for long-running analytical and batch workloads.

Key capabilities:

  • Dynamic Cluster Sizing: The planner adjusts parallelism to the number of active executors as nodes join or leave.
  • Distributed Ingestion: Ingestion for partitioned accelerated tables is distributed across executors, with partition-aware write-through splitting scheduler-side Flight DoPut writes to the responsible executors.
  • Data-Local Query Routing: Cayenne catalog queries route to the executors holding the relevant partitions.
  • Per-Executor Table Statistics: Executors report table statistics โ€” including NDV-aware estimates โ€” so distributed JoinSelection can size joins correctly, fixing out-of-memory conditions on large semi-joins.
  • Readiness & Failure Detection: /v1/ready gates on a configurable executor quorum for safe rolling deployments; scheduler readiness additionally waits for executor partition loads; executor heartbeat timeout reduced from 180s to 30s.
  • Distributed DML & DDL: UPDATE/DELETE forwarding to all executors, executor DDL sync for late joiners, and distributed MERGE INTO.
  • Cluster Observability: New cluster metrics (including scheduler_active_executors_count), distributed runtime.task_history replication, and a Grafana dashboard.
  • Ballista S3 Shuffle: Async queries with runtime.params.shuffle_location: s3://... complete reliably with executor-environment-derived S3 clients.

Security: Mutual TLS, Secret Stores, and Hardeningโ€‹

Several capabilities in this section are Spice.ai Enterprise features. See Enterprise Security.

Mutual TLS across the platform:

  • Public mTLS for HTTP and Flight: client_auth_mode: request (optional, for migration windows) or required (strict) client-certificate verification.
  • TLS Cert Hot-Reload: The runtime reloads TLS certificates on SIGHUP for zero-downtime rotation.
  • Outbound mTLS Client Certificates: FlightSQL and Spice.ai data connectors present client certificates to upstream services; the spice sql REPL supports mTLS client auth.
runtime:
tls:
enabled: true
certificate_file: /etc/spice/tls/server.crt
key_file: /etc/spice/tls/server.key
client_auth_mode: required
client_auth_ca_file: /etc/spice/tls/client-ca.crt

Authentication & Authorization (Spice.ai Enterprise):

  • OIDC Authentication: Validate OIDC bearer tokens (JWTs) issued by enterprise identity providers โ€” Microsoft Entra ID, Okta, Auth0, AWS Cognito, and Google โ€” for secure access to runtime endpoints, standalone or combined with API keys.
  • Principal-Based Policy Enforcement: Fine-grained, Cedar-based authorization policy configured under runtime.authorization governs allow/deny access across datasets, models, tools, and endpoints. Combined with identity SQL functions (current_principal(), current_principal_email(), current_principal_groups()), policies enforce per-principal row-level filtering and column masking.

New Secret Stores: HashiCorp Vault (KV v1/v2; token, approle, kubernetes, and jwt auth with automatic lease renewal) and Azure Key Vault (service principal, managed identity, workload identity, Azure CLI, or auto-detect; sovereign cloud support).

Hardening:

  • Read-only API Key Enforcement on the Flight DoGet path and async query endpoints.
  • Per-Principal Cache Namespacing: SQL, search, and caching-accelerator caches are namespaced per authenticated principal so cached results never cross identity boundaries.
  • API Key Timing Leak & Remote-UDF SSRF: Closed a timing-based position-disclosure leak in API key comparison and blocked SSRF via remote UDF endpoints.
  • Snowflake Function Deny-List: A function deny-list is enforced in Snowflake federation pushdown, and Snowflake account identifiers and auth configuration are validated at startup.
  • MCP allowed_hosts: MCP servers can be restricted to an explicit allowlist of upstream hosts.

Change Data Capture (CDC) Sourcesโ€‹

See Change Data Capture (CDC) for an overview of CDC in Spice.

  • MongoDB Change Streams: MongoDB datasets with refresh_mode: changes stream changes natively into any local accelerator โ€” no Debezium or Kafka required.
  • PostgreSQL Native Replication (WAL): PostgreSQL datasets stream INSERT/UPDATE/DELETE directly from logical replication using pgoutput decoding, with automatic per-replica slot management, an initial REPEATABLE READ bootstrap snapshot, and durable LSN acknowledgement.
  • Kafka CDC Offset Persistence: Kafka CDC offsets persist in sidecar tables for durable, resumable streams across restarts and failovers.
  • Pipelined CDC Ingestion: Source reads overlap with batch apply, with envelope coalescing and improved nullability propagation.
  • Debezium Schema Evolution: Schema changes in Debezium-sourced datasets no longer break dataset initialization on reload.
datasets:
- from: postgres:my_table
name: my_table
params:
pg_host: localhost
pg_db: mydb
acceleration:
enabled: true
engine: duckdb
refresh_mode: changes

DML, DDL, and Write-Backโ€‹

Spice v2.0 turns more connectors and catalogs into full read/write tables:

  • PostgreSQL DML: INSERT, UPDATE, and DELETE write-back on PostgreSQL datasets, with foreign-key metadata exposed via the PostgreSQL catalog connector.
  • Snowflake DML: INSERT, UPDATE, and DELETE write-back on Snowflake datasets.
  • DynamoDB DML: INSERT, UPDATE, and DELETE for DynamoDB, complementing read and CDC streaming.
  • Arrow Primary Key Upserts: Native update-or-insert semantics for in-memory Arrow-accelerated tables.
  • DDL for Iceberg: CREATE TABLE and DROP TABLE via FlightSQL and /v1/sql for Iceberg, with catalog.access: read_write_create.
  • DuckLake INSERT: DuckLake catalog tables with read_write access support INSERT.

SQL & User-Defined Functionsโ€‹

See the SQL Reference for the full SQL surface area.

  • User-Defined Functions: Define reusable SQL UDFs as first-class spicepod components, or invoke remote functions over HTTP (Spice.ai Enterprise), plus table user functions.
  • Spatial SQL UDFs: Optional geospatial ST_* UDFs for geometry workloads.
  • JSON UDTFs: flatten_json, json_tree, and flatten_json_properties table-valued functions for JSON transformation and schema decomposition (with options such as expand_maps). See JSON Functions and Operators.
  • PostgreSQL Metadata UDFs: Dataset and column descriptions are exposed via PostgreSQL-compatible UDFs (obj_description, col_description), so BI tools and psql surface Spice metadata.
  • FlightSQL Substrait Plans: CommandStatementSubstraitPlan support for clients submitting Substrait-encoded plans.
  • SQL REPL Expanded View: Toggle \x for a vertical key-value layout on wide result sets.
  • Prepared statement, federation, and unparsing fixes across the engine, including keeping correlated subqueries out of JOIN ON conditions for Spice Cloud federation and correct EXISTS/NOT EXISTS subquery handling in the federation analyzer.

Runtime Featuresโ€‹

  • On-Demand Dataset Loading: Datasets can be deferred โ€” registered with a declared schema at startup (columns[].type, columns[].nullable) and fully resolved on first reference, reducing startup time and memory for large spicepods.
  • Unified Query Cancellation: HTTP, Flight, FlightSQL, MCP, and internal execution paths honour a unified cancellation signal โ€” disconnects, REPL Ctrl-C, and cancelled HTTP requests cancel the query end-to-end.
  • Storage-Profile Accelerator Tuning: acceleration.storage_profile (auto, local_ssd, ebs, tmpfs) applies storage-aware defaults across DuckDB, SQLite, Turso, and Cayenne file-mode accelerators; auto detects the backing storage.
  • refresh_mode: snapshot (Spice.ai Enterprise): Point-in-time snapshot acceleration with SQLite/Turso WAL flushing and Cayenne metastore slice integration, now reporting accurate readiness when no snapshot exists yet.
  • Structured Component Errors: /v1/datasets?status=true and /v1/models?status=true return structured error objects (category, type, code) and human-readable error_message fields; the CLI shows an ERROR column.
  • Actionable Config Errors: Parameter typos, missing secret references, and unknown engine names produce specific, actionable errors with suggestions.

Spicepod v2โ€‹

Spicepods now support version: v2, the default for spice init, while v1 spicepods continue to work with automatic migration of deprecated fields.

VersionStatus
v2Default. Used by spice init.
v1Supported. Deprecated fields auto-migrate.
v1beta1Removed. No longer accepted.
v1 (deprecated)v2 (preferred)Notes
runtime.results_cacheruntime.caching.sql_resultsAll fields migrate automatically. cache_max_size โ†’ max_size.
runtime.memory_limitruntime.query.memory_limitAuto-migrated. query.memory_limit takes priority if both set.
runtime.temp_directoryruntime.query.temp_directoryAuto-migrated. query.temp_directory takes priority if both set.
dataset.invalid_type_actiondataset.unsupported_type_actionAuto-migrated. v2 adds a new string variant.

New v2 fields include runtime.ready_state, runtime.query.spill_compression, runtime.caching.sql_results.stale_while_revalidate_ttl, runtime.caching.sql_results.encoding, scheduler partition-assignment configuration, and catalog.access: read_write_create.

Data Connectors & Catalogsโ€‹

New connectors:

  • Elasticsearch (Alpha, Spice.ai Enterprise): Query Elasticsearch indexes as SQL tables with native hybrid search โ€” vector_search() kNN, text_search() BM25, and rrf() fusion โ€” plus Elasticsearch as a backing vector engine, direct FTS engine configuration, and index lifecycle controls.
  • GCS (Alpha): Federated queries against Google Cloud Storage, with Iceberg table support.
  • Azure Cosmos DB (Alpha): Read-only NoSQL / Core SQL API connector with cross-partition scans and schema inference.
  • Git (RC): HTTPS/SSH auth, Git LFS support, and per-repo connection resilience.
  • ADBC: Data connector and catalog with full query federation, BigQuery support, and schema/table discovery.
  • DuckLake (Beta): Lakehouse-style data management with DuckDB as the metadata catalog and object storage for data โ€” ACID transactions, time travel, and schema evolution on Parquet.
  • Self-Hosted Spice Connector: Connect Spice to another self-hosted Spice runtime as a federated source.

New catalog connectors for PostgreSQL, MySQL, MSSQL, and Snowflake, using native metadata catalogs for schema and table discovery. Unity Catalog compatibility extends to OSS Unity Catalog deployments, and DDL-defined catalogs can expose and query views.

HTTP connector: OAuth2 refresh-token authentication, query-parameter and no-limit pagination, dynamic request headers parameterised from query predicates, subquery-driven request parameters for fan-out queries, response metadata as queryable columns, map-to-array conversion, shared and persistent rate-control state across restarts and replicas, no caching of transient 429/5xx errors, and a correctly populated fetched_at column.

JSON ingestion: Single-object documents, JSONL, BOM-prefixed input, Socrata SODA responses, format auto-detection, and RFC 6901 json_pointer extraction of nested payloads.

Databricks: Resilience controls, Unity Catalog-aware permission prechecks with structured advisory errors, Classic SQL Warehouse foreign-table compatibility, connect_timeout/client_timeout parameters, a Databricks SQL dialect for federation, and Delta Lake column mapping (Name and Id modes).

Other connector improvements: MongoDB SRV support; MySQL mysql_zero_date_behavior; Snowflake OBJECT, MAP, GEOGRAPHY, GEOMETRY, VECTOR, and TIMESTAMP_LTZ types plus key-pair auth; ClickHouse Date32; S3 s3_url_style for path-style addressing and faster Parquet reads; GraphQL custom auth headers; Oracle and MSSQL sort/limit pushdown; GitHub GraphQL resilience; and improved Kafka reliability.

AI & LLMโ€‹

  • Provider-Aware Prompt Caching: LLM calls automatically use provider-side prompt caching (e.g., Anthropic, OpenAI) for system prompts and tool descriptions, reducing latency and cost.
  • Responses API Across All Providers: The Responses API works with every configured model provider, including streaming response.output_text.delta events and Authorization: Bearer header support.
  • Multi-Vector Embeddings with MaxSim: List-of-string columns produce one embedding per element with MaxSim/mean/sum scoring for ColBERT-style late-interaction retrieval, plus a _match column identifying the best-matching element.
  • rerank() UDTF: Reorder results from vector_search, text_search, or rrf using any registered chat model as a reranker, with automatic query propagation and pushdown support.
  • Searchable LLM Tool Registry: Agents discover tools via semantic search instead of enumerating every tool in the system prompt.
  • MCP Improvements: Streamable HTTP transport (/v1/mcp) on rmcp v1.5.0, native auth for streamable HTTP tools (mcp_auth_token, mcp_headers), external MCP server tool calls traced in task history, and configurable allowed_hosts.
  • Per-Model Rate-Limited AI UDF Execution for controlling concurrent AI function invocations.

Search & Vectorsโ€‹

  • DuckDB Vector Engine: vector_engine: duckdb uses DuckDB's HNSW index for fast approximate nearest-neighbor search without an external vector store. In v2.0.0, the DuckDB VSS extension is statically linked into the bundled DuckDB, so HNSW vector search works out-of-the-box on clean machines with no extension download. HNSW indexes are preserved across data refresh, and cosine_distance pushes down via array_cosine_distance.
  • Hybrid Search: Combine kNN vector search and BM25 full-text search with reciprocal rank fusion (rrf()), backed by Tantivy, Elasticsearch, or DuckDB.
  • Full-Text Search Performance: Significantly faster Tantivy ingestion with rollback-on-error, and search metadata is correctly preserved on indexing and in Vortex physical schema calculation.
  • Embedding Validation: row_id columns are validated during dataset initialization.

Cachingโ€‹

Improvements across Caching:

  • Stale-While-Revalidate: runtime.caching.sql_results.stale_while_revalidate_ttl serves stale results while revalidating in the background.
  • Cache Encoding: Optional compression (e.g., zstd) for SQL results cache entries.
  • Retention Policies for cached query results, and improved CDC-driven cache invalidation (including view plan invalidation on updates).
  • Idle Cache Maintenance: Periodic maintenance drains invalidation predicates on idle caches, fixing unbounded memory growth in rarely-read caches.

Performance & Query Engineโ€‹

Apache DataFusion is upgraded to v52.5 over the course of the release cycle, bringing:

  • Sort Pushdown to Scans: ~30x faster top-K queries on pre-sorted data; Parquet scans reverse row-group order for DESC on ASC-sorted files.
  • Rewritten Sort-Merge Join: Up to three orders of magnitude faster in pathological cases (e.g., TPC-H Q21: minutes โ†’ milliseconds).
  • Dynamic Filters: MIN/MAX aggregates and hash-join build sides prune files, row groups, and rows during execution.
  • Faster CASE Expressions, statistics caching, and prefix-aware list-files caching for faster planning.
  • TableProvider DELETE/UPDATE hooks and the RelationPlanner API for extensible SQL planning.
  • Strict Overflow Handling: try_cast_to errors on overflow instead of silently producing NULLs.

Additional engine work: default query memory limit raised from 70% to 90% with GreedyMemoryPool, partial aggregation optimization for FlightSQLExec, improved partitioned query planning, and metastore transaction support to prevent concurrent conflicts.

Rust CLIโ€‹

The Spice CLI is completely rewritten from Go to Rust โ€” a single spice binary built from the same codebase as spiced, with full feature parity across 27+ commands.

  • spice query: Interactive REPL for async queries with multi-line SQL, progress indication, and cancellation.
  • spice dataset configure: Non-interactive flag-based configuration (--from, --description, --param KEY=VALUE, --set) alongside interactive prompts.
  • spice completions: Shell completion script generation.
  • --output=json: Machine-readable output for scripting; spice login --output adds env, json, and keychain modes.
  • spice init writes a yaml-language-server schema directive for IDE completions.

Observabilityโ€‹

  • OpenTelemetry: Exporter fixes, authenticated metrics export, configurable metric name prefix (runtime.telemetry.metric_prefix), delta temporality by default, and OTLP resource attributes via runtime.telemetry.properties.
  • Query Metrics: The query_executions metric gains a datasets dimension for per-dataset query attribution.
  • Ingestion Metrics: rows_written, bytes_written, and dataset_acceleration_size_bytes for acceleration refresh and Flight DoPut/ADBC ingestion, and EXPLAIN ANALYZE metrics in FlightSQLExec.
  • Task History: Distributed task history in cluster mode and tracing for external MCP server tool calls.

Notable Bug Fixesโ€‹

  • localpod synchronization: localpod child datasets correctly track parent refreshes when the parent uses the in-memory Arrow accelerator.
  • Spice Cloud federation: Correlated subqueries are kept out of JOIN ON conditions, fixing rejected federated queries.
  • refresh_mode: snapshot: No longer reports Ready with empty data when no snapshot exists.
  • Search metadata: Field and schema metadata preserved on search indexing and in Vortex physical schema calculation.
  • HTTP connector: fetched_at column is correctly populated.
  • Connector correctness: DynamoDB Streams transient-error retries and typed-NULL DML handling; ScyllaDB physical filter pushdown disabled to fix incorrect results; MSSQL TOP N pushdown; DuckDB DELETE/UPDATE on full and caching refresh modes; Turso checked arithmetic for timestamp conversions; ODBC queries no longer silently return 0 rows on failure; Flight GetFlightInfo/DoGet schema parity.

Dependency Updatesโ€‹

Dependency / ComponentVersion
DataFusionv52.5
Ballistav52
Arrow (arrow-rs)v57.2
DuckDBv1.5.3 (with statically linked VSS)
iceberg-rustv0.9.1
Turso (libsql)v0.6.1
Vortexv0.69.0
delta_kernelv0.18.2
rmcp (MCP)v1.5.0
mistral.rsv0.8.x (candle v0.10.1)
ADBC Corev0.23
Rust toolchainv1.94.1

Contributorsโ€‹

Breaking Changesโ€‹

  • Models included by default: The separate models build variant has been removed. Local LLM inference is always included in the default build and image.

  • Windows native builds removed: Use WSL for local development.

  • Spicepod version defaults to v2: spice init creates version: v2 spicepods. v1 remains supported with auto-migration; v1beta1 is no longer accepted.

  • Flattened runtime.scheduler configuration: The nested runtime.scheduler.partition_management block is flattened and renamed:

    # Before
    runtime:
    scheduler:
    partition_management:
    interval: 30s
    max_assignments_per_cycle: 16
    discovery_timeout: 10s

    # After
    runtime:
    scheduler:
    partition_assignment_interval: 30s
    max_assignments_per_interval: 16
    partition_discovery_timeout: 10s
  • S3 metadata columns renamed: location, last_modified, size โ†’ _location, _last_modified, _size.

  • Default query memory limit changed: Increased from 70% to 90%.

  • Metric renames: accelerated_refresh metrics renamed to acceleration_refresh; last_refresh_time gauge renamed to include the milliseconds unit.

  • DuckDB parameter rename: partitioned_write_flush_threshold โ†’ partitioned_write_flush_threshold_rows.

  • /v1/search API: Always returns an array in matches, even for single results.

  • /v1/evals API removed.

  • Perplexity model provider removed.

  • x.ai model endpoint: x.ai models exclusively use the /v1/responses endpoint.

Upgrade Guide from v1.xโ€‹

Most v1 spicepods continue to work on v2.0 โ€” v1 remains supported and deprecated fields auto-migrate at load time โ€” so many deployments can upgrade by updating the binary or image alone. The steps below cover the breaking changes that may require manual action. Review each before upgrading a production deployment.

1. Build, image, and platform changesโ€‹

  • Models are now included by default. The separate models build variant (and the corresponding -models image tags) has been removed; local LLM inference is always included in the default build and image. If your deployment pinned a models build or -models-tagged image, switch to the default build/image.
  • Native Windows builds are removed. Use WSL for local Windows development.

spice init now creates version: v2 spicepods. v1 spicepods remain supported with automatic migration, but v1beta1 is no longer accepted. To move to v2, set version: v2 and update the following fields โ€” each auto-migrates from v1, but updating now clears the deprecation:

v1 (deprecated)v2 (preferred)
runtime.results_cacheruntime.caching.sql_results (cache_max_size โ†’ max_size)
runtime.memory_limitruntime.query.memory_limit
runtime.temp_directoryruntime.query.temp_directory
dataset.invalid_type_actiondataset.unsupported_type_action

3. Update changed configurationโ€‹

  • DuckDB parameter rename: partitioned_write_flush_threshold โ†’ partitioned_write_flush_threshold_rows.
  • Default query memory limit raised from 70% to 90%. If you relied on the previous default to leave headroom for other processes on the host, set it explicitly via runtime.query.memory_limit.

4. Update queries and API clientsโ€‹

  • S3 metadata columns renamed: location, last_modified, size โ†’ _location, _last_modified, _size. Update any queries that reference these columns.
  • /v1/search always returns an array in matches, even for a single result. Update clients that assumed a scalar value.
  • /v1/evals API removed. Remove integrations that depend on it.

5. Update model providersโ€‹

  • Perplexity model provider removed. Re-point affected models to another provider.
  • x.ai models use the /v1/responses endpoint exclusively. Ensure x.ai integrations target the Responses API.

6. Update observabilityโ€‹

  • Metric renames: accelerated_refresh โ†’ acceleration_refresh, and the last_refresh_time gauge is renamed to include the milliseconds unit. Update dashboards and alerts that reference these metric names.

After updating, restart the runtime and verify datasets and models report ready via /v1/datasets?status=true and /v1/models?status=true (the CLI shows a Ready/ERROR column).

Cookbook Updatesโ€‹

New Spice Cookbook recipes added during the v2.0 release cycle:

The Spice Cookbook includes more than 100 recipes to help you get started with Spice quickly and easily.

Upgradingโ€‹

To upgrade to v2.0.0, use one of the following methods:

CLI:

spice upgrade

Homebrew:

brew upgrade spiceai/spiceai/spice

Docker:

Pull the spiceai/spiceai:2.0.0 image:

docker pull spiceai/spiceai:2.0.0

For available tags, see DockerHub.

Helm:

helm repo update
helm upgrade spiceai spiceai/spiceai --version 2.0.0

AWS Marketplace:

Spice is available in the AWS Marketplace.

What's Changedโ€‹

Changelogโ€‹

  • Add TPC-DS integration tests with S3 source and PostgreSQL acceleration by @phillipleblanc in #9006
  • fix(tests): fix flaky/slow/failing unit tests by @phillipleblanc in #9009
  • fix: Update benchmark snapshots for DF51 upgrade by @app/github-actions in #9008
  • fix: add feature gate to rrf TEST_EMBEDDING_MODEL by @phillipleblanc in #9017
  • fix: features check by @phillipleblanc in #9014
  • fix: Enable Cayenne acceleration snapshots by @lukekim in #9020
  • URL table support by @lukekim in #9018
  • ScyllaDB key filter by @lukekim in #8997
  • fix: Schema mismatch when using column projection with HTTP caching by @phillipleblanc in #9021
  • Add more tests for HTTP caching with columns selection by @sgrebnov in #9025
  • HTTP cache snapshots: default to time_interval and fix snapshots_creation_policy: on_change by @sgrebnov in #9026
  • Fix duplicate snapshot creation on startup by @sgrebnov in #9029
  • Add ScyllaDB and SMB to the README table by @krinart in #9034
  • Remove waiting for runtime to be ready before creating snapshot by @krinart in #9033
  • Fix snapshot on_change policy to skip when no writes occurred by @sgrebnov in #9028
  • Release notes for release release/1.11.0-rc.2 by @krinart in #9016
  • ci: use arduino/setup-protoc for official protobuf compiler by @phillipleblanc in #9036
  • ci: install unzip on aarch64 runner for arduino/setup-protoc by @phillipleblanc in #9038
  • fix: don't fail release if upload to minio fails by @phillipleblanc in #9039
  • Add missing protoc step to setup-cc action by @krinart in #9041
  • fix: Update Search integration test snapshots by @app/github-actions in #9013
  • Fix formula_1 and codebase_community in bird-bench by @Jeadie in #9000
  • Cayenne S3 Express One Zone improvements by @lukekim in #9015
  • Add zlib1g-dev to CI by @lukekim in #9052
  • Improve validation and logging for hash indexes by @lukekim in #9047
  • Upgrade Vortex with CASE-WHEN by @lukekim in #9051
  • x.ai models now exclusively use /v1/responses endpoint by @lukekim in #9400
  • Improvements for snapshot schema comparison by @krinart in #9401
  • v2.0 breaking changes by @lukekim in #9233
  • Create PartitionManagementTask for scheduler to update accelerated table partition assignments by @Jeadie in #9378
  • refactor(Cayenne): route all write orchestration through CayenneDataSink by @sgrebnov in #9402
  • Refactor benchmark to use QueryExecutor trait by @Jeadie in #9418
  • feat: Add spidapter build and release workflow by @peasee in #9427
  • Testoperator: add support for api-key when connecting to external spice instance by @sgrebnov in #9421
  • Initial implementation of Ducklake catalog & data connectors by @lukekim in #9083
  • Require aws_lc_rs since jsonwebtoken upgrade by @Jeadie in #9426
  • feat: Add spidapter tool by @peasee in #9425
  • Add release notes for 1.11.2 patch release by @sgrebnov in #9430
  • feat(spidapter): integrate system-adapter-protocol with SCP provisioning by @phillipleblanc in #9434
  • Add DuckLake TPCH E2E workflow and federated Spicepod configuration by @lukekim in #9431
  • fix(spidapter): use Flight handshake auth instead of x-api-key header by @phillipleblanc in #9435
  • [spidapter] Keep only what sparks joy by @Jeadie in #9439
  • Refactor binary operator balancing by @Jeadie in #9424
  • feat: Add Iceberg DDL support (CREATE TABLE / DROP TABLE) for default catalog override by @phillipleblanc in #9440
  • Fix Flight SQL schema consistency: expand view types and verify field names by @sgrebnov in #9438
  • Update spidapter for new system-adapter-protocol by @sgrebnov in #9442
  • docs: fix typos and syntax errors in style guide and error handling docs by @cluster2600 in #9445
  • Add acceleration refresh ingestion metrics (rows_written, bytes_written) by @phillipleblanc in #9461
  • Refactor(Cayenne): Replace CatalogError and string based errors with Snafu errors by @sgrebnov in #9403
  • Replace deprecated claude-3-5-haiku-latest with claude-haiku-4-5 by @Jeadie in #9492
  • Fix #9481: Preserve schema in results cache for empty query results by @phillipleblanc in #9485
  • Fix partition by serializing by @Jeadie in #9474
  • query: reconcile execution stream nullability with logical plan schema by @phillipleblanc in #9486
  • initial spice-cloud-client crate and spice cloud metrics --app <app-name>. by @Jeadie in #9480
  • feat: Return dataset error message in datasets API by @peasee in #9487
  • Spicebench by @lukekim in #9447
  • build(deps): consolidate dependabot dependency updates by @phillipleblanc in #9504
  • fix(cluster): route non-partitioned accelerated tables in distributed mode by @phillipleblanc in #9508
  • Enable core scalar UDFs in refresh SQL by @sgrebnov in #9502
  • Fix metrics in Spidapter again by @Jeadie in #9497
  • fix(cluster): tolerate Completed->status propagation race in distributed query handle by @phillipleblanc in #9510
  • feat: Support distributed ingestion in cayenne catalog by @peasee in #9506
  • Fix Cayenne duplicate primary keys after DELETE + UPSERT CDC sequences by @krinart in #9494
  • fix(cluster): rewrite table scans inside subqueries for distributed execution by @phillipleblanc in #9518
  • fix: Set catalog mode to readwritecreate in spidapter by @peasee in #9519
  • Upgrade AWS SDK crates & set APN user-agent in AWS SDK credential bridge by @lukekim in #8328
  • feat(runtime): add runtime ready_state on_registration semantics by @lukekim in #9522
  • fix: Add spidapter post-setup retries by @peasee in #9526
  • Make partition discovery more robust and make initialization non-blocking by @sgrebnov in #9499
  • Make lint-rust-fix support targeted packages and features by @Jeadie in #9511
  • Handle new Cloud SCP API by @Jeadie in #9532
  • Refactor and simplify streaming benchmarks by @krinart in #9405
  • fix: ensure spidapter only increments attempts on failures by @peasee in #9534
  • feat: Support specifying app resources in spidapter by @peasee in #9536
  • test(runtime): Spice Cayenne DDL integration test by @lukekim in #9535
  • fix: Handle schema evolution mismatch errors during data refresh by @lukekim in #9527
  • fix: resolve clippy lint warnings by @phillipleblanc in #9547
  • pr-builds --tag <TAG> for build_and_release.yml by @Jeadie in #9507
  • Add --output flag to spice login with env/json/keychain modes by @Jeadie in #9541
  • Don't use 'PartitionedTableScanRewrite' in async distributed query by @Jeadie in #9548
  • feat(spidapter): add local backend mode with single executor by @phillipleblanc in #9531
  • support chat template in HF by @Jeadie in #9543
  • fix(cayenne): stream PK retention deletes and run OOM regression in CI by @phillipleblanc in #9533
  • cayenne: Staged append writes to prevent partial writes and data loss on stream error by @sgrebnov in #9491
  • AcceleratedTable::scan use FederatedTable::scan when ClusterRole::Scheduler by @Jeadie in #9550
  • Upgrade to delta-kernel-rs v0.18.2 by @lukekim in #9528
  • Run cayenne tests as part of PR CI by @sgrebnov in #9554
  • Upgrade to DataFusion v52.2.0 by @lukekim in #9419
  • Remove Snapshot Compaction + Add snapshot existence check by @krinart in #9523
  • Update dependencies by @lukekim in #9566
  • fix: Update benchmark snapshots by @app/github-actions in #9565
  • fix: Compare Cayenne table configuration on startup by @peasee in #9529
  • Make Refresh::refresh_sql more robust to alterations over time. by @Jeadie in #9549
  • fix: Update datafusion-table-providers dependency to latest revision by @lukekim in #9574
  • Unset AWS_ENDPOINT_URL when empty by @krinart in #9575
  • fix: allow BytesProcessedExec repartitioning for unordered input by @lukekim in #9540
  • Sanitize DataFusion errors by @lukekim in #9530
  • Add conditional logging for partition assignments by @Jeadie in #9577
  • use 'properly early exit on SIGTERM' by @Jeadie in #9573
  • Update datafusion to 52.2.0 by @phillipleblanc in #9582
  • Ensure we query one and only one partition per request by @Jeadie in #9416
  • feat: Add support for Spicepod version v2 by @lukekim in #9583
  • [SpiceDQ] Improve error messages; Avoid race condition on allocate_initial_partitions. by @Jeadie in #9579
  • Update ballista dependencies to latest 52.0.0 revision by @lukekim in #9581
  • Fix Databricks spark_connect mode always disabled by @phillipleblanc in #9586
  • Support partitioning in Arrow accelerator by @Jeadie in #9571
  • Fix spice query CLI response deserialization by @phillipleblanc in #9588
  • fix: Update benchmark snapshots by @app/github-actions in #9584
  • fix: Share RuntimeEnv across Cayenne read/write/delete paths for targeted list_files_cache invalidation by @sgrebnov in #9589
  • feat: Add file:// state_location support for async queries scheduler by @phillipleblanc in #9590
  • Update endgame links by @krinart in #9598
  • ci: fix E2E CLI upgrade test to use latest release for spiced download by @phillipleblanc in #9613
  • fix(DF): Lazily initialize BatchCoalescer in RepartitionExec to avoid schema type mismatch by @sgrebnov in #9623
  • feat: Implement catalog connectors for various databases by @lukekim in #9509
  • Refactor and clean up code across multiple crates by @lukekim in #9620
  • fix: Improve error handling for distributed mode and state_location configuration by @lukekim in #9611
  • Properly install postgres in install-postgres action by @krinart in #9629
  • fix: Use Python venv for schema validation in CI by @phillipleblanc in #9637
  • Update spicepod.schema.json by @app/github-actions in #9640
  • Update testoperator dispatch to use release/2.0 branch by @phillipleblanc in #9641
  • fix: Align CUDA asset names in Dockerfile and install tests with build output by @phillipleblanc in #9639
  • Fix expect test scripts in E2E Installation AI test by @sgrebnov in #9643
  • testoperator for partitioned arrow accelerator by @Jeadie in #9635
  • Remove default 1s refresh_check_interval from spidapter for hive datasets by @phillipleblanc in #9645
  • Fix scheduler panic and cancel race condition by @phillipleblanc in #9644
  • Align Spice.ai connector parameter names across catalog/data connectors by @lukekim in #9632
  • docs: update distribution details and add NAS support in release notes by @lukekim in #9650
  • Enable postgres-accel in CI builds for benchmarks by @sgrebnov in #9649
  • perf: Cache Turso metastore connection across operations by @penberg in #9646
  • Add 'scheduler_state_location' to spidapter by @Jeadie in #9655
  • Implement Cayenne S3 Express multi-zone live test with data validation by @lukekim in #9631
  • chore(spidapter): bump default memory limit from 8Gi to 32Gi by @phillipleblanc in #9661
  • perf: Use prepare_cached() in Turso and SQLite metastore backends by @penberg in #9662
  • Improve CDC cache invalidation by @krinart in #9651
  • Refactor Cayenne IDs to use UUIDv7 strings by @lukekim in #9667
  • fix: add liveness check for dead executors in partition routing by @Jeadie in #9657
  • fix(s3): Fix metadata column schema mismatches in projected queries by @sgrebnov in #9664
  • s3_metadata_columns tests: include test for location outside table prefix by @sgrebnov in #9676
  • docs: Update DuckDB, GCS, Git connector and Cayenne documentation by @lukekim in #9671
  • Add s3_url_style support for S3 connector URL addressing by @phillipleblanc in #9642
  • Consolidate E2E workflows and require WSL for Windows runtime by @lukekim in #9660
  • Upgrade to Rust v1.93.1 by @lukekim in #9669
  • Security fixes and improvements by @lukekim in #9666
  • feat(flight): add DoPut rows/bytes written metrics for DoPut ETL ingestion tracking by @phillipleblanc in #9663
  • Skip caching http error response + add response_headers by @krinart in #9670
  • refactor: Remove v1/evals functionality by @Jeadie in #9420
  • Make a test harness for Distributed Spice integration tests by @Jeadie in #9615
  • Enable on_zero_results: use_source for views by @krinart in #9699
  • fix(spidapter): Lower memory limit, passthrough AWS secrets, override flight URL by @peasee in #9704
  • Show an error on a shared acceleration file with snapshots enabled by @krinart in #9698
  • Fixes for anthropic by @Jeadie in #9707
  • Use max_partitions_per_executor in allocate_initial_partitions by @Jeadie in #9659
  • [SpiceDQ] Accelerations must have partition key by @Jeadie in #9711
  • Upgrade to Turso v0.5 by @lukekim in #9628
  • feat: Rename metadata columns to _location, _last_modified, _size by @phillipleblanc in #9712
  • fix: bump datafusion-ballista to fix BatchCoalescer schema mismatch panic by @phillipleblanc in #9716
  • fix: Ensure Cayenne respects target file size by @peasee in #9730
  • refactor: Make DDL preprocessing generic from Iceberg DDL processing by @peasee in #9731
  • [SpiceDQ] Distribute query of Cayenne Catalog to executors with data by @Jeadie in #9727
  • Properly set primary_keys/on_conflict for Cayenne tables by @krinart in #9739
  • Add executor resource and replica support to cloud app config by @ewgenius in #9734
  • feat: Support PARTITION BY in Cayenne Catalog table creation by @peasee in #9741
  • Update datafusion and related packages to version 52.3.0 by @lukekim in #9708
  • Route FlightSQL statement updates through QueryBuilder by @phillipleblanc in #9754
  • JSON file format improvements by @lukekim in #9743
  • [SpiceDQ] Partition Cayenne catalogs writes through to executors by @Jeadie in #9737
  • Update to DF v52.3.0 versions of datafusion & datafusion-tableproviders by @lukekim in #9756
  • Make S3 metadata column handling more robust by @sgrebnov in #9762
  • Fetch API keys from dedicated endpoint instead of apps response by @phillipleblanc in #9767
  • Update arrow-rs, datafusion-federation, and datafusion-table-providers dependencies by @phillipleblanc in #9769
  • Chunk metastore batch inserts to respect SQLite parameter limits by @phillipleblanc in #9770
  • Improve JSON SODA support by @lukekim in #9795
  • Add ADBC Data Connector by @lukekim in #9723
  • docs: Release Cayenne as RC by @peasee in #9766
  • cli[feat]: cloud mode to use region-specific endpoints by @lukekim in #9803
  • Include updated JSON formats in HTTPS connector by @lukekim in #9800
  • Flight DoPut: Partition-aware write-through forwarding by @Jeadie in #9759
  • Pass through authentication to ADBC connector by @lukekim in #9801
  • Move scheduler_state_location from adapter metadata to env var by @phillipleblanc in #9802
  • Fix Cayenne DoPut upsert returning stale data after 3+ writes by @phillipleblanc in #9806
  • Fix JSON column projection producing schema mismatch by @sgrebnov in #9811
  • Fix http connector by @krinart in #9818
  • Fix ADBC Connector build and test by @lukekim in #9813
  • Support update & delete DML for distributed cayenne catalog by @Jeadie in #9805
  • Set allow_http param when S3 endpoint uses http scheme by @phillipleblanc in #9834
  • fix: Cayenne Catalog DDL requires a connected executor in distributed mode by @Jeadie in #9838
  • fix: Add conditional put support for file:// scheduler state location by @Jeadie in #9842
  • fix: Require the DDL primary key contain the partition key by @Jeadie in #9844
  • fix: Databricks SQL Warehouse schema retrieval with INLINE disposition and async retry by @lukekim in #9846
  • Filter pushdown improvements for SqlTable by @lukekim in #9852
  • feat: add iam_role_source parameter for AWS credential configuration by @lukekim in #9854
  • Fix ODBC queries silently returning 0 rows on query failure by @lukekim in #9864
  • feat(adbc): Add ADBC catalog connector with schema/table discovery by @lukekim in #9865
  • Make Turso SQL unparsing more robust and fix date comparisons by @lukekim in #9871
  • Fix Flight/FlightSQL filter precedence and mutable query consistency by @lukekim in #9876
  • Partial Aggregation optimisation for FlightSQLExec by @lukekim in #9882
  • fix: v1/responses API preserves client instructions when system_prompt is set by @Jeadie in #9884
  • feat: emit scheduler_active_executors_count and use it in spidapter by @Jeadie in #9885
  • feat: Add custom auth header support for GraphQL connector by @krinart in #9899
  • Add --endpoint flag to spice run with scheme-based routing by @lukekim in #9903
  • When executor connects, send DDL for existing tables by @Jeadie in #9904
  • fix: Improve ADBC driver shutdown handling and error classification by @lukekim in #9905
  • fix: require all executors to succeed for distributed DML (DELETE/UPDATE) forwarding by @Jeadie in #9908
  • fix(cayenne catalog): fix catalog refresh race condition causing duplicate primary keys by @Jeadie in #9909
  • Remove Perplexity support by @Jeadie in #9910
  • Fix refresh_sql support for debezium constraints by @krinart in #9912
  • Implement DML for DynamoDBTableProvider by @lukekim in #9915
  • chore: Update iceberg-rust fork to v0.9 by @lukekim in #9917
  • Run physical optimizer on FallbackOnZeroResultsScanExec fallback plan by @sgrebnov in #9927
  • Improve Databricks error message when dataset has no columns by @sgrebnov in #9928
  • Delta Lake: fix data skipping for >= timestamp predicates by @sgrebnov in #9932
  • fix: Ensure distributed Cayenne DML inserts are forwarded to executors by @Jeadie in #9948
  • Add full query federation support for ADBC data connector by @lukekim in #9953
  • Make time_format deserialization case-insensitive by @claudespice in #9955
  • Hash ADBC join-pushdown context to prevent credential leaks in EXPLAIN plans by @lukekim in #9956
  • fix: Normalize Arrow Dictionary types for DuckDB and SQLite acceleration by @sgrebnov in #9959
  • ADBC BigQuery: Improve BigQuery dialect date/time and interval SQL generation by @lukekim in #9967
  • Make BigQueryDialect more robust and add BigQuery TPC-H benchmark support by @lukekim in #9969
  • fix: Show proper unauthorized error instead of misleading runtime unavailable by @lukekim in #9972
  • fix: Enforce target_chunk_size as hard maximum in chunking by @lukekim in #9973
  • Add caching retention by @krinart in #9984
  • fix: improve Databricks schema error detection and messages by @lukekim in #9987
  • fix: Set default S3 region for opendal operator and fix cayenne nextest by @phillipleblanc in #9995
  • fix(PostgreSQL): fix schema discovery for PostgreSQL partitioned tables by @sgrebnov in #9997
  • fix: Defer cache size check until after encoding for compressed results by @krinart in #10001
  • fix: Rewrite numeric BETWEEN to CAST(AS REAL) for Turso by @lukekim in #10003
  • fix: Handle integer time columns in append refresh for all accelerators by @sgrebnov in #10004
  • fix: preserve s3a:// scheme when building OpenDalStorageFactory with custom endpoint by @phillipleblanc in #10006
  • Fix ISO8601 time_format with Vortex/Cayenne append refresh by @sgrebnov in #10009
  • fix: Address data correctness bugs found in audit by @sgrebnov in #10015
  • fix(federation): fix SQL unparsing for Inexact filter pushdown with alias by @lukekim in #10017
  • Improve GitHub connector ref handling and resilience by @lukekim in #10023
  • feat: Add spice completions command for shell completion generation by @lukekim in #10024
  • fix: Fix data correctness bugs in DynamoDB decimal conversion and GraphQL pagination by @sgrebnov in #10054
  • Implement RefreshDataset for distributed control stream by @Jeadie in #10055
  • perf: Improve S3 parquet read performance by @sgrebnov in #10064
  • fix: Prevent write-through stalls and preserve PartitionTableProvider during catalog refresh by @Jeadie in #10066
  • feat: spice completions auto-detects shell directory and writes file by @lukekim in #10068
  • fix: Bug in DynamoDB, GraphQL, and ISO8601 refresh data handling by @sgrebnov in #10063
  • fix partial aggregation deduplication on string checking by @lukekim in #10078
  • fix: add MetastoreTransaction support to prevent concurrent transaction conflicts by @phillipleblanc in #10080
  • fix: Use GreedyMemoryPool, add spidapter query memory limit arg by @phillipleblanc in #10082
  • feat: Add metrics for EXPLAIN ANALYZE in FlightSQLExec by @lukekim in #10084
  • Use strict cast in try_cast_to to error on overflow instead of silent NULL by @sgrebnov in #10104
  • feat: Implement MERGE INTO for Cayenne catalog tables by @peasee in #10105
  • feat: Add distributed MERGE INTO support for Cayenne catalog tables by @peasee in #10106
  • Improve JSON format auto-detection for single multi-line objects by @lukekim in #10107
  • Add mode: file_update acceleration mode by @krinart in #10108
  • Coerce unsupported Arrow types to Iceberg v2 equivalents in REST catalog API by @peasee in #10109
  • fix: Update default query memory limit to 90% from 70% by @phillipleblanc in #10112
  • feat: Add mTLS client auth support to spice sql REPL by @lukekim in #10113
  • fix(datafusion-federation): report error on overflow instead of silent NULL by @sgrebnov in #10124
  • fix: Prevent data loss in MERGE when source has duplicate keys by @peasee in #10126
  • feat: Add ClickHouse Date32 type support by @sgrebnov in #10132
  • Add Delta Lake column mapping support (Name/Id modes) by @sgrebnov in #10134
  • fix: Restore Turso numeric BETWEEN rewrite lost in DML revert by @lukekim in #10139
  • fix: Enable arm64 Linux builds with fp16 and lld workarounds by @lukekim in #10142
  • fix: remove double trailing slash in Unity Catalog storage locations by @sgrebnov in #10147
  • fix: Improve GitHub GraphQL client resilience and performance by @lukekim in #10151
  • Enable reqwest compression and optimize HTTP client settings by @lukekim in #10154
  • fix: executor startup failures by @Jeadie in #10155
  • feat: Distributed runtime.task_history support by @Jeadie in #10156
  • fix: Preserve timestamp timezone in DDL forwarding to executors by @peasee in #10159
  • feat: Per-model rate-limited concurrent AI UDF execution by @Jeadie in #10160
  • fix(Turso): Reject subquery/outer-ref filter pushdown in Turso provider by @lukekim in #10174
  • Fix linux/macos spice upgrade by @phillipleblanc in #10194
  • Improve CREATE TABLE LIKE error messages, success output, EXPLAIN, and validation by @peasee in #10203
  • fix: chunk MERGE delete filters and update Vortex for stack-safe IN-lists by @peasee in #10207
  • Propagate runtime.params.parquet_page_index to Delta Lake connector by @sgrebnov in #10209
  • Properly mark dataset as Ready on Scheduler by @Jeadie in #10215
  • fix: handle Utf8View/LargeUtf8 in GitHub connector ref filters by @lukekim in #10217
  • fix(databricks): Fix schema introspection and timestamp overflow by @lukekim in #10226
  • fix(databricks): Fix schema introspection failures for non-Unity-Catalog environments by @lukekim in #10227
  • feat: Add pagination support to HTTP data connector by @lukekim in #10228
  • feat(databricks): DESCRIBE TABLE fallback and source-native type parsing for Lakehouse Federation by @lukekim in #10229
  • fix(databricks): harden HTTP retries, compression, and token refresh by @lukekim in #10232
  • feat[helm chart]: Add support for ServiceAccount annotations and AWS IRSA example by @peasee in #9833
  • fix: Log warning and fall back gracefully on Cayenne config change by @krinart in #9092
  • fix: Handle engine mismatch gracefully in snapshot fallback loop by @krinart in #9187
  • fix: Full Text Search schema mismatch with ADBC connector by @lukekim in #10235
  • docs: Update v2.0.0-rc.2 release notes with latest changes by @lukekim in #10238
  • Fix append refresh dedup failure when refresh_sql selects column subset by @sgrebnov in #10225
  • Revert "Properly mark dataset as Ready on Scheduler (#10215)" by @sgrebnov in #10242
  • Fix failing merge conflicts for benchmarks by @krinart in #10247
  • fix(github): fetch commits for dynamic and slash refs by @lukekim in #10233
  • Upgrade DataFusion to v52.5.0-rc1 by @lukekim in #10249
  • Merge develop to trunk (2026-04-09) by @claudespice in #10248
  • fix: Validate embedding row_id columns during dataset init (fixes #8226) by @claudespice in #10208
  • fix: Update tpch benchmark snapshots for federated/glue[csv].yaml by @app/github-actions in #10244
  • feat(databricks): add resilience controls, UC awareness, and task history instrumentation by @lukekim in #10246
  • fix: Make PartitionManager resilient to bare vs fully qualified table references by @sgrebnov in #10257
  • fix: Update tpch benchmark snapshots for accelerated/s3[parquet]-cayenne[file].yaml by @app/github-actions in #10256
  • Merge develop to trunk (2026-04-10) by @claudespice in #10251
  • Improve Snowflake/ADBC dataset registration performance and observability by @lukekim in #10266
  • Fixes for kafka connector by @krinart in #10263
  • fix(runtime): gate otel code tags, suppress aws sdk noise, and unblock connector init by @lukekim in #10260
  • fix(runtime): avoid regionless AWS SDK loads by @lukekim in #10271
  • Add versioned release install workflow coverage by @lukekim in #10276
  • fix(runtime): handle HTTP JSON unions and spicepod reloads by @lukekim in #10277
  • Databricks UC permission prechecks: explicit denial as permanent error, ambiguous cases advisory by @lukekim in #10274
  • Revert component status changes re-introduced by develop merge (#10248) by @sgrebnov in #10293
  • Fix broken CI workflows by @ewgenius in #10294
  • Group dependabot updates by ecosystem by @lukekim in #10296
  • fix(tests): Replace flaky S3 Vectors snapshot tests with structural validation by @lukekim in #10301
  • Update test_github_workflows snapshot by @lukekim in #10304
  • fix(ci): fix Bedrock runner mismatch and snapshot auto-merge failure by @ewgenius in #10306
  • feat(http): Add map-to-array conversion and query-parameter pagination by @lukekim in #10295
  • New crate: datafusion-ddl by @Jeadie in #10205
  • Make Databricks UC permission checks advisory with structured error reporting by @lukekim in #10283
  • build(deps): bump the github-actions-dependencies group with 4 updates by @app/dependabot in #10298
  • fix: Clear cached plans on view updates by @peasee in #10312
  • build(deps): bump the aws-sdk group with 7 updates by @app/dependabot in #10299
  • Code out of runtime. by @Jeadie in #10178
  • fix: Respect function registry denies for accelerated table filter pushdown by @peasee in #10311
  • fix: Don't block heartbeat when all slots acquired by @peasee in #10322
  • fix: strip only outer parens in get_table_partition_expr_from_ctx by @Jeadie in #10323
  • Upgrade datafusion-table-providers with MongoDB SRV support by @lukekim in #10317
  • fix: Avoid pushing down bucketing partition expressions into executors by @peasee in #10324
  • Upgrade datafusion-table-providers to d1b911a5 and bump adbc to 0.23 by @lukekim in #10329
  • fix: Update Search integration test snapshots by @app/github-actions in #10308
  • Handle foreign table + Classic sql warehouse combination gracefully by @krinart in #10318
  • New crate datafusion-flightsql by @Jeadie in #10201
  • Set tantivy=warn unless very verbose logging by @Jeadie in #10338
  • Remove image registry and image name options from spidapter by @ewgenius in #10241
  • build(deps): bump sysinfo from 0.37.2 to 0.38.4 by @app/dependabot in #10291
  • build(deps): bump futures from 0.3.31 to 0.3.32 by @app/dependabot in #10289
  • New crate 'datafusion-dml' by @Jeadie in #10334
  • Jeadie/26 04 16/spice sql by @Jeadie in #10343
  • Add Teraswitch/Pittsburgh apt mirrors + retry config for CI runners by @lukekim in #10349
  • Implement sort pushdown and fix pushdown gaps across providers by @lukekim in #10337
  • Merge develop to trunk (2026-04-16) by @claudespice in #10345
  • Update candle and mistral.rs lock-step pins by @lukekim in #10278
  • docs: fix status badges in README by @lukekim in #10350
  • Migrate secrets to vars by @krinart in #10354
  • Add limit pushdown and improve sort pushdown for Oracle and MSSQL by @sgrebnov in #10351
  • Fix ubuntu mirror configuration by @ewgenius in #10359
  • fix: Increase throughput test default ready_wait from 30s to 300s (fixes #8207) by @claudespice in #10344
  • Add auth headers support to OTEL metrics exporter by @lukekim in #10347
  • fix(github): shrink GraphQL page size on gateway errors; lower comment defaults by @lukekim in #10355
  • Relax apt mirror substitution failure to warning in CI action by @ewgenius in #10361
  • feat(http): Add OAuth2 refresh-token auth to HTTP connector by @lukekim in #10348
  • Upgrade Rust toolchain to 1.94.1 by @lukekim in #10353
  • Handle order by and sort in PartitionedTableScanRewrite by @Jeadie in #9656
  • Fix OTEL Exporter by @krinart in #10363
  • Pin spiceai candle / TEI forks to merged revs; drop local [patch] overrides by @lukekim in #10362
  • Integrate spiceio and makefile_targets into pr.yml by @lukekim in #10357
  • ci: skip artifact compression for test binaries/archives by @lukekim in #10381
  • chore(deps): bump spiceai/candle, spiceai/mistral.rs, aws-lc-rs, tantivy, rand by @lukekim in #10379
  • Bump datafusion-table-providers (#10375) by @lukekim in #10384
  • fix: Update Search integration test snapshots by @app/github-actions in #10376
  • v2.0.0-rc.3 preparation by @ewgenius in #10382
  • fix(spicepod): JSON schema accepts string or {name: expr} for partition_by by @lukekim in #10352
  • fix: Use ROUND for Turso decimal BETWEEN comparisons (fixes #9872) by @claudespice in #10360
  • Revert "v2.0.0-rc.3 preparation" from trunk by @ewgenius in #10386
  • Add on_schema_resolved dataset ready state by @lukekim in #10368
  • feat: Add Elasticsearch data connector with hybrid search support by @lukekim in #10258
  • ci: bump test archive upload compression-level to 1 by @lukekim in #10388
  • feat(git-connector): promote Git connector to RC status by @lukekim in #10385
  • feat(postgres): stream WAL directly to Spice accelerators by @lukekim in #10364
  • Add schema decomposition to the HTTP connector by @lukekim in #10393
  • fix(cayenne): Skip catalog refresh state reload for existing providers by @sgrebnov in #10396
  • Make cayenne-flightsql tool by @Jeadie in #10356
  • build(deps): bump the github-actions-dependencies group with 2 updates by @app/dependabot in #10398
  • Update openapi.json by @app/github-actions in #10272
  • Merge develop to trunk โ€” 2026-04-19 by @claudespice in #10407
  • feat(otel): default OTLP push exporter to delta temporality by @phillipleblanc in #10412
  • fix: Restore analyzer rule ordering to run federation before type coercion by @sgrebnov in #10415
  • fix: Map Utf8/LargeUtf8 to STRING in Databricks/Spark SQL dialects by @sgrebnov in #10420
  • feat(otel): add metric name prefix at runtime.telemetry.metric_prefix by @phillipleblanc in #10418
  • fix: Map LargeUtf8 to VARCHAR in Athena ODBC dialect by @sgrebnov in #10419
  • feat(cluster): connector-driven object store registration on executors by @phillipleblanc in #10414
  • build(deps): bump ubuntu from 22.04 to 24.04 in the docker-dependencies group by @app/dependabot in #10397
  • fix: Update benchmark snapshots Apr 20 by @app/github-actions in #10417
  • feat(otel): apply runtime.telemetry.properties as resource attributes on exported metrics by @phillipleblanc in #10416
  • Publish RC releases to DockerHub; upgrade runners to ubuntu-24.04 by @lukekim in #10428
  • feat: Add Azure Cosmos DB (NoSQL) data connector (RC) by @lukekim in #10392
  • feat(datafusion): flatten_json_properties + json_tree UDTFs by @lukekim in #10406
  • Harden /v1/tools and /v1/nsql against unauthenticated / LLM-driven SQL by @lukekim in #10365
  • feat(embeddings): multi-vector embeddings with MaxSim + late-interaction by @lukekim in #10408
  • Update GH runners for CUDA builds by @ewgenius in #10432
  • fix(delta_lake): register object stores on cluster executors by @phillipleblanc in #10436
  • DF-native DML by @krinart in #10327
  • ci: run Build and Test on spiceai-macos; split install jobs by profile by @lukekim in #10434
  • Improve search UDTFs: text_search, vector_search, rrf by @lukekim in #10387
  • fix(model2vec): Improve robustness of model loading for sentence-transformers layouts by @sgrebnov in #10444
  • Merge develop to trunk โ€” 2026-04-21 by @claudespice in #10448
  • Enable filter pushdown for vector_search UDTF by @sgrebnov in #10447
  • Support Snowflake OBJECT, MAP, GEOGRAPHY, GEOMETRY, VECTOR, TIMESTAMP_LTZ types by @lukekim in #10451
  • Fix Databricks tests by @krinart in #10449
  • fix(cluster): forward register_object_stores through connector wrappers by @phillipleblanc in #10460
  • Fixes for vector-search by @krinart in #10455
  • Add expand_maps option and flatten_json UDTF by @lukekim in #10452
  • fix: Update Search integration test snapshots by @app/github-actions in #10458
  • Fix physical codec decode ambiguity for empty protobuf messages by @sgrebnov in #10466
  • chore(logging): demote s3_single_file_cached skip refresh log to debug by @phillipleblanc in #10467
  • Enable filter pushdown for rrf UDTF by @sgrebnov in #10465
  • feat(cluster): consolidate distributed state into cluster.json by @phillipleblanc in #10463
  • feat(cayenne): Add column statistics and data inlining by @lukekim in #10314
  • docs(copilot): flag missing wrapper delegation when adding default trait methods by @phillipleblanc in #10461
  • Wire Elasticsearch vector engine write path through acceleration by @lukekim in #10453
  • Add helm lint CI by @ewgenius in #10468
  • Fix Azure and GCS acceleration snapshot object store credential handling by @phillipleblanc in #10486
  • Update spicepod.schema.json by @app/github-actions in #10485
  • fix(secrets): harden AWS Secrets Manager secret store by @lukekim in #10478
  • Update datafusion-ballista crate by @sgrebnov in #10488
  • feat(secrets): add ParameterSpec and more params for AWS secrets manager by @phillipleblanc in #10487
  • Add rerank UDTF for hybrid search with query auto-propagation by @lukekim in #10469
  • Fix flatten_json_properties by @krinart in #10475
  • fix: preserve field and schema metadata in expand_views_schema by @claudespice in #10494
  • Upgrade rmcp to upstream 1.5.0; switch MCP server to Streamable HTTP by @lukekim in #10491
  • fix: handle Snowflake TIMESTAMP_LTZ wire format and prevent nanosecond overflow by @claudespice in #10493
  • Lint parity in Makefile by @krinart in #10492
  • Add connect_timeout/client_timeout params to Databricks sql_warehouse mode by @lukekim in #10495
  • fix(tracing): suppress opentelemetry INFO logs at all verbosity levels by @lukekim in #10497
  • DynamoDB DML by @krinart in #10470
  • feat(cayenne): native vector search via SIMD similarity UDFs by @lukekim in #10456
  • fix(cli): suppress banner for all JSON-producing cloud subcommands (fixes #10498) by @claudespice in #10510
  • fix(deps): bump openssl to 0.10.78 by @phillipleblanc in #10509
  • fix(s3): quiet AWS SDK credential probe when no region is configured by @phillipleblanc in #10506
  • fix(cdc): emit ready signal on caught-up Kafka/Debezium streams (#5201) by @phillipleblanc in #10504
  • runtime-cluster crate + Run partition discovery before forwarding refresh to executors by @krinart in #10490
  • Update lint-rust target to use --keep-going by @Jeadie in #10508
  • Add TPC-H SF100 s3[parquet]-duckdb[file] benchmark spicepod by @lukekim in #10524
  • Remove dev-profile install steps from pr.yml by @Jeadie in #10507
  • fix: add missing NULL check on Timestamp path in append refresh by @claudespice in #10518
  • fix: return error on Decimal128/256 overflow instead of silently dropping scale by @claudespice in #10519
  • fix: delegate update and delete_from in IndexedTableProvider and EmbeddingTable by @claudespice in #10520
  • feat(devx): make config errors, CLI, and REPL lead users to success by @lukekim in #10489
  • fix(rerank): defer execution to RerankExec, enable filters and projection pushdown by @sgrebnov in #10514
  • fix(llms): support Gemma models with missing attention_bias config field by @lukekim in #10523
  • Fix vector_search silently ignoring named limit/column/include_score args by @sgrebnov in #10527
  • fix: split unsupported filters locally in scan() for UseSource mode by @ewgenius in #10528
  • feat(secrets): add Azure Key Vault secret store by @lukekim in #10496
  • Bump mistralrs by @krinart in #10532
  • Fix benchmark configurations and CI build issues by @sgrebnov in #10535
  • Fix catalog query overrides for MySQL and MSSQL benchmarks by @sgrebnov in #10543
  • For Cayenne, preserve matched columns for MERGE ... ON <cols> by @Jeadie in #10340
  • build(deps): bump the aws-sdk group across 1 directory with 5 updates by @app/dependabot in #10538
  • docs: update AI agent instructions (git workflow + Rust 1.94) by @lukekim in #10544
  • fix: Update tpch benchmark snapshots by @app/github-actions in #10529
  • fix: Update tpch benchmark snapshots for accelerated/s3[parquet]-duckdb[file].yaml by @app/github-actions in #10525
  • Extract runtime-datafusion from runtime by @krinart in #10545
  • Use generic DML extension planner for Cayenne by @Jeadie in #10437
  • fix: Update Search integration test snapshots by @app/github-actions in #10552
  • Fix security and correctness audit issues by @lukekim in #10526
  • fix(MySQL): revert MySQL result column reorder to fix federated query failures by @sgrebnov in #10557
  • Fix protoc installation by @krinart in #10566
  • fix: Disable Ballista dynamic filters on HashJoinExec by @peasee in #10548
  • Support views on DDL catalogs by @Jeadie in #10554
  • Update datafusion by @Jeadie in #10422
  • Improve full-text search indexing performance by @sgrebnov in #10464
  • feat(mysql): add mysql_zero_date_behavior parameter (null|error) by @phillipleblanc in #10573
  • fix(snowflake): declare private_key in connector PARAMETERS (fixes #10517) by @claudespice in #10559
  • Honour CARGO_TARGET_DIR in Makefiles by @Jeadie in #10569
  • Enable cosine_distance pushdown to DuckDB accelerator via array_cosine_distance by @sgrebnov in #10564
  • fix: Update test snapshots by @app/github-actions in #10570
  • fix: Update tpch benchmark snapshots by @app/github-actions in #10560
  • feat(snapshots): make snapshots an optional feature by @phillipleblanc in #10574
  • Enforce read-only API key restrictions on Flight DoGet and async query paths by @Jeadie in #10551
  • Improved security posture on Github workflows by @Jeadie in #10556
  • fix: Update datafusion-table-providers to improve SqlTable filter pushdown by @sgrebnov in #10595
  • feat(secrets): add HashiCorp Vault secret store by @phillipleblanc in #10561
  • fix: delegate update() in UpsertDedupTableProvider to inner provider by @claudespice in #10593
  • Add DuckDB vector engine support by @lukekim in #10562
  • Sharepoint - add object-store listing connector with expanded auth and write support by @lukekim in #10473
  • fix: Install protoc from source by @peasee in #10597
  • Enable DML support for PostgreSQL data connector by @phillipleblanc in #10446
  • feat(postgres): support inline PEM sslrootcert by @claudespice in #10578
  • Add foreign key metadata discovery to PostgreSQL Catalog by @sgrebnov in #10849
  • Add Snowflake DML support by @lukekim in #10747
  • Add MongoDB Change Streams support by @lukekim in #10813
  • Add user-defined functions by @lukekim in #10571
  • Add table user functions and gate HTTP servers by @lukekim in #10675
  • feat: add on-demand dataset loading by @phillipleblanc in #10629
  • feat(runtime): declared-schema deferred datasets by @phillipleblanc in #10669
  • feat(spicepod, runtime): add columns[].type / nullable + lenient type parser by @phillipleblanc in #10661
  • Replace external smb crate with internal SMB 3.1.1 client by @phillipleblanc in #10516
  • Add unified query cancellation across all paths by @lukekim in #10390
  • Add dynamic HTTP request headers by @lukekim in #10604
  • feat(http): Support dynamic HTTP connector request params from subqueries by @lukekim in #10636
  • feat(http): pass through HTTP metadata columns with JSON schema decomposition by @lukekim in #10679
  • Add nolimit HTTP pagination max pages by @lukekim in #10673
  • Add shared HTTP rate control for connectors by @lukekim in #10648
  • Use origin label instead of name for HTTP rate control metrics by @lukekim in #10689
  • fix(http): reject OR across different HTTP filter columns by @lukekim in #10625
  • Add provider-aware LLM prompt caching by @lukekim in #10645
  • Add searchable registry mode for LLM tools by @lukekim in #10647
  • feat: refresh_mode: snapshot + SQLite/Turso WAL flush + Cayenne metastore slice by @phillipleblanc in #10651
  • feat: per-principal cache namespacing for SQL/search/caching-accelerator by @lukekim in #10702
  • Add self-hosted Spice connector support by @phillipleblanc in #10546
  • Add Delta Lake Azure tenant parameter by @phillipleblanc in #10671
  • Support OAuth2 client credentials in 'spice cloud login' by @ewgenius in #10586
  • Add configurable allowed_hosts for MCP by @lukekim in #10638
  • fix: make Helm chart probes configurable by @peasee in #10696
  • Strip high-cardinality datasets dim from anonymous telemetry by @lukekim in #10711
  • feat(elasticsearch): direct FTS engine config + index lifecycle and ingestion controls by @lukekim in #10672
  • Add DuckDB HNSW vector index support for accelerated views by @sgrebnov in #10695
  • Rewrite DuckDB vector search SQL to activate HNSW_INDEX_SCAN by @sgrebnov in #10674
  • Fix DuckDB HNSW vector indexes lost after data refresh by @sgrebnov in #10668
  • Fix DuckDB DELETE/UPDATE on full and caching refresh mode datasets by @phillipleblanc in #10632
  • Fix DuckLake connector: downcast, module registration, schema discovery, and S3 credentials by @sgrebnov in #10650
  • Fix federation pushing denied functions inside subqueries to remote engines by @phillipleblanc in #10692
  • fix(caching): honour refresh_on_startup: always in caching mode by @phillipleblanc in #10594
  • fix(iceberg): rebuild storage factory when Hadoop catalog scheme is inferred by @sgrebnov in #10601
  • Pipeline CDC ingestion: overlap source reads with batch apply by @lukekim in #10676
  • fix: add NULL check to CDC primary key extraction by @lukekim in #10684
  • Properly handle nullability during CDC processing by @krinart in #10803
  • Flatten scheduler config and rename partition management โ†’ partition assignment by @lukekim in #10450
  • Improve NSQL UX and harden internal LLM tools by @lukekim in #10715
  • Support Responses API across model providers by @lukekim in #10724
  • Update xAI default model and handle Grok model retirements by @Jeadie in #10723
  • Improve cli table layout by @krinart in #10725
  • TLS cert hot-reload (mTLS plan M1) by @phillipleblanc in #10727
  • Fix DuckLake catalog include filter being ignored by @phillipleblanc in #10738
  • Promote DuckLake Catalog and Data Connector to Beta quality by @sgrebnov in #10743
  • feat(ducklake): Support INSERT on catalog tables with read_write access by @sgrebnov in #10744
  • perf(cdc): coalesce envelopes and overlap commits in apply pipeline by @lukekim in #10745
  • feat: Allow full version tags in spicepod version by @peasee in #10748
  • Add Arrow primary key upserts by @lukekim in #10749
  • fix(snapshot): keep refresh_mode snapshot read-only by @phillipleblanc in #10752
  • feat(tls): public mTLS for HTTP and Flight (channel + identity modes) by @phillipleblanc in #10753
  • perf(cayenne): lock-free deletion caches with bloom-prefiltered probe by @lukekim in #10756
  • fix(security): close API key timing-position leak and remote-UDF SSRF by @lukekim in #10757
  • Fix 'wait_until_dependent_tables_are_ready' for catalogs by @phillipleblanc in #10758
  • Fixes for views and resolved tables on 'spice refresh' CLI by @phillipleblanc in #10759
  • Implement FlightSQL CommandStatementSubstraitPlan support by @lukekim in #10761
  • feat(connectors): mTLS client cert support for flightsql and spiceai connectors by @phillipleblanc in #10764
  • Allow arbitrary filenames when specifying spicepod path + kind validation by @krinart in #10777
  • fix: ignore field metadata in schema compatibility check in index_table_scan by @Jeadie in #10778
  • Display pushed-down limits in EXPLAIN TREE output by @lukekim in #10779
  • fix: enable streaming append for Kafka with Cayenne accelerator by @lukekim in #10780
  • fix: bound chunked-index intermediate batch size to prevent OOM by @phillipleblanc in #10783
  • fix: label all columns in spice cloud metrics table output by @claudespice in #10784
  • fix: use checked arithmetic for Turso integer-millis timestamp read path by @claudespice in #10786
  • fix: use checked arithmetic in timestamp-to-nanosecond conversions by @claudespice in #10666
  • Upgrade to DuckDB v1.5.2 by @sgrebnov in #10788
  • Improve CDC ingestion performance by @lukekim in #10789
  • Fix tool_search/tool_invoke spans by @lukekim in #10791
  • Add Cayenne inline mutations and benchmark coverage by @lukekim in #10792
  • Ensure we always resolve table names in distributed mode/metadata by @Jeadie in #10793
  • Remove permanent errors from DynamoDB Streams by @krinart in #10794
  • Add expanded view mode for wide table display in SQL REPL by @lukekim in #10797
  • Fix Cayenne CDC schema mismatch error by @sgrebnov in #10800
  • Executors should create catalog tables on join by @Jeadie in #10807
  • Add compressed file support for listing connectors by @lukekim in #10809
  • Improve Cayenne mutation, scan, and inline memtable scaling by @lukekim in #10811
  • Add range fallback for large join filters by @lukekim in #10816
  • Improve Cayenne join filter pushdown by @lukekim in #10818
  • Synchronize Cayenne partition commits across partitions by @phillipleblanc in #10819
  • fix: Deny nondistributed cayenne catalog by @peasee in #10821
  • Enable parallel Cayenne Vortex writes by @lukekim in #10822
  • Expand Arrow type handling in formatting and Elasticsearch by @lukekim in #10825
  • Add response.output_text.delta to responses API by @krinart in #10828
  • feat(cayenne): add join filter propagation and no-spill Q21 planning by @lukekim in #10840
  • Upgrade Turso to v0.6.0 by @sgrebnov in #10843
  • feat(cli): add spice feedback command to open community Slack by @lukekim in #10856
  • Upgrade iceberg to v0.9.1 by @sgrebnov in #10859
  • feat(cluster): per-request executor readiness gate on /v1/ready by @phillipleblanc in #10860
  • fix: Require dim-side statistics for CayennePropagateFilterAcrossEquiJoinKeys by @sgrebnov in #10863
  • fix: Debezium schema evolution breaks dataset init on reload by @claudespice in #10144
  • fix(mssql): Push topK limit to SQL Server for non-nullable sort columns by @Jeadie in #10621
  • fix(ScyllaDB): disable physical filter pushdown by @sgrebnov in #10772
  • fix: handle typed NULLs and prevent overflow in DynamoDB DML type conversions by @krinart in #10511
  • fix: use InsertOp::Overwrite in DynamoDB bootstrap scan_and_overwrite_accelerator by @krinart in #10639
  • Improve DynamoDB Bootstrap performance by @krinart in #10616
  • fix: preserve field and schema metadata in Vortex type transformation by @lukekim in #10628
  • fix: GH connector - explicitly use AWS LC RS crypto provider for jwt by @phillipleblanc in #10619
  • fix: add snapshot mode guards to delete_from/update and delegate DML in SwappableTableProvider by @phillipleblanc in #10685
  • Persist HTTP rate-control state in object storage by @lukekim in #10697
  • Rate limit metrics HTTP endpoint by @lukekim in #10162
  • feat(geo): add optional spatial SQL UDF support by @lukekim in #10833
  • feat(cayenne): CDC throughput, compaction, scan caching, and benchmarks by @lukekim in #10852
  • fix(cayenne): fix Vortex panic on highly compressible data by @sgrebnov in #10855
  • fix(cayenne): Read live protected snapshots after cleanup grace period by @sgrebnov in #10901
  • fix: Disable Cayenne HashJoin rewriter optimizer by @sgrebnov in #10882
  • Fix GetFlightInfo vs DoGet Flight Schema by @krinart in #10864
  • fix(search): preserve column casing in /v1/search primary key plumbing by @claudespice in #10909
  • fix(object-store): dedupe s3 url style auto-detection log by @phillipleblanc in #10898
  • Improve Spice CLI manifest editing and direct command modes by @lukekim in #10815
  • Persist Kafka CDC offsets in sidecar tables by @lukekim in #10823
  • feat(task-history): record Ballista stages for distributed queries by @phillipleblanc in #10831
  • Add '#[deny(clippy::missing_trait_methods)]' to wrapper/delegation trait impls by @Jeadie in #10795
  • Optimize Cayenne catalog maintenance paths by @lukekim in #10904
  • Centralize DuckDB settings for accelerator by @ewgenius in #10895
  • deps(ballista): bump to 47e2b494 to fix S3 shuffle reads under cluster mode by @phillipleblanc in #10910
  • Authorization header + Bump async-openai + responses_adapter fix by @krinart in #10911
  • Tune accelerators by storage profile by @lukekim in #10913
  • feat: add dataset-level on_schema_change config by @lukekim in #10908
  • Handle NULL sentinel for nullable partition expressions by @Jeadie in #10880
  • fix: Remove Cayenne Catalog from catalog registration by @peasee in #10914
  • Add catalog name to foreign key metadata in postgres catalog by @Jeadie in #10917
  • Cayenne perf: eliminate redundant clones, PK point-lookup fanout fix, IN-list rewrite + microbench coverage by @lukekim in #10916
  • fix(turso-shared): retry on Turso BEGIN CONCURRENT "Write-write conflict" by @lukekim in #10946
  • Vendor Vortex DataFusion for Cayenne by @lukekim in #10933
  • perf(cayenne): background retention + enable CDC pipelining for retention-configured tables by @lukekim in #10936
  • feat(cayenne): scale metastore pool to 32 + vs_duckdb_scaling benches (1โ†’128 concurrency, sqlite + turso lanes) by @lukekim in #10943
  • feat(mcp): support auth for streamable HTTP tools by @phillipleblanc in #10927
  • Explicit error if v1/search requests a table without search index by @Jeadie in #10968
  • Fix spicepod loading failure when directory name contains dots by @sgrebnov in #10958
  • Extend append tests with arrow engine configurations by @sgrebnov in #10959
  • Remove dataset on_schema_change Policy from rc.5 release notes by @sgrebnov in #10964
  • Skip tpcds_q78 for Cayenne engine at SF100 by @sgrebnov in #10966
  • fix: Update benchmark snapshots May-20 by @app/github-actions in #10952
  • Fix #10951: UdtfExec invariant Vec lengths must match children count by @phillipleblanc in #10953
  • docs(release): update v2.0.0-rc.5 notes with latest trunk PRs by @lukekim in #10949
  • Remove eval related things for v2.0.0 by @Jeadie in #10945
  • build(deps): bump ubuntu from 24.04 to 26.04 in the docker-dependencies group by @app/dependabot in #10883
  • fix: Add publish = false to chbench-driver by @sgrebnov in #10939
  • [Bug] Timing between reconnect and AllocateInitialPartitions leaves connection without flight_sql_client by @Jeadie in #10805
  • Fix: refresh_mode: snapshot reports Ready with empty data when no snapshot exists by @sgrebnov in #10979
  • fix(cluster): gate scheduler readiness on executor partition loads by @phillipleblanc in #10992
  • fix: handle EXISTS/NOT EXISTS subqueries in federation analyzer by @sgrebnov in #10996
  • Refactor spice dataset configuration command by @Jeadie in #10999
  • fix: preserve field and schema metadata in Vortex physical schema calculation by @claudespice in #11013
  • fix: validate Snowflake account identifiers and auth config by @Jeadie in #11024
  • Fix Unity Catalog connector deserialization failure with OSS Unity Catalog by @ewgenius in #11026
  • feat(cayenne): allow inline writes with pending deletions (deletes/upserts) by @sgrebnov in #11031
  • Expose metadata descriptions via PostgreSQL UDFs by @lukekim in #11032
  • Remove default runtime features - enable explicitly in spiced by @phillipleblanc in #11037
  • feat(cayenne): fast-path CDC deletes by extracting PK values from filters by @sgrebnov in #11049
  • Cayenne optimizer rules: auto relevance test for q21-shape (all-Cayenne CH-Bench) and runtime rule selection by @lukekim in #11050
  • refactor(cdc): reduce CDC sub-batch splits for interleaved upsert/delete workloads by @sgrebnov in #11051
  • fix(snowflake): enforce function deny-list in federation pushdown by @claudespice in #11057
  • fix(mcp): trace external server tool calls in task history by @ewgenius in #11058
  • perf(cdc): Last-write-wins dedup in group_into_sub_batches to reduce sub-batch splits by @sgrebnov in #11059
  • PM edits to v2.0.0-rc5 by @lukekim in #11067
  • fix(snowflake): wire deny-list in extracted connector crate (#10703) by @claudespice in #11071
  • perf(cayenne): keep CDC upsert PK keysets resident to avoid per-batch full-table rebuilds by @lukekim in #11074
  • Fix metadata on search indexing by @Jeadie in #11080
  • feat(cayenne): merge-on-read position deletes for PK upsert tables + memory-pool accounting by @lukekim in #11085
  • perf(cayenne): scale CDC inline flush caps with memory + storage class by @lukekim in #11087
  • feat(cluster): report per-executor table statistics so distributed JoinSelection can size joins by @phillipleblanc in #11089
  • Improve Cayenne CDC write and compaction path tracing by @sgrebnov in #11091
  • Support tuple-IN composite PK extraction in Cayenne delete fast-path by @sgrebnov in #11093
  • feat(cluster): NDV-aware executor stats so CDC q18 join swap fires by @phillipleblanc in #11098
  • feat(cayenne): maintain join-sizing stats on the write path by @phillipleblanc in #11104
  • fix(cache): run periodic moka maintenance for idle caches by @phillipleblanc in #11106
  • Upgrade to DuckDB 1.5.3 + statically link the VSS (HNSW) extension by @sgrebnov in #11107
  • Fix fetched_at for HTTP connector by @Jeadie in #11116
  • fix(cayenne): tombstone inline-checkpointed rows on upsert to prevent duplicate PKs by @sgrebnov in #11129
  • feat: dedicated compaction runtime for Cayenne + CDC pipelining, protected snapshots, and test coverage by @lukekim in #11130
  • Add datasets dimension to the query_executions metric by @phillipleblanc in #11138
  • Fix #11137: localpod child not tracking parent refreshes with in-memory (arrow) parent accelerator by @phillipleblanc in #11139
  • Fix Windows build: vendor the VSS extension (drop nested submodule) by @phillipleblanc in #11140
  • fix(spiceai): keep correlated subqueries out of JOIN ON for Spice Cloud federation by @phillipleblanc in #11143
  • Refactor spice dataset configuration command by @Jeadie in #10999
  • feat(cayenne): sharded parallel Vortex encode with key/time clustering by @lukekim in #11144
  • fix(cluster): prevent DoPut write pipeline self-deadlock under ingest backpressure by @phillipleblanc in #11160
  • fix(cayenne): only warn on genuine protected-snapshot amplification by @lukekim in #11158

Full Changelog: https://github.com/spiceai/spiceai/compare/v1.11.6...v2.0.0

Spice v2.0-rc.5 (May 27, 2026)

ยท 30 min read
Jack Eadie
Token Plumber at Spice AI

Spice v2.0-rc.5 is now available! ๐Ÿ”ฅ

v2.0.0-rc.5 is the fifth release candidate for advanced testing of v2.0, building on v2.0.0-rc.4.

This release completes the mTLS implementation across server endpoints and outbound connectors, adds MongoDB Change Streams and durable Kafka offset persistence as new CDC sources, expands DML write-back to PostgreSQL, Snowflake, and Arrow, promotes DuckLake to Beta, introduces user-defined functions, on-demand dataset loading, unified query cancellation, dynamic HTTP request headers and subquery-driven request parameters, provider-aware LLM prompt caching, and a long list of Cayenne performance improvements.

Highlights in this release candidate include:

  • Spice Cayenne โ€” CDC throughput, compaction and scan caching, synchronized partition commits, join filter propagation, parallel Vortex writes, lock-free deletion caches
  • Mutual TLS (mTLS) โ€” TLS cert hot-reload, public mTLS for HTTP and Flight (channel + identity modes), mTLS client certs for FlightSQL and Spice.ai connectors
  • MongoDB Change Streams โ€” native real-time CDC for MongoDB, no Debezium or Kafka required
  • Kafka CDC offsets โ€” offsets persisted in sidecar tables for durable, resumable Kafka CDC
  • PostgreSQL DML โ€” INSERT, UPDATE, DELETE write-back on PostgreSQL datasets
  • Snowflake DML โ€” INSERT, UPDATE, DELETE write-back on Snowflake datasets
  • Arrow Primary Key Upserts โ€” native upsert path using primary key matching
  • DuckLake promoted to Beta โ€” with INSERT support on catalog tables
  • User-Defined Functions โ€” define SQL UDFs in spicepods, plus remote UDFs over HTTP (Spice.ai Enterprise)
  • Spatial SQL UDFs โ€” optional geospatial UDFs (ST_*) for geometry workloads
  • On-Demand Dataset Loading โ€” datasets can be deferred and loaded on first reference
  • Unified Query Cancellation โ€” Ctrl-C and HTTP request cancellation propagate across all execution paths
  • Dynamic HTTP Connector โ€” pass-through request headers, subquery-driven params, and JSON schema decomposition
  • HTTP Rate-Control persistence โ€” rate-limit state persisted in object storage across restarts
  • refresh_mode: snapshot โ€” point-in-time snapshot acceleration with SQLite/Turso WAL flushing
  • Storage-profile accelerator tuning โ€” accelerators auto-tune defaults based on local SSD, EBS-class disk, or tmpfs
  • Provider-Aware LLM Prompt Caching โ€” automatic prompt caching for OpenAI-compatible providers that support it
  • Responses API โ€” support across all model providers with streaming response.output_text.delta, plus Authorization: Bearer header support

What's New in v2.0.0-rc.5โ€‹

Cayenne Improvementsโ€‹

Significant performance work across Spice Cayenne-backed catalogs and accelerators.

  • Ingest throughput: End-to-end improvements to CDC ingest, background compaction, and a new scan-result cache for hot reads; parallel Vortex partition writes; lock-free deletion caches with bloom-prefiltered probes; background retention with CDC pipelining; SQLite metastore pool scaled to 32 for high-concurrency mutation workloads.
  • Data inlining: Small writes are serialized as Arrow IPC and committed directly into the Cayenne metastore (cayenne_inlined_data), bypassing the staged Vortex write path for low-latency ingest. Inline upserts atomically rewrite existing inline rows instead of emitting side delete markers, and inline data remains query-visible via an in-memory union scan with a generation-keyed decode cache. Inline rows are checkpointed to Vortex when row, segment, or byte thresholds are reached. Defaults are refresh-mode aware: inline writes are enabled by default for high-frequency caching, changes, and fast append workloads and disabled for full, snapshot, and slower append.
  • Query planning: Join filter propagation across equi-join keys (gated behind runtime.params.cayenne_filter_propagation), range fallback for large join filters, hot-path clone elimination, and IN-list rewrites for large filter lists.
  • Correctness: Synchronized partition commits across partitions, correct NULL-sentinel handling for nullable partition expressions (e.g. bucket(N, col)), Vortex panic fix on highly compressible data, and live reads through expired protected snapshots.
  • Catalog and platform: Refresh-mode-aware compaction defaults, rejection of non-distributed Cayenne catalog configurations, and a vendored Vortex DataFusion integration for faster iteration on the Cayenne planner.

Mutual TLS (mTLS)โ€‹

Spice.ai Enterprise feature. See Enterprise Security.

Spice now supports full mutual TLS for both HTTP and Arrow Flight endpoints.

TLS cert hot-reload (#10727): The Spice runtime watches for SIGHUP and reloads TLS certificates without restarting, enabling cert rotation with zero downtime.

Public mTLS for HTTP and Flight (#10753): Two client_auth_mode values control how the server handles client certificates:

  • request โ€” optional mTLS: the server requests a client cert but accepts connections without one (useful for migration windows).
  • required โ€” strict mTLS: the server requires a valid client cert signed by the configured CA.

mTLS client certs for FlightSQL and Spice.ai connectors (#10764): Outbound connections from the FlightSQL and Spice.ai data connectors can now present client certificates for mutual authentication with upstream services.

Example configuration:

runtime:
tls:
enabled: true
certificate_file: /etc/spice/tls/server.crt
key_file: /etc/spice/tls/server.key
client_auth_mode: required
client_auth_ca_file: /etc/spice/tls/client-ca.crt

MongoDB Change Streamsโ€‹

MongoDB datasets configured with refresh_mode: changes now stream changes from MongoDB Change Streams into any local accelerator (#10813), providing real-time CDC without Debezium or Kafka.

Example configuration:

datasets:
- from: mongodb:my_collection
name: my_collection
params:
host: my-cluster.mongodb.net
db: mydb
acceleration:
enabled: true
engine: duckdb
refresh_mode: changes

CDC Improvementsโ€‹

See Change Data Capture (CDC) for an overview of CDC in Spice.

  • Kafka CDC offset persistence (#10823): Kafka CDC offsets are persisted in sidecar tables for durable, resumable streams. On restart or failover, Spice resumes from the last committed offset.
  • Pipelined CDC ingestion (#10676): Source reads overlap with batch apply, with additional batching, envelope coalescing, and nullability propagation improvements across the apply pipeline.
  • Debezium schema evolution fix (#10144): Schema changes in Debezium-sourced datasets no longer break dataset initialization on reload (fixes #9782).

PostgreSQL DML Supportโ€‹

The PostgreSQL data connector now supports write-back via INSERT, UPDATE, and DELETE operations (#10446). Combined with the existing read-side federation, PostgreSQL-backed datasets can serve as full read/write tables. The PostgreSQL Catalog connector additionally exposes foreign-key metadata for NSQL and query planning (#10849).

Snowflake DML Supportโ€‹

The Snowflake data connector now supports write-back via INSERT, UPDATE, and DELETE operations (#10747), complementing its existing read capabilities.

Arrow Primary Key Upsertsโ€‹

Arrow-accelerated tables now support native upsert operations using primary key matching (#10749), providing efficient update-or-insert semantics for in-memory datasets.

DuckLake Promoted to Betaโ€‹

The DuckLake Catalog and Data Connector are promoted to Beta quality (#10743).

DuckLake catalog tables with read_write access now support INSERT operations (#10744), enabling full read/write workflows against DuckLake-backed catalogs. The DuckLake connector also gains a series of correctness fixes for downcast, module registration, schema discovery, and S3 credentials (#10650).

User-Defined Functionsโ€‹

Spice now supports user-defined functions (UDFs) as a first-class spicepod component (#10571), letting you define reusable SQL functions in the spicepod or invoke remote functions over HTTP. The runtime also gains table user functions with HTTP server gating (#10675).

A security fix closes a remote-UDF SSRF vector (#10757).

Spatial SQL UDFsโ€‹

Spice now ships an optional set of geospatial SQL UDFs (ST_*) for geometry workloads (#10833). The functions are gated behind a build feature and can be invoked from any SQL surface.

On-Demand Dataset Loadingโ€‹

Datasets can now be marked for on-demand loading (#10629). Deferred datasets are registered with a declared schema at startup (#10669) and only fully resolve when first referenced, reducing startup time and memory footprint for spicepods with many seldom-used datasets.

Spicepods also gain columns[].type and columns[].nullable (#10661) with a lenient type parser for declaring schemas inline.

Unified Query Cancellationโ€‹

All query execution paths โ€” HTTP, Flight, FlightSQL, MCP, and internal โ€” now honour a unified cancellation signal (#10390). When a client disconnects, presses Ctrl-C in the REPL, or cancels an in-flight HTTP request, the corresponding query is cancelled end-to-end, freeing resources promptly.

Dynamic HTTP Connectorโ€‹

The HTTP data connector gains dynamic request headers parameterised from query predicates (#10604), subquery-driven request parameters for fan-out queries (#10636), HTTP response metadata as queryable columns via JSON schema decomposition (#10679), no-limit pagination (#10673), and shared rate-control across HTTP-based connectors using the same backend host (#10648).

HTTP Rate-Control Persistenceโ€‹

The HTTP rate-control state (per-endpoint throttle counters) is now persisted in object storage (#10697), ensuring rate limits survive restarts and are consistent across replicas. Rate-control metrics now use an origin label rather than the connector name for cleaner aggregation (#10689).

The metrics HTTP endpoint (/metrics) is also independently rate-limited (#10162) to prevent scraping from impacting query serving.

refresh_mode: snapshotโ€‹

Spice.ai Enterprise feature. See Acceleration Snapshots.

A new refresh_mode: snapshot provides point-in-time snapshot acceleration (#10651), with SQLite and Turso WAL flushing and a Cayenne metastore slice integration so accelerated readers see a consistent snapshot while writes continue.

Storage-Profile Accelerator Tuningโ€‹

Acceleration configs gain a new storage_profile field (#10913) with values auto (default), local_ssd, ebs, and tmpfs. Under auto, the runtime detects whether the acceleration store is backed by local SSD, EBS-class network disk, or tmpfs, and applies storage-aware defaults across DuckDB, partitioned DuckDB, SQLite, Turso, and Cayenne file-mode accelerators. Explicit per-accelerator parameters always override the profile defaults.

Provider-Aware LLM Prompt Cachingโ€‹

LLM calls automatically use provider-aware prompt caching (#10645) when the configured model provider supports it (e.g., Anthropic, OpenAI). System prompts and tool descriptions are marked for caching so repeated invocations within the cache window reuse the provider-side cached prefix, reducing latency and cost.

A new searchable registry mode for LLM tools (#10647) lets agents discover tools by semantic search rather than enumerating all tools in the system prompt, which scales to large tool inventories.

Responses API Improvementsโ€‹

The Responses API is now supported across all configured model providers (#10724). Streaming delta events via response.output_text.delta are also supported (#10828). The runtime now also accepts Authorization: Bearer headers in addition to x-api-key, bumps async-openai, and stops populating FunctionToolCall.id so OpenAI-compatible servers can assign the ID themselves (#10911).

Distributed Cluster Improvementsโ€‹

Spice.ai Enterprise feature. See High Availability.

  • Per-request executor readiness gate (#10860): /v1/ready on schedulers waits for a configurable quorum of executors before returning healthy, enabling proper rolling deployments.
  • Ballista S3 shuffle reads under cluster mode (#10910): The shuffle reader builds its S3 client from the executor pod's environment, matching the writer. Async queries with runtime.params.shuffle_location: s3://... now complete instead of failing with AccessDenied on shuffle fetches.
  • Flattened scheduler config (#10450): runtime.scheduler.partition_management.* fields are flattened directly onto runtime.scheduler and renamed under the canonical "partition assignment" terminology. See Breaking Changes.

Improvements across Caching and Search:

  • Per-principal cache namespacing (#10702): SQL, search, and caching-accelerator caches are now namespaced per authenticated principal, so cached results never cross identity boundaries.
  • DuckDB HNSW vector indexes (#10695, #10674, #10668): DuckDB-accelerated views support HNSW vector indexes for vector search, vector search SQL is rewritten to activate HNSW_INDEX_SCAN, and HNSW indexes are preserved across data refresh.

Security Improvementsโ€‹

See Authentication and TLS for configuring Spice security.

  • API key timing-position leak and remote-UDF SSRF (#10757): Closed a timing-based position-disclosure leak in API key comparison and blocked SSRF via remote UDF endpoint parameters.
  • Configurable allowed_hosts for MCP (#10638): MCP servers can be restricted to an explicit allowlist of upstream hosts.

SQL, Query, and Developer Experienceโ€‹

See the SQL Reference for the full SQL surface area.

  • SQL REPL expanded view (#10797): Toggle \x in the REPL for a vertical key-value layout on wide result sets.
  • FlightSQL Substrait plan support (#10761): The Spice runtime now implements CommandStatementSubstraitPlan, enabling clients that submit plans as Substrait-encoded protobuf.
  • MCP auth for streamable HTTP tools (#10927): Streamable HTTP MCP tools support native authentication via mcp_auth_token and mcp_headers, both with full Spice secret expansion.
  • Elasticsearch FTS engine config and index lifecycle (#10672): Direct FTS engine configuration plus index lifecycle and ingestion controls for the Elasticsearch connector.
  • Self-hosted Spice connector (#10546): Connect Spice to another self-hosted Spice runtime as a federated source.

Connector Bug Fixesโ€‹

Notable correctness fixes across the Data Connectors: DynamoDB Streams retry on transient errors (#10794) and typed-NULL handling in DML (#10511); ScyllaDB physical filter pushdown disabled to fix incorrect results (#10772); MSSQL TOP N pushdown for non-nullable sort columns (#10621); DuckLake include filter applied (#10738); DuckDB DELETE/UPDATE on full and caching refresh modes (#10632); checked arithmetic for Turso integer-millis and timestamp-to-nanosecond conversions (#10786, #10666); and Flight GetFlightInfo/DoGet schema parity (#10864). See the Changelog for the full list.

Dependency Updatesโ€‹

Dependency / ComponentVersion
DuckDBv1.5.2
Icebergv0.9.1
Tursov0.6.0
Vortexv0.69.0

Contributorsโ€‹

Breaking Changesโ€‹

Flattened runtime.scheduler configuration (#10450): The nested runtime.scheduler.partition_management block has been flattened and renamed to use the canonical "partition assignment" terminology. Migrate as follows:

# Before
runtime:
scheduler:
partition_management:
interval: 30s
max_assignments_per_cycle: 16
discovery_timeout: 10s

# After
runtime:
scheduler:
partition_assignment_interval: 30s
max_assignments_per_interval: 16
partition_discovery_timeout: 10s

Cookbook Updatesโ€‹

No new cookbook recipes.

The Spice Cookbook includes 86 recipes to help you get started with Spice quickly and easily.

Upgradingโ€‹

To upgrade to v2.0.0-rc.5, use one of the following methods:

CLI:

spice upgrade v2.0.0-rc.5

Homebrew:

brew upgrade spiceai/spiceai/spice

Docker:

Pull the spiceai/spiceai:2.0.0-rc.5 image:

docker pull spiceai/spiceai:2.0.0-rc.5

For available tags, see DockerHub.

Helm:

helm repo update
helm upgrade spiceai spiceai/spiceai --version 2.0.0-rc.5

AWS Marketplace:

Spice is available in the AWS Marketplace.

What's Changedโ€‹

Changelogโ€‹

  • Enable DML support for PostgreSQL data connector by @phillipleblanc in #10446
  • feat(postgres): support inline PEM sslrootcert by @claudespice in #10578
  • Add foreign key metadata discovery to PostgreSQL Catalog by @sgrebnov in #10849
  • Add Snowflake DML support by @lukekim in #10747
  • Add MongoDB Change Streams support by @lukekim in #10813
  • Add user-defined functions by @lukekim in #10571
  • Add table user functions and gate HTTP servers by @lukekim in #10675
  • feat: add on-demand dataset loading by @phillipleblanc in #10629
  • feat(runtime): declared-schema deferred datasets by @phillipleblanc in #10669
  • feat(spicepod, runtime): add columns[].type / nullable + lenient type parser by @phillipleblanc in #10661
  • Replace external smb crate with internal SMB 3.1.1 client by @phillipleblanc in #10516
  • Add unified query cancellation across all paths by @lukekim in #10390
  • Add dynamic HTTP request headers by @lukekim in #10604
  • feat(http): Support dynamic HTTP connector request params from subqueries by @lukekim in #10636
  • feat(http): pass through HTTP metadata columns with JSON schema decomposition by @lukekim in #10679
  • Add nolimit HTTP pagination max pages by @lukekim in #10673
  • Add shared HTTP rate control for connectors by @lukekim in #10648
  • Use origin label instead of name for HTTP rate control metrics by @lukekim in #10689
  • fix(http): reject OR across different HTTP filter columns by @lukekim in #10625
  • Add provider-aware LLM prompt caching by @lukekim in #10645
  • Add searchable registry mode for LLM tools by @lukekim in #10647
  • feat: refresh_mode: snapshot + SQLite/Turso WAL flush + Cayenne metastore slice by @phillipleblanc in #10651
  • feat: per-principal cache namespacing for SQL/search/caching-accelerator by @lukekim in #10702
  • Add self-hosted Spice connector support by @phillipleblanc in #10546
  • Add Delta Lake Azure tenant parameter by @phillipleblanc in #10671
  • Support OAuth2 client credentials in 'spice cloud login' by @ewgenius in #10586
  • Add configurable allowed_hosts for MCP by @lukekim in #10638
  • fix: make Helm chart probes configurable by @peasee in #10696
  • Strip high-cardinality datasets dim from anonymous telemetry by @lukekim in #10711
  • feat(elasticsearch): direct FTS engine config + index lifecycle and ingestion controls by @lukekim in #10672
  • Add DuckDB HNSW vector index support for accelerated views by @sgrebnov in #10695
  • Rewrite DuckDB vector search SQL to activate HNSW_INDEX_SCAN by @sgrebnov in #10674
  • Fix DuckDB HNSW vector indexes lost after data refresh by @sgrebnov in #10668
  • Fix DuckDB DELETE/UPDATE on full and caching refresh mode datasets by @phillipleblanc in #10632
  • Fix DuckLake connector: downcast, module registration, schema discovery, and S3 credentials by @sgrebnov in #10650
  • Fix federation pushing denied functions inside subqueries to remote engines by @phillipleblanc in #10692
  • fix(caching): honour refresh_on_startup: always in caching mode by @phillipleblanc in #10594
  • fix(iceberg): rebuild storage factory when Hadoop catalog scheme is inferred by @sgrebnov in #10601
  • Pipeline CDC ingestion: overlap source reads with batch apply by @lukekim in #10676
  • fix: add NULL check to CDC primary key extraction by @lukekim in #10684
  • Properly handle nullability during CDC processing by @krinart in #10803
  • Flatten scheduler config and rename partition management โ†’ partition assignment by @lukekim in #10450
  • Improve NSQL UX and harden internal LLM tools by @lukekim in #10715
  • Support Responses API across model providers by @lukekim in #10724
  • Update xAI default model and handle Grok model retirements by @Jeadie in #10723
  • Improve cli table layout by @krinart in #10725
  • TLS cert hot-reload (mTLS plan M1) by @phillipleblanc in #10727
  • Fix DuckLake catalog include filter being ignored by @phillipleblanc in #10738
  • Promote DuckLake Catalog and Data Connector to Beta quality by @sgrebnov in #10743
  • feat(ducklake): Support INSERT on catalog tables with read_write access by @sgrebnov in #10744
  • perf(cdc): coalesce envelopes and overlap commits in apply pipeline by @lukekim in #10745
  • feat: Allow full version tags in spicepod version by @peasee in #10748
  • Add Arrow primary key upserts by @lukekim in #10749
  • fix(snapshot): keep refresh_mode snapshot read-only by @phillipleblanc in #10752
  • feat(tls): public mTLS for HTTP and Flight (channel + identity modes) by @phillipleblanc in #10753
  • perf(cayenne): lock-free deletion caches with bloom-prefiltered probe by @lukekim in #10756
  • fix(security): close API key timing-position leak and remote-UDF SSRF by @lukekim in #10757
  • Fix 'wait_until_dependent_tables_are_ready' for catalogs by @phillipleblanc in #10758
  • Fixes for views and resolved tables on 'spice refresh' CLI by @phillipleblanc in #10759
  • Implement FlightSQL CommandStatementSubstraitPlan support by @lukekim in #10761
  • feat(connectors): mTLS client cert support for flightsql and spiceai connectors by @phillipleblanc in #10764
  • Allow arbitrary filenames when specifying spicepod path + kind validation by @krinart in #10777
  • fix: ignore field metadata in schema compatibility check in index_table_scan by @Jeadie in #10778
  • Display pushed-down limits in EXPLAIN TREE output by @lukekim in #10779
  • fix: enable streaming append for Kafka with Cayenne accelerator by @lukekim in #10780
  • fix: bound chunked-index intermediate batch size to prevent OOM by @phillipleblanc in #10783
  • fix: label all columns in spice cloud metrics table output by @claudespice in #10784
  • fix: use checked arithmetic for Turso integer-millis timestamp read path by @claudespice in #10786
  • fix: use checked arithmetic in timestamp-to-nanosecond conversions by @claudespice in #10666
  • Upgrade to DuckDB v1.5.2 by @sgrebnov in #10788
  • Improve CDC ingestion performance by @lukekim in #10789
  • Fix tool_search/tool_invoke spans by @lukekim in #10791
  • Add Cayenne inline mutations and benchmark coverage by @lukekim in #10792
  • Ensure we always resolve table names in distributed mode/metadata by @Jeadie in #10793
  • Remove permanent errors from DynamoDB Streams by @krinart in #10794
  • Add expanded view mode for wide table display in SQL REPL by @lukekim in #10797
  • Fix Cayenne CDC schema mismatch error by @sgrebnov in #10800
  • Executors should create catalog tables on join by @Jeadie in #10807
  • Add compressed file support for listing connectors by @lukekim in #10809
  • Improve Cayenne mutation, scan, and inline memtable scaling by @lukekim in #10811
  • Add range fallback for large join filters by @lukekim in #10816
  • Improve Cayenne join filter pushdown by @lukekim in #10818
  • Synchronize Cayenne partition commits across partitions by @phillipleblanc in #10819
  • fix: Deny nondistributed cayenne catalog by @peasee in #10821
  • Enable parallel Cayenne Vortex writes by @lukekim in #10822
  • Expand Arrow type handling in formatting and Elasticsearch by @lukekim in #10825
  • Add response.output_text.delta to responses API by @krinart in #10828
  • feat(cayenne): add join filter propagation and no-spill Q21 planning by @lukekim in #10840
  • Upgrade Turso to v0.6.0 by @sgrebnov in #10843
  • feat(cli): add spice feedback command to open community Slack by @lukekim in #10856
  • Upgrade iceberg to v0.9.1 by @sgrebnov in #10859
  • feat(cluster): per-request executor readiness gate on /v1/ready by @phillipleblanc in #10860
  • fix: Require dim-side statistics for CayennePropagateFilterAcrossEquiJoinKeys by @sgrebnov in #10863
  • fix: Debezium schema evolution breaks dataset init on reload by @claudespice in #10144
  • fix(mssql): Push topK limit to SQL Server for non-nullable sort columns by @Jeadie in #10621
  • fix(ScyllaDB): disable physical filter pushdown by @sgrebnov in #10772
  • fix: handle typed NULLs and prevent overflow in DynamoDB DML type conversions by @krinart in #10511
  • fix: use InsertOp::Overwrite in DynamoDB bootstrap scan_and_overwrite_accelerator by @krinart in #10639
  • Improve DynamoDB Bootstrap performance by @krinart in #10616
  • fix: preserve field and schema metadata in Vortex type transformation by @lukekim in #10628
  • fix: GH connector - explicitly use AWS LC RS crypto provider for jwt by @phillipleblanc in #10619
  • fix: add snapshot mode guards to delete_from/update and delegate DML in SwappableTableProvider by @phillipleblanc in #10685
  • Persist HTTP rate-control state in object storage by @lukekim in #10697
  • Rate limit metrics HTTP endpoint by @lukekim in #10162
  • feat(geo): add optional spatial SQL UDF support by @lukekim in #10833
  • feat(cayenne): CDC throughput, compaction, scan caching, and benchmarks by @lukekim in #10852
  • fix(cayenne): fix Vortex panic on highly compressible data by @sgrebnov in #10855
  • fix(cayenne): Read live protected snapshots after cleanup grace period by @sgrebnov in #10901
  • fix: Disable Cayenne HashJoin rewriter optimizer by @sgrebnov in #10882
  • Fix GetFlightInfo vs DoGet Flight Schema by @krinart in #10864
  • fix(search): preserve column casing in /v1/search primary key plumbing by @claudespice in #10909
  • fix(object-store): dedupe s3 url style auto-detection log by @phillipleblanc in #10898
  • Improve Spice CLI manifest editing and direct command modes by @lukekim in #10815
  • Persist Kafka CDC offsets in sidecar tables by @lukekim in #10823
  • feat(task-history): record Ballista stages for distributed queries by @phillipleblanc in #10831
  • Add '#[deny(clippy::missing_trait_methods)]' to wrapper/delegation trait impls by @Jeadie in #10795
  • Optimize Cayenne catalog maintenance paths by @lukekim in #10904
  • Centralize DuckDB settings for accelerator by @ewgenius in #10895
  • deps(ballista): bump to 47e2b494 to fix S3 shuffle reads under cluster mode by @phillipleblanc in #10910
  • Authorization header + Bump async-openai + responses_adapter fix by @krinart in #10911
  • Tune accelerators by storage profile by @lukekim in #10913
  • feat: add dataset-level on_schema_change config by @lukekim in #10908
  • Handle NULL sentinel for nullable partition expressions by @Jeadie in #10880
  • fix: Remove Cayenne Catalog from catalog registration by @peasee in #10914
  • Add catalog name to foreign key metadata in postgres catalog by @Jeadie in #10917
  • Cayenne perf: eliminate redundant clones, PK point-lookup fanout fix, IN-list rewrite + microbench coverage by @lukekim in #10916
  • fix(turso-shared): retry on Turso BEGIN CONCURRENT "Write-write conflict" by @lukekim in #10946
  • Vendor Vortex DataFusion for Cayenne by @lukekim in #10933
  • perf(cayenne): background retention + enable CDC pipelining for retention-configured tables by @lukekim in #10936
  • feat(cayenne): scale metastore pool to 32 + vs_duckdb_scaling benches (1โ†’128 concurrency, sqlite + turso lanes) by @lukekim in #10943
  • feat(mcp): support auth for streamable HTTP tools by @phillipleblanc in #10927
  • Explicit error if v1/search requests a table without search index by @Jeadie in #10968
  • Fix spicepod loading failure when directory name contains dots by @sgrebnov in #10958
  • Extend append tests with arrow engine configurations by @sgrebnov in #10959
  • Remove dataset on_schema_change Policy from rc.5 release notes by @sgrebnov in #10964
  • Skip tpcds_q78 for Cayenne engine at SF100 by @sgrebnov in #10966
  • fix: Update benchmark snapshots May-20 by @app/github-actions in #10952
  • Fix #10951: UdtfExec invariant Vec lengths must match children count by @phillipleblanc in #10953
  • docs(release): update v2.0.0-rc.5 notes with latest trunk PRs by @lukekim in #10949
  • Remove eval related things for v2.0.0 by @Jeadie in #10945
  • build(deps): bump ubuntu from 24.04 to 26.04 in the docker-dependencies group by @app/dependabot in #10883
  • fix: Add publish = false to chbench-driver by @sgrebnov in #10939

Full Changelog: https://github.com/spiceai/spiceai/compare/v2.0.0-rc.4...v2.0.0-rc.5