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:
Pull the Vespa Docker image
docker pull vespaengine/vespa
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)
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.
Step 2: Create an Application
Let’s build a simple music search application.
Create the application directory structure
mkdir -p music-app/schemas
cd music-app
Create a schema file
Create schemas/music.sd with the following content: 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
Create a services configuration
Create 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:
Create a deployment package
zip -r music-app.zip schemas/ services.xml
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.
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.
Create sample documents
Create a file feed.json with sample music data: {
"fields" : {
"artist" : "The Beatles" ,
"title" : "Hey Jude" ,
"year" : 1968 ,
"album" : "Hey Jude"
}
}
Feed the document
curl -X POST -H "Content-Type: application/json" \
--data-binary @feed.json \
http://localhost:8080/document/v1/music/music/docid/1
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.
Simple text search
Search with filters
Sort by year
Count documents
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>
Example: Full-text search with ranking
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
Example: Structured query with filters
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. Delete a document by ID: curl -X DELETE http://localhost:8080/document/v1/music/music/docid/1
The document is immediately removed from search results. Retrieve a specific document: curl http://localhost:8080/document/v1/music/music/docid/2
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: Common issues:
Schema syntax errors
Invalid XML in services.xml
Insufficient memory (Vespa needs at least 4GB RAM)
Queries return no results
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