Vespa.NET 3.0.0: our typed .NET client for Vespa

Vespa.NET 3.0.0 is available under the MIT licence. It is the typed .NET client we built for our own Vespa workloads, covering document models, schema deployment, feeding and queries. This major version includes breaking changes for users upgrading from 2.0.0.

Vespa supports full-text search, vector search and machine-learned ranking in the same query. A .NET application can use its HTTP APIs directly, but it also needs code for JSON payloads, YQL queries and schema management. Maintaining a separate .sd file alongside C# document types creates another definition to keep in sync.

We first open-sourced Vespa.NET in April. At the time of this article, we had been running Vespa in production for eight months, powering AI search, recommendations and hybrid vector and keyword workloads in our own solutions. The SDK brings the integration code from that work into a reusable library.

What the SDK covers

The SDK covers four stages: defining document models in C#, deploying schemas, feeding documents and querying them.

Schema as code

C# attributes describe the document model. Vespa.NET generates the .sd schema and application package, then deploys them through the config server with DeploySchemaAsync<T>(). Supported definitions include indexing modes, tensor fields and types, rank profiles, struct and map fields, garbage-collection selections and multi-node layouts.

The generator rejects unsupported shapes during generation, including enum and byte properties, predicate fields without arity, recursive structs and redundancy greater than the node count. This surfaces those errors before deployment.

Feeding at scale

A bounded queue applies backpressure to the producer during parallel feeding. Per-document retries handle 429 and 503 responses with exponential backoff, using Retry-After for 429 responses when available. If the pipeline faults, the exception includes the partial FeedResult so the caller can inspect the progress made before the failure.

Queries and document operations

The typed YQL builder supports full-text search, nearest-neighbor search, weakAnd, wand, hybrid queries and geo search. It also supports term annotations, negation, near and onear exclusions, sameElement and parameter substitution. Raw(...) is available for expressions outside the builder’s coverage. Identifier validation checks field names at the builder’s entry points.

The grouping DSL builds all(...) expressions with composable filters, buckets with open and closed endpoints, aliases, parallel each() blocks and documented expression functions. Streaming search and a ranking DSL are also available. Grouping results use structured models, with RawAggregations for non-numeric outputs.

The SDK also covers the document/v1 API: conditional puts, partial updates, tensor modify/add/remove operations, selection-based updates and deletes, and visiting with automatic continuation.

Authentication, resilience and telemetry

Authentication includes mTLS for Vespa Cloud, with or without dependency injection, and bearer tokens through the ApiKey option. When registered through AddVespaClient, the client uses Microsoft.Extensions.Http.Resilience for HTTP retry and circuit-breaker policies. Health checks can be registered by name.

The SDK emits telemetry through the BCL’s ActivitySource and Meter. These can feed an existing OpenTelemetry pipeline without adding an OpenTelemetry dependency to Vespa.NET. Metrics carry method, host, operation and status tags. Query text and document IDs are excluded from traces unless explicitly enabled.

For integration tests, Vespa.NET.Testcontainers starts a Vespa container.

Install or upgrade

dotnet add package Vespa.NET

The package targets .NET 8 LTS and .NET 10 and uses the MIT licence. Source code is available at github.com/outmatic/Vespa.NET.

This article describes version 3.0.0. It includes breaking changes, documented with their reasons in the changelog. Read the changelog before upgrading from 2.0.0.