• Home
  • Cloud VPS
    • Hong Kong VPS
    • US VPS
  • Dedicated Servers
    • Hong Kong Servers
    • US Servers
    • Singapore Servers
    • Japan Servers
  • Company
    • Contact Us
    • Blog
logo logo
  • Home
  • Cloud VPS
    • Hong Kong VPS
    • US VPS
  • Dedicated Servers
    • Hong Kong Servers
    • US Servers
    • Singapore Servers
    • Japan Servers
  • Company
    • Contact Us
    • Blog
ENEN
  • 简体简体
  • 繁體繁體
Client Area

Vector Database on Hong Kong VPS: Build a RAG System with pgvector (2026)

September 4, 2026

Retrieval-Augmented Generation (RAG) grounds AI responses in your actual data — customer support knowledge bases, product documentation, internal wikis — rather than hallucinated training data. The core component is a vector database that stores semantic embeddings and retrieves the most relevant documents for each query. Running pgvector or Qdrant on a Hong Kong VPS keeps your proprietary knowledge base on your infrastructure, makes the vector search endpoint accessible to mainland Chinese applications via CN2 GIA, and eliminates per-query API costs from managed vector database services.


How RAG Works

<code">
[Document ingestion]
  Your documents → Embedding model → Vectors → Vector DB

[Query time]
  User question → Embedding → Vector similarity search
       ↓
  Top-K relevant document chunks retrieved
       ↓
  LLM prompt: "Answer using these documents: [chunks]"
       ↓
  Grounded, accurate response

Option A: pgvector (PostgreSQL Extension)

pgvector adds vector similarity search to your existing PostgreSQL installation — no additional database required, queries join vector search with relational data.

Install pgvector

<code">apt install -y postgresql-16-pgvector

# Enable extension in your database
sudo -u postgres psql -d myapp << 'SQL'
CREATE EXTENSION IF NOT EXISTS vector;

-- Create a table with vector column (1536 dimensions for OpenAI text-embedding-3-small)
-- Use 768 for nomic-embed-text (Ollama), 384 for all-MiniLM
CREATE TABLE documents (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    content TEXT NOT NULL,
    metadata JSONB,
    embedding vector(768),
    created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Create IVFFlat index for approximate nearest-neighbour search
-- lists = sqrt(number of rows) is a good starting point
CREATE INDEX idx_documents_embedding
    ON documents
    USING ivfflat (embedding vector_cosine_ops)
    WITH (lists = 100);
SQL

Ingest Documents (Python)

<code"># pip install psycopg2-binary openai pgvector --break-system-packages

import psycopg2
import json
from openai import OpenAI

# Or use Ollama for free, local embeddings:
# client = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama")
# model = "nomic-embed-text"

client = OpenAI(api_key="YOUR_KEY")
conn = psycopg2.connect("postgresql://myapp_user:pass@localhost/myapp")
cur = conn.cursor()

def ingest_document(text: str, metadata: dict = {}):
    # Generate embedding
    response = client.embeddings.create(
        model="text-embedding-3-small",
        input=text
    )
    embedding = response.data[0].embedding

    # Store in PostgreSQL
    cur.execute(
        "INSERT INTO documents (content, metadata, embedding) VALUES (%s, %s, %s)",
        (text, json.dumps(metadata), embedding)
    )
    conn.commit()

# Ingest your knowledge base
documents = [
    ("Our Hong Kong VPS plans start at 1 GB RAM with CN2 GIA routing.", {"source": "pricing", "category": "vps"}),
    ("CN2 GIA provides premium routing to mainland China at 30-50ms from Hong Kong.", {"source": "technical", "category": "network"}),
    ("To set up WireGuard VPN, install wireguard package and generate keypairs.", {"source": "docs", "category": "tutorial"}),
]

for content, metadata in documents:
    # Chunk long documents (max ~500 tokens per chunk for best retrieval)
    ingest_document(content, metadata)

print(f"Ingested {len(documents)} documents")

Query (Similarity Search)

<code"># Retrieve top-5 most relevant documents for a query
def retrieve_context(query: str, top_k: int = 5) -> list[dict]:
    # Embed the query
    q_embedding = client.embeddings.create(
        model="text-embedding-3-small",
        input=query
    ).data[0].embedding

    # Vector similarity search (cosine distance)
    cur.execute("""
        SELECT content, metadata,
               1 - (embedding <=> %s::vector) AS similarity
        FROM documents
        WHERE 1 - (embedding <=> %s::vector) > 0.7   -- Minimum similarity threshold
        ORDER BY embedding <=> %s::vector
        LIMIT %s
    """, (q_embedding, q_embedding, q_embedding, top_k))

    results = []
    for content, metadata, similarity in cur.fetchall():
        results.append({
            "content": content,
            "metadata": metadata,
            "similarity": float(similarity)
        })
    return results

# Use in RAG pipeline
def rag_answer(question: str) -> str:
    # 1. Retrieve relevant documents
    context_docs = retrieve_context(question)
    context = "\n\n".join([doc["content"] for doc in context_docs])

    # 2. Generate answer grounded in retrieved context
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[
            {"role": "system", "content": f"""Answer the user's question using ONLY the following context.
If the answer is not in the context, say "I don't have information about that."

Context:
{context}"""},
            {"role": "user", "content": question}
        ]
    )
    return response.choices[0].message.content

# Test
print(rag_answer("What latency can I expect from Hong Kong to China?"))

Option B: Qdrant (Dedicated Vector Database)

Qdrant is a purpose-built vector database with advanced filtering, payload storage, and a REST/gRPC API — better for large-scale RAG systems than pgvector.

<code">docker run -d \
  --name qdrant \
  --restart unless-stopped \
  -p 127.0.0.1:6333:6333 \
  -v /opt/qdrant/storage:/qdrant/storage \
  qdrant/qdrant:latest

# Verify
curl http://localhost:6333/healthz

Create Collection and Ingest

<code"># pip install qdrant-client --break-system-packages

from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, PointStruct
import uuid

qdrant = QdrantClient(host="localhost", port=6333)

# Create collection
qdrant.create_collection(
    collection_name="knowledge_base",
    vectors_config=VectorParams(size=768, distance=Distance.COSINE),
)

# Ingest with rich metadata (Qdrant payload)
def ingest_to_qdrant(text: str, metadata: dict):
    embedding = get_embedding(text)  # Your embedding function

    qdrant.upsert(
        collection_name="knowledge_base",
        points=[PointStruct(
            id=str(uuid.uuid4()),
            vector=embedding,
            payload={"content": text, **metadata}
        )]
    )

# Search with filters
results = qdrant.search(
    collection_name="knowledge_base",
    query_vector=get_embedding("CN2 GIA network routing"),
    query_filter={
        "must": [{"key": "category", "match": {"value": "network"}}]
    },
    limit=5,
    with_payload=True
)

Build a RAG API Endpoint

<code"># FastAPI RAG endpoint — serves your internal knowledge base
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Question(BaseModel):
    question: str
    top_k: int = 5

@app.post("/api/ask")
async def ask(body: Question):
    # 1. Retrieve relevant context
    context_docs = retrieve_context(body.question, body.top_k)

    if not context_docs:
        return {"answer": "No relevant information found.", "sources": []}

    # 2. Generate grounded answer
    answer = rag_answer(body.question, context_docs)

    return {
        "answer": answer,
        "sources": [
            {"content": doc["content"][:200] + "...", "similarity": doc["similarity"]}
            for doc in context_docs
        ]
    }

Document Chunking Strategy

<code"># Good chunking is critical for RAG quality
def chunk_document(text: str, chunk_size: int = 500, overlap: int = 50) -> list[str]:
    """Split document into overlapping chunks for better retrieval."""
    words = text.split()
    chunks = []

    for i in range(0, len(words), chunk_size - overlap):
        chunk = ' '.join(words[i:i + chunk_size])
        if chunk:
            chunks.append(chunk)

    return chunks

# Ingest a large document
with open("product_manual.txt") as f:
    full_text = f.read()

chunks = chunk_document(full_text)
for i, chunk in enumerate(chunks):
    ingest_document(chunk, {
        "source": "product_manual.txt",
        "chunk_index": i,
        "total_chunks": len(chunks)
    })

print(f"Ingested {len(chunks)} chunks from product manual")

Cost Comparison: Self-Hosted vs Managed Vector DB

Solution10M vectors1M queries/monthChina accessible
Pinecone (managed)~$70/month~$100/monthNo (US only)
Weaviate Cloud~$50/month~$80/monthVariable
pgvector on HK VPSDisk space only$0 (CPU cost)Yes (CN2 GIA)
Qdrant on HK VPSDisk space only$0 (CPU cost)Yes (CN2 GIA)

Conclusion

pgvector on your existing Hong Kong VPS PostgreSQL instance is the lowest-friction starting point for RAG — no new infrastructure, queries join vector search with relational data, and backups are part of your existing PostgreSQL backup routine. Qdrant adds advanced features (filtering, quantisation, distributed mode) as your vector dataset grows. Both approaches keep your proprietary knowledge base on your infrastructure, accessible to mainland Chinese applications via CN2 GIA at 30–50ms — a meaningful advantage over managed vector database services hosted in the US or EU.

Build your AI stack: Browse Server.HK Hong Kong VPS plans — pair a 8 GB VPS with pgvector and Ollama for a fully self-hosted RAG pipeline with no per-query costs.

Recent Posts

  • Monorepo Deployment on Hong Kong VPS: Turborepo and pnpm (2026)
  • GitLab Runner on Hong Kong VPS: Self-Hosted CI/CD Pipeline (2026)
  • Deploy Spring Boot on Hong Kong VPS: Java Microservices for Asia (2026)
  • TimescaleDB on Hong Kong VPS: Time-Series Data for Asia-Pacific (2026)
  • Hong Kong VPS China Accessibility Checklist: Make Your Site Work (2026)

Recent Comments

  1. Hong Kong VPS Uptime and SLA: What 99.9% Uptime Really Means for Your Business (2026) - Server.HK on How to Monitor Your Hong Kong VPS: Uptime, Performance, and Alert Setup Guide (2026)
  2. Best Hong Kong VPS Providers in 2026: Compared by Speed, Routing, and Value - Server.HK on How to Migrate Your Website to a Hong Kong VPS: Zero-Downtime Transfer Guide (2026)
  3. vibramycin injection on How to Choose the Right Hong Kong VPS Plan: A Buyer’s Guide for 2026
  4. allopurinol for gout on CN2 GIA vs BGP vs CN2 GT: What’s the Real Difference for China Connectivity?
  5. antibiotics online purchase on How to Set Up a WordPress Site on a Hong Kong VPS with aaPanel (Step-by-Step 2026)

Knowledge Base

Access detailed guides, tutorials, and resources.

Live Chat

Get instant help 24/7 from our support team.

Send Ticket

Our team typically responds within 10 minutes.

logo
Alipay Cc-paypal Cc-stripe Cc-visa Cc-mastercard Bitcoin
Cloud VPS
  • Hong Kong VPS
  • US VPS
Dedicated Servers
  • Hong Kong Servers
  • US Servers
  • Singapore Servers
  • Japan Servers
More
  • Contact Us
  • Blog
  • Legal
© 2026 Server.HK | Hosting Limited, Hong Kong | Company Registration No. 77008912
Telegram
Telegram @ServerHKBot