← Back to list

106 Vespa | Attribute Store vs Document Store

When people first learn Vespa, one of the most confusing concepts is why the same document is stored in multiple places:

Growwithtechzone · 2026-06-20 01:39 · 0 claps · 3.9 min read
#vespa #vespa-search-engine #vector-database #vector-search #vector-search-engine
Open on Medium ↗
Wiki topics: RAG · RAG & Retrieval

106 Vespa | Attribute Store vs Document Store

When people first learn Vespa, one of the most confusing concepts is why the same document is stored in multiple places:

  • Inverted Index
  • Attribute Store
  • Document Store

The answer is simple: each storage structure is optimized for a different job.

Think of Vespa as a high-performance search engine that must answer three questions efficiently:

Which documents match the query?

Which matching documents should rank highest?

What content should be returned to the user?

To solve these efficiently, Vespa separates data into specialized storage structures.

Example Document

Consider the following product document:

{
  "id": "1",
  "title": "iPhone 15",
  "description": "Latest Apple smartphone",
  "price": 799,
  "rating": 4.6,
  "category": "phone"
}

In Vespa, different parts of this document may be stored in different structures depending on schema settings.

The Attribute Store

Purpose

The Attribute Store is designed for:

  • Filtering
  • Sorting
  • Grouping
  • Ranking features

Typical queries:

price < 1000
sort by rating
group by category

These operations must execute extremely quickly, often across millions of documents.

How Attribute Storage Works

Unlike traditional databases that store rows together, Vespa stores attributes in a column-oriented layout.

Imagine three documents:

| DocId | Price | Rating | Category |
| ----- | ----- | ------ | -------- |
| 1     | 799   | 4.6    | Phone    |
| 2     | 1299  | 4.2    | Laptop   |
| 3     | 599   | 4.8    | Phone    |

Instead of storing rows together, Vespa stores each attribute separately.

Price Column
------------
799
1299
599
Rating Column
-------------
4.6
4.2
4.8
Category Column
---------------
Phone
Laptop
Phone

Each column lives in memory (RAM).

How Columns Stay Connected

A common question is:

“If columns are separate, how does Vespa know which rating belongs to which price?”

The answer is the internal document identifier (docId).

Position 0 → Doc 1
Position 1 → Doc 2
Position 2 → Doc 3

Therefore:

price[1] = 799
rating[1] = 4.6
category[1] = Phone
price[2] = 1299
rating[2] = 4.2
category[2] = Laptop

The docId acts as the glue connecting all attribute columns.

Why Column-Oriented Storage is Fast

Suppose a user searches:

price < 1000

Vespa only needs the Price column.

799    ✓
1299   ✗
599    ✓

Result:

Matching DocIds:
[1,3]

No need to read:

  • title
  • description
  • category
  • body

This dramatically reduces memory access.

Multi-Column Queries

Consider:

price < 1000
sort by rating

Step 1: Read Price column.

Matching DocIds:
[1,3]

Step 2: Read Rating values only for those documents.

rating[1] = 4.6
rating[3] = 4.8

Step 3: Sort.

Doc 3
Doc 1

The columns work together through the shared docId.

Recall Attribute Store

The Document Store

Purpose

The Document Store serves a completely different purpose. Its job is not filtering or sorting. Its job is returning document content to the user.

Typical fields:

  • title
  • description
  • url
  • body

The Document Store contains the original document.

Recall Document store

How Document Storage Works

Unlike the Attribute Store, the Document Store uses a row-oriented layout.

Doc 1
------
title
description
url
body
Doc 2
------
title
description
url
body
Doc 3
------
title
description
url
body

Each document is stored as a complete unit. The store is compressed and persisted on disk.

Why Not Store Everything in the Document Store?

Imagine searching:

price < 1000

If only the Document Store existed, Vespa would need to:

Read Doc 1
Read Doc 2
Read Doc 3
Read Doc 4
...
Read Doc 10 Million

and inspect every document. This would be extremely slow. The Attribute Store avoids this by keeping searchable attributes in memory.

Why Not Store Everything in the Attribute Store?

Imagine returning search results.

The user wants:

{
  "title": "...",
  "description": "...",
  "url": "..."
}

If only the Attribute Store existed, every text field would need to remain in RAM. For large datasets this becomes prohibitively expensive. Instead, Vespa stores document content in compressed disk structures and loads it only when needed.

Attribute Store vs Document Store

Mental Model

Think of Vespa as three specialized engines working together.

Inverted Index
    ↓
Find matching documentsAttribute Store
    ↓
Filter, Sort, Rank
Document Store
    ↓
Return document content

Or even more simply:

Attribute Store = Find the right documents fast

Document Store = Show the document contents to the user

This separation of responsibilities allows Vespa to achieve both high search performance and efficient storage utilization at massive scale.

Query Execution Flow

Consider the query:

price < 1000
sort by rating

Execution path:

User Query
    │
    ▼
Attribute Store
    │
    ├─ Filter by price
    ├─ Read ratings
    └─ Sort results
    │
    ▼
Matching DocIds
    │
    ▼
Document Store
    │
    ├─ Fetch title
    ├─ Fetch description
    └─ Fetch url
    │
    ▼
Return Results

This separation is one of the key reasons Vespa can scale to billions of documents.


메타데이터
post_id
9c64a3f06b69
slug
106-vespa-attribute-store-vs-document-store-9c64a3f06b69
url
https://medium.com/@growwithtechzone/106-vespa-attribute-store-vs-document-store-9c64a3f06b69
canonical_url
https://medium.com/@growwithtechzone/106-vespa-attribute-store-vs-document-store-9c64a3f06b69
author_url
https://medium.com/@growwithtechzone
status
ok
fetched_at
2026-07-09 21:48:21