Skip to main content
This guide will get you up and running with Vespa in under 10 minutes. You’ll learn how to:
  • Run Vespa using Docker
  • Create a schema for your documents
  • Deploy an application
  • Feed data into Vespa
  • Query your data

Prerequisites

Before you begin, ensure you have:

Docker

Docker Desktop or Docker Engine installed

curl or similar

Command-line tool for HTTP requests
This guide uses Docker for simplicity. For production deployments, see the Installation page.

Step 1: Start Vespa

Pull and run the Vespa container:
1

Pull the Vespa Docker image

docker pull vespaengine/vespa
2

Start the Vespa container

docker run --detach --name vespa --hostname vespa-container \
  --publish 8080:8080 --publish 19071:19071 \
  vespaengine/vespa
This command:
  • Runs Vespa in detached mode
  • Exposes port 8080 (query/feed API)
  • Exposes port 19071 (config server)
3

Wait for Vespa to start

docker exec vespa bash -c 'while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' http://localhost:19071/state/v1/health)" != "200" ]]; do sleep 1; done'
This ensures the config server is ready.
Vespa is now running! Verify by visiting http://localhost:8080 in your browser.

Step 2: Create an Application

Let’s build a simple music search application.
1

Create the application directory structure

mkdir -p music-app/schemas
cd music-app
2

Create a schema file

Create schemas/music.sd with the following content:
schemas/music.sd
schema music {
    document music {
        field artist type string {
            indexing: summary | index
            index: enable-bm25
        }
        
        field title type string {
            indexing: summary | index
            index: enable-bm25
        }
        
        field year type int {
            indexing: summary | attribute
        }
        
        field album type string {
            indexing: summary | index
        }
    }
    
    fieldset default {
        fields: artist, title, album
    }
    
    rank-profile bm25 {
        first-phase {
            expression: bm25(artist) + bm25(title) + bm25(album)
        }
    }
    
    rank-profile default inherits bm25 {
    }
}
This schema defines:
  • Four fields: artist, title, year, and album
  • BM25 ranking for text fields
  • A default fieldset for searching across multiple fields
3

Create a services configuration

Create services.xml:
services.xml
<?xml version="1.0" encoding="UTF-8"?>
<services version="1.0">
    <container id="default" version="1.0">
        <search/>
        <document-api/>
    </container>
    
    <content id="music" version="1.0">
        <redundancy>1</redundancy>
        <documents>
            <document type="music" mode="index"/>
        </documents>
        <nodes>
            <node distribution-key="0" hostalias="node1"/>
        </nodes>
    </content>
</services>
This configuration:
  • Sets up a container cluster for query and document processing
  • Defines a content cluster to store music documents
  • Configures single-node redundancy (suitable for development)

Step 3: Deploy the Application

Deploy your application to the running Vespa instance:
1

Create a deployment package

zip -r music-app.zip schemas/ services.xml
2

Deploy to Vespa

curl --header Content-Type:application/zip --data-binary @music-app.zip \
  http://localhost:19071/application/v2/tenant/default/prepareandactivate
You should see a JSON response indicating successful deployment.
3

Wait for application to be ready

curl -s http://localhost:8080/state/v1/health
The response should show the application is up and ready.
Your application is now deployed and ready to receive data!

Step 4: Feed Data

Let’s add some music documents to Vespa.
1

Create sample documents

Create a file feed.json with sample music data:
feed.json
{
  "fields": {
    "artist": "The Beatles",
    "title": "Hey Jude",
    "year": 1968,
    "album": "Hey Jude"
  }
}
2

Feed the document

curl -X POST -H "Content-Type: application/json" \
  --data-binary @feed.json \
  http://localhost:8080/document/v1/music/music/docid/1
3

Feed more documents

Let’s add a few more:
# Document 2
curl -X POST -H "Content-Type: application/json" \
  --data '{
    "fields": {
      "artist": "Pink Floyd",
      "title": "Wish You Were Here",
      "year": 1975,
      "album": "Wish You Were Here"
    }
  }' \
  http://localhost:8080/document/v1/music/music/docid/2

# Document 3
curl -X POST -H "Content-Type: application/json" \
  --data '{
    "fields": {
      "artist": "The Beatles",
      "title": "Let It Be",
      "year": 1970,
      "album": "Let It Be"
    }
  }' \
  http://localhost:8080/document/v1/music/music/docid/3
Documents are immediately available for search after feeding — no reindexing required!

Step 5: Query Your Data

Now let’s search the data we just indexed.
curl "http://localhost:8080/search/?yql=select%20*%20from%20music%20where%20userQuery()&query=beatles"

Understanding the Query API

Vespa uses YQL (Yahoo Query Language) for queries. The basic structure is:
/search/?yql=SELECT <fields> FROM <source> WHERE <condition>
curl "http://localhost:8080/search/?yql=select%20*%20from%20music%20where%20userQuery()&query=beatles&ranking=bm25"
This query:
  • Searches for “beatles” across all fields in the default fieldset
  • Uses the bm25 ranking profile
  • Returns all fields (*) for matching documents
curl "http://localhost:8080/search/?yql=select%20artist,%20title,%20year%20from%20music%20where%20artist%20contains%20'beatles'%20and%20year%20%3E%201968&ranking=bm25"
This query:
  • Filters for Beatles songs from after 1968
  • Returns only artist, title, and year fields
  • Uses BM25 ranking

Query Response

A typical response looks like:
{
  "root": {
    "id": "toplevel",
    "relevance": 1.0,
    "fields": {
      "totalCount": 2
    },
    "children": [
      {
        "id": "index:music/0/d73a07c63f23b36a1d5e1b5e",
        "relevance": 0.36464314940319056,
        "source": "music",
        "fields": {
          "artist": "The Beatles",
          "title": "Hey Jude",
          "year": 1968,
          "album": "Hey Jude"
        }
      }
    ]
  }
}

Step 6: Update and Delete Documents

Update specific fields in a document:
curl -X PUT -H "Content-Type: application/json" \
  --data '{
    "fields": {
      "year": { "assign": 1969 }
    }
  }' \
  http://localhost:8080/document/v1/music/music/docid/1
Partial updates are efficient and don’t require re-sending the entire document.

Next Steps

Congratulations! You’ve successfully:
  • ✅ Started a Vespa instance
  • ✅ Created and deployed an application
  • ✅ Fed documents
  • ✅ Queried your data

Explore More

Add Vector Search

Implement semantic search with embeddings

Advanced Ranking

Learn about multi-phase ranking and ML models

Production Setup

Deploy Vespa for production workloads

Sample Apps

Explore complete example applications

Cleanup

When you’re done, stop and remove the Docker container:
docker stop vespa
docker rm vespa

Troubleshooting

If ports 8080 or 19071 are already in use, you can map to different ports:
docker run --detach --name vespa --hostname vespa-container \
  --publish 8081:8080 --publish 19072:19071 \
  vespaengine/vespa
Then use localhost:8081 for queries and localhost:19072 for deployment.
Check the Vespa logs:
docker logs vespa
Common issues:
  • Schema syntax errors
  • Invalid XML in services.xml
  • Insufficient memory (Vespa needs at least 4GB RAM)
Verify documents were fed successfully:
curl "http://localhost:8080/search/?yql=select%20*%20from%20music%20where%20true"
This returns all documents regardless of query terms.

Learn More

Build docs developers (and LLMs) love