vespa-feed-client

  • Java library and command line client for feeding document operations using Document v1 over HTTP/2.
  • Asynchronous, high-performance Java implementation, with retries and dynamic throttling.
  • Supports a JSON array of feed operations, as well as JSONL: one operation JSON per line.

Installing

Java library

The Java library is available as a Maven JAR artifact at Maven Central. It requires minimum JDK17.

Find an example application using this client at client-java.

Command line client

Two alternatives:

Download example:

$ F_REPO="https://repo1.maven.org/maven2/com/yahoo/vespa/vespa-feed-client-cli" && \
  F_VER=$(curl -Ss "${F_REPO}/maven-metadata.xml" | sed -n 's/.*<release>\(.*\)<.*>/\1/p') && \
  curl -SsLo vespa-feed-client-cli.zip ${F_REPO}/${F_VER}/vespa-feed-client-cli-${F_VER}-zip.zip && \
  unzip -o vespa-feed-client-cli.zip

Enable feed endpoint in Vespa

Requirements:

HTTP/2 over TLS is optional but recommended from a security perspective.

Example services.xml with TLS:

<?xml version="1.0" encoding="utf-8" ?>
<services version="1.0">
    <container version="1.0" id="default">
        <http>
            <server id="default" port="443">
                <ssl>
                    <private-key-file>/path/to/private-key.pem</private-key-file>
                    <certificate-file>/path/to/certificate.pem</certificate-file>
                    <ca-certificates-file>/path/ca-certificates.pem</ca-certificates-file>
                </ssl>
            </server>
        </http>
        <document-api/>
    </container>
</services>

Example services.xml without TLS:

<?xml version="1.0" encoding="utf-8" ?>
<services version="1.0">
    <container version="1.0" id="default">
        <document-api/>
    </container>
</services>

Using the client

The Javadoc for the programmatic API is available at javadoc.io. See output of $ vespa-feed-client --help for usage.

Use --speed-test for bandwidth testing.

Example Java

Add vespa-feed-client as dependency to your Maven (or other build system using Maven for dependency management):

<dependency>
    <groupId>com.yahoo.vespa</groupId>
    <artifactId>vespa-feed-client</artifactId>
    <version>8.663.19</version>
</dependency>

Code examples are listed in the vespa-feed-client source code on GitHub.

Example command line

HTTP/2 over TLS:

$ vespa-feed-client \
  --connections 4 \
  --certificate cert.pem --private-key key.pem --ca-certificates ca.pem \
  --file /path/to/json/file \
  --endpoint https://container-endpoint:443/

The input must be either a proper JSON array, or a series, of JSON feed operations (JSONL), in the format described for the Vespa feed client here.

HTTP/2 without TLS:

$ vespa-feed-client \
  --connections 4 \
  --file /path/to/json/file \
  --endpoint http://container-endpoint:8080/

Tuning for multi-worker pipelines

A common pattern is feeding from an Apache Beam topology (e.g., Google Cloud Dataflow). It is important to balance the number of workers and the connection settings.

As each of the workers initializes its own FeedClient instance, the default settings can create too many connections. In this example we assume 128 workers and 10 Vespa Container nodes. With defaults (8 connections per endpoint, 128 max streams per connection), 128 workers opens 1,024 connections — each requiring a TLS handshake to the endpoint — which is a major source of container CPU overhead.

Recommended configuration per worker (Javadoc):

FeedClient client = FeedClientBuilder.create(endpoint)
    .setConnectionsPerEndpoint(1)
    .setMaxStreamPerConnection(maxStreams)
    .setInitialInflightFactor(factor)
    .build();
  • setConnectionsPerEndpoint(1): One connection per worker gives 128 total, which is more than sufficient for 10 container nodes.
  • setMaxStreamPerConnection(maxStreams): Calculate based on the target feed rate and total number of workers. For example, if the target is 50k docs/sec across 128 workers, each worker needs ~390 docs/sec. With typical per-document latency of 5–10 ms, each worker needs ~2–4 concurrent streams.
  • setInitialInflightFactor(factor): The dynamic throttler starts at a low inflight count and slowly ramps up via random walk. If you observe slow ramp-up at the start of a feed job, set this to a higher value (e.g., 4–8) to start closer to the optimal inflight level. The factor multiplies the minimum inflight (2 × connectionsPerEndpoint × endpoints), so with 1 connection and factor 8, you'd start at 16 inflight instead of 2.

Also, use vespa-feed-client 8.657 or later, for the latest improvements to connection handling and stability.