Published: 2026-06-01 • Updated: 2026-06-20

Integrating PGVector with Spring AI: Complete Practical Guide

PGVector is one of the most useful vector database options for Java and Spring AI applications because it brings vector search directly into PostgreSQL. If your application already uses PostgreSQL, PGVector allows you to store embeddings, run semantic similarity search, and build Retrieval-Augmented Generation systems without introducing a completely separate vector database.

Spring AI provides a PGVector VectorStore integration for storing document embeddings and performing similarity searches. PGVector itself is a PostgreSQL extension that supports storing and searching machine-learning-generated embeddings and can perform exact or approximate nearest-neighbor search. ([docs.spring.io](https://docs.spring.io/spring-ai/reference/api/vectordbs/pgvector.html?utm_source=chatgpt.com))


What is PGVector?

PGVector is an open-source PostgreSQL extension that adds vector data type support to PostgreSQL.

With PGVector, PostgreSQL can store vectors like:

[0.12, -0.45, 0.88, 0.31, -0.09, ...]

These vectors usually represent the meaning of text, documents, questions, products, tickets, policies, or knowledge base content.


Why Use PGVector with Spring AI?

PGVector is a strong option when you want semantic search and RAG inside a familiar PostgreSQL environment.

  • Uses PostgreSQL infrastructure
  • Works well with Spring Boot
  • Supports semantic search
  • Supports RAG workflows
  • Can store metadata with embeddings
  • Good for small to medium enterprise AI systems
  • Reduces need for a separate vector database

Spring AI + PGVector Architecture

User Question
      |
      v
Spring Boot API
      |
      v
Embedding Model
      |
      v
PGVector VectorStore
      |
      v
Similar Documents Retrieved
      |
      v
ChatClient
      |
      v
Grounded AI Answer

Real-Time Example: Learning Platform

Suppose your learning website contains courses, interview questions, tutorials, and project explanations.

User searches:

I want to learn scalable Java backend deployment.

Keyword search may miss related content. PGVector semantic search can retrieve:

  • Spring Boot Microservices
  • Docker Deployment
  • Kubernetes Autoscaling
  • CI/CD with Kubernetes
  • Cloud Deployment with AWS

This improves content discovery and user experience.


Real-Time Banking Example

A banking support AI assistant may store FAQs and policies in PGVector.

User asks:

Amount debited but UPI payment failed. What should I do?

PGVector can retrieve relevant policy documents about failed UPI transaction reversal even if the user does not use the exact policy wording.


Real-Time E-Commerce Example

An e-commerce AI assistant may store refund policy, delivery policy, warranty rules, and product descriptions.

User asks:

Can I return a damaged phone after delivery?

PGVector can retrieve semantically relevant return policy chunks and help the AI generate a grounded answer.


Step 1: Start PostgreSQL with PGVector Using Docker

The easiest setup is using the official PGVector Docker image.

docker run --name pgvector-db \
  -e POSTGRES_USER=postgres \
  -e POSTGRES_PASSWORD=postgres \
  -e POSTGRES_DB=spring_ai \
  -p 5432:5432 \
  -d pgvector/pgvector:pg16

Step 2: Enable PGVector Extension

Connect to PostgreSQL:

docker exec -it pgvector-db psql -U postgres -d spring_ai

Enable extension:

CREATE EXTENSION IF NOT EXISTS vector;

Check extension:

\dx

Step 3: Create Spring Boot Project

Create a Spring Boot project with:

  • Java 17 or later
  • Spring Web
  • Spring JDBC
  • PostgreSQL Driver
  • Spring AI OpenAI or Ollama starter
  • Spring AI PGVector Vector Store starter

Step 4: Add Spring AI BOM

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-bom</artifactId>
            <version>1.0.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Step 5: Add Maven Dependencies

PGVector Vector Store Starter

Spring AI provides a PGVector vector store starter artifact named spring-ai-starter-vector-store-pgvector. ([central.sonatype.com](https://central.sonatype.com/artifact/org.springframework.ai/spring-ai-starter-vector-store-pgvector?utm_source=chatgpt.com))

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-vector-store-pgvector</artifactId>
</dependency>

PostgreSQL Driver

<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <scope>runtime</scope>
</dependency>

OpenAI Starter Example

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>

Step 6: Configure application.properties

spring.application.name=spring-ai-pgvector-demo

spring.datasource.url=jdbc:postgresql://localhost:5432/spring_ai
spring.datasource.username=postgres
spring.datasource.password=postgres

spring.ai.model.embedding=openai
spring.ai.openai.api-key=${OPENAI_API_KEY}
spring.ai.openai.embedding.options.model=text-embedding-3-small

spring.ai.vectorstore.pgvector.initialize-schema=true
spring.ai.vectorstore.pgvector.index-type=HNSW
spring.ai.vectorstore.pgvector.distance-type=COSINE_DISTANCE
spring.ai.vectorstore.pgvector.dimensions=1536

The embedding dimension must match the embedding model. For example, if your embedding model produces 1536-dimensional vectors, PGVector must be configured with the same dimension.


Step 7: Understand PGVector Table Structure

Spring AI can initialize the vector store schema automatically when enabled.

Conceptually, a vector table stores:

  • Document ID
  • Text content
  • Metadata
  • Embedding vector
vector_store
   |
   +-- id
   +-- content
   +-- metadata
   +-- embedding

Step 8: Create Document Ingestion Service

package com.dhanish.pgvector.service;

import org.springframework.ai.document.Document;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@Service
public class KnowledgeIngestionService {

    private final VectorStore vectorStore;

    public KnowledgeIngestionService(VectorStore vectorStore) {
        this.vectorStore = vectorStore;
    }

    public void addSampleDocuments() {

        Document springAiDoc = new Document(
                "Spring AI helps Java developers build AI applications using chat models, embeddings, vector stores, and RAG.",
                Map.of(
                        "topic", "spring-ai",
                        "source", "internal-course"
                )
        );

        Document pgVectorDoc = new Document(
                "PGVector is a PostgreSQL extension used to store and search vector embeddings for semantic search.",
                Map.of(
                        "topic", "pgvector",
                        "source", "internal-course"
                )
        );

        vectorStore.add(List.of(springAiDoc, pgVectorDoc));
    }
}

Step 9: Create Semantic Search Service

package com.dhanish.pgvector.service;

import org.springframework.ai.document.Document;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class SemanticSearchService {

    private final VectorStore vectorStore;

    public SemanticSearchService(VectorStore vectorStore) {
        this.vectorStore = vectorStore;
    }

    public List<Document> search(String query) {
        return vectorStore.similaritySearch(query);
    }
}

Step 10: Create Search Controller

package com.dhanish.pgvector.controller;

import com.dhanish.pgvector.service.KnowledgeIngestionService;
import com.dhanish.pgvector.service.SemanticSearchService;
import org.springframework.ai.document.Document;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/knowledge")
public class KnowledgeController {

    private final KnowledgeIngestionService ingestionService;
    private final SemanticSearchService searchService;

    public KnowledgeController(KnowledgeIngestionService ingestionService,
                               SemanticSearchService searchService) {
        this.ingestionService = ingestionService;
        this.searchService = searchService;
    }

    @PostMapping("/load")
    public String load() {
        ingestionService.addSampleDocuments();
        return "Documents added to PGVector successfully.";
    }

    @GetMapping("/search")
    public List<Document> search(@RequestParam String query) {
        return searchService.search(query);
    }
}

Step 11: Test Document Ingestion

curl -X POST http://localhost:8080/api/knowledge/load

Expected Response

Documents added to PGVector successfully.

Step 12: Test Semantic Search

curl "http://localhost:8080/api/knowledge/search?query=How can Java developers build AI apps?"

Expected result should include the Spring AI document even if the query does not exactly match the stored text.


Semantic Search Flow

User Query
     |
     v
Embedding Generated
     |
     v
PGVector Similarity Search
     |
     v
Relevant Documents Returned

Step 13: Build RAG with PGVector and ChatClient

PGVector is most powerful when used with RAG.

User Question
      |
      v
Search PGVector
      |
      v
Retrieve Related Documents
      |
      v
Send Context to Chat Model
      |
      v
Generate Grounded Answer

RAG Answer Service Example

package com.dhanish.pgvector.service;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.document.Document;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class RagAnswerService {

    private final VectorStore vectorStore;
    private final ChatClient chatClient;

    public RagAnswerService(VectorStore vectorStore,
                            ChatClient.Builder builder) {
        this.vectorStore = vectorStore;
        this.chatClient = builder.build();
    }

    public String answer(String question) {

        List<Document> documents =
                vectorStore.similaritySearch(question);

        String context = documents.stream()
                .map(Document::getText)
                .collect(Collectors.joining("\n\n"));

        return chatClient.prompt()
                .system("""
                        You are a helpful Spring AI assistant.

                        Use only the provided context.
                        If the answer is not available in the context,
                        say: I do not have enough information.
                        """)
                .user("""
                      Context:
                      %s

                      Question:
                      %s
                      """.formatted(context, question))
                .call()
                .content();
    }
}

RAG Controller Example

@RestController
@RequestMapping("/api/rag")
public class RagController {

    private final RagAnswerService ragAnswerService;

    public RagController(RagAnswerService ragAnswerService) {
        this.ragAnswerService = ragAnswerService;
    }

    @GetMapping("/ask")
    public String ask(@RequestParam String question) {
        return ragAnswerService.answer(question);
    }
}

Test RAG API

curl "http://localhost:8080/api/rag/ask?question=What is PGVector used for?"

Using PGVector with Ollama Embeddings

If you want local embeddings, you can use Ollama.

spring.ai.model.embedding=ollama
spring.ai.ollama.base-url=http://localhost:11434
spring.ai.ollama.embedding.options.model=nomic-embed-text

spring.ai.vectorstore.pgvector.dimensions=768

Always confirm the embedding dimension of the model you use. If dimensions do not match the PGVector table, inserts may fail.


Using PGVector in Docker Compose

services:

  postgres:
    image: pgvector/pgvector:pg16
    container_name: pgvector-db
    environment:
      POSTGRES_DB: spring_ai
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
    ports:
      - "5432:5432"
    volumes:
      - pgvector-data:/var/lib/postgresql/data

volumes:
  pgvector-data:

Spring Boot Docker Compose Connection

If Spring Boot runs on the host machine:

spring.datasource.url=jdbc:postgresql://localhost:5432/spring_ai

If Spring Boot runs inside the same Docker Compose network:

spring.datasource.url=jdbc:postgresql://postgres:5432/spring_ai

Index Types in PGVector

PGVector supports different search/indexing approaches. Spring AI PGVector supports configuration for index type and distance type. The Spring AI reference explains PGVector can identify exact and approximate nearest neighbors. ([docs.spring.io](https://docs.spring.io/spring-ai/reference/api/vectordbs/pgvector.html?utm_source=chatgpt.com))

Index Type Use Case
HNSW Fast approximate nearest-neighbor search
IVFFlat Approximate search with indexing
None Small datasets or exact search

Distance Types

Distance Type Meaning
Cosine Distance Compares vector direction
Euclidean Distance Compares geometric distance
Inner Product Often used for similarity scoring

Production Document Ingestion Pipeline

Document Uploaded
      |
      v
Validate File
      |
      v
Extract Text
      |
      v
Split into Chunks
      |
      v
Generate Embeddings
      |
      v
Store in PGVector
      |
      v
Ready for Semantic Search

Chunking Strategy

Do not store huge documents as one embedding. Split documents into meaningful chunks.

  • Keep chunks focused
  • Add metadata
  • Use overlap for long explanations
  • Avoid cutting important context
  • Test retrieval quality

Metadata Strategy

Metadata helps with filtering, citations, debugging, and access control.

{
  "source": "spring-ai-course",
  "topic": "pgvector",
  "module": "rag",
  "tenantId": "dhanish-empower"
}

Multi-Tenant Search

If your application serves multiple users, companies, or customers, filter search results by tenant or user permission.

User A
  |
  v
Search only User A documents

User B
  |
  v
Search only User B documents

Without access filtering, one user may retrieve another user’s private documents.


Common Errors and Fixes

1. PGVector Extension Not Found

ERROR: type "vector" does not exist

Fix:

CREATE EXTENSION IF NOT EXISTS vector;

2. Dimension Mismatch

ERROR: expected 1536 dimensions, not 768

Fix:

  • Check embedding model dimension
  • Set spring.ai.vectorstore.pgvector.dimensions correctly
  • Recreate table if dimension changed

3. Cannot Connect to PostgreSQL

Check:

  • Database container is running
  • Port mapping is correct
  • Datasource URL is correct
  • Username and password are correct

4. Empty Search Results

Possible causes:

  • No documents added
  • Poor chunking
  • Wrong embedding model
  • Similarity threshold too strict
  • Metadata filter mismatch

5. Slow Search

Possible fixes:

  • Add proper vector index
  • Use HNSW or IVFFlat
  • Reduce top-k
  • Improve chunking
  • Scale PostgreSQL resources

Performance Best Practices

  • Use proper vector indexes
  • Keep chunk size reasonable
  • Use metadata filters
  • Avoid very large top-k values
  • Monitor query latency
  • Use connection pooling
  • Vacuum and maintain PostgreSQL regularly
  • Separate OLTP workload and heavy vector workload if needed

Security Best Practices

  • Protect PostgreSQL credentials
  • Use environment variables or Kubernetes Secrets
  • Enable database backups
  • Use user-level or tenant-level metadata filtering
  • Do not embed secrets unnecessarily
  • Do not log sensitive documents
  • Encrypt sensitive data where required

Monitoring PGVector-Based RAG

Track:

  • Embedding generation time
  • Vector search latency
  • Top-k result quality
  • Empty result count
  • PostgreSQL CPU and memory
  • Connection pool usage
  • RAG answer fallback count
  • User feedback score

Production Architecture

Frontend
   |
   v
Spring Boot AI API
   |
   +-- Document Ingestion Service
   +-- Embedding Service
   +-- PGVector VectorStore
   +-- RAG Answer Service
   +-- Monitoring Layer
   |
   v
PostgreSQL + PGVector

Best Practices Summary

  • Use PGVector when PostgreSQL is already part of your stack
  • Match embedding dimensions correctly
  • Enable PGVector extension
  • Use meaningful chunks
  • Add metadata for filtering
  • Use RAG prompts that avoid guessing
  • Monitor vector search latency
  • Secure tenant-specific retrieval
  • Rebuild embeddings when changing embedding models
  • Use indexes for larger datasets

Interview Questions

Q1: What is PGVector?

PGVector is a PostgreSQL extension that supports storing and searching vector embeddings for semantic search and AI applications.

Q2: Why use PGVector with Spring AI?

It allows Spring AI applications to store embeddings and perform semantic search using PostgreSQL.

Q3: What is VectorStore in Spring AI?

VectorStore is the Spring AI abstraction used to store and retrieve embeddings from vector databases such as PGVector.

Q4: Why does embedding dimension matter?

The vector table dimension must match the embedding model output dimension. Otherwise, insert or search operations may fail.

Q5: What is PGVector used for in RAG?

It retrieves semantically relevant documents that are added to the chat prompt for grounded AI responses.


Advanced Interview Questions

Q1: Difference between PostgreSQL full-text search and PGVector search?

Full-text search matches keywords, while PGVector search matches semantic meaning using embeddings.

Q2: Why use metadata with PGVector?

Metadata supports filtering, tenant isolation, source tracking, citations, and debugging.

Q3: What happens if you change embedding model?

You may need to regenerate all embeddings because vector dimensions and semantic spaces may change.

Q4: When should you not use PGVector?

For extremely large-scale vector workloads requiring specialized distributed vector infrastructure, a dedicated vector database may be better.

Q5: How do you secure PGVector retrieval?

Use authentication, authorization, tenant filters, safe metadata filters, secure database credentials, and avoid storing sensitive secrets as embeddings.


Recommended Learning Path


Summary

PGVector is a practical and powerful choice for Spring AI applications that need semantic search, embeddings, and RAG while continuing to use PostgreSQL.

Spring AI’s PGVector VectorStore integration makes it easier to add documents, generate embeddings, perform similarity search, and combine retrieved knowledge with ChatClient for grounded AI responses.

For learning platforms, banking assistants, e-commerce support systems, internal knowledge bases, and AI agents, PGVector provides a strong foundation for building production-ready semantic search and RAG features.

About the Author

Naresh Kumar

Naresh Kumar

Senior Java Backend Engineer experienced in Banking, Payments, ISO 20022, Spring Boot, Microservices, Kafka, Docker, Kubernetes, AWS and Cloud Native Systems.

Built enterprise payment solutions, transaction processing systems, API platforms and scalable microservices used in production.

LinkedIn Profile