Deploying Qdrant Vector Database on a VPS for AI Applications: Step-by-Step
TL;DR
In this guide, we will step-by-step configure and deploy a high-performance Qdrant vector database on your own VPS server. Qdrant is a critical component for modern AI applications such as semantic search, recommendation systems, and RAG (Retrieval-Augmented Generation) architectures, allowing you to store and efficiently search high-dimensional vectors. You will get a fully functional, secure, and ready-to-use Qdrant instance, managed via Docker Compose, with automatic HTTPS via Caddy.
- Qdrant will be installed using Docker Compose for easy management and scaling.
- The server will be secured with basic security settings: SSH keys, UFW, and Fail2ban.
- Automatic HTTPS for the Qdrant API will be configured using Caddy, ensuring secure interaction.
- Minimum VPS requirements will be discussed, and recommendations for configuration selection will be provided.
- Scripts for Qdrant data backup and maintenance recommendations will be included.
- All commands and configurations are current for 2026 and tested on Ubuntu 24.04 LTS.
What we are setting up and why
In the modern world of artificial intelligence, data is often represented as high-dimensional vectors (embeddings) that encode the semantic meaning of text, images, audio, or other data. To work efficiently with these vectors — for similarity search, clustering, or use in Retrieval-Augmented Generation (RAG) architectures — specialized databases, called Vector Databases, are required.
Qdrant is a high-performance, open-source vector database designed for storing, indexing, and searching vectors with millisecond latency. It supports various distance metrics, metadata filtering, and scaling. By deploying Qdrant on your own VPS, you gain full control over data, security, and performance, which is critically important for many AI applications.
By the end of this guide, you will have a fully configured and operational Qdrant instance, accessible via HTTPS, ready for integration with your AI models and applications. This will allow you to create your own intelligent systems, such as chatbots capable of answering questions based on your documentation, product recommendation systems, or semantic search services, without relying on expensive cloud providers.
There are alternatives to Qdrant, such as cloud solutions (Pinecone, Weaviate Cloud, Azure AI Search Vector Search) or other self-hosted options (Milvus, Weaviate, Chroma). Cloud services are convenient for a quick start but can be significantly more expensive in the long run, especially with large data volumes or intensive queries. Furthermore, they often impose customization limitations and raise data privacy concerns. Self-hosted deployment on a VPS, in contrast, provides:
- Cost savings: Long-term VPS costs are typically lower than cloud-managed services, especially with stable loads.
- Full control: You manage all aspects of the infrastructure, from the operating system to Qdrant configuration, allowing fine-tuning of performance and security.
- Data privacy: Your data remains on your server, which complies with strict privacy requirements and regulatory norms.
- Flexibility: The ability to install any additional tools and integrate with existing infrastructure.
Choosing a self-hosted solution on a VPS is especially relevant for developers, startups, and companies that value a balance between performance, cost, and data control.
What VPS configuration is needed for this task
VPS requirements for Qdrant heavily depend on the volume of stored vectors, their dimensionality, query intensity, and latency requirements. However, minimum and recommended configurations for getting started can be outlined.
Minimum requirements (for testing and small projects):
- CPU: 2 cores (modern processor, e.g., Intel Xeon E5 or AMD EPYC). Qdrant actively uses the CPU for indexing and searching.
- RAM: 4 GB. Qdrant stores indexes in RAM for fast searching. If the volume of vectors and metadata exceeds available RAM, performance may significantly decrease due to swapping.
- Disk: 50 GB NVMe SSD. Vectors and metadata are stored on disk. NVMe SSD is critical for performance, as Qdrant frequently accesses the disk.
- Network: 100 Mbps. This is sufficient for internal queries, but intensive traffic will require more.
Recommended VPS plan (for small to medium production applications):
For more serious projects, where millions of vectors are planned to be stored and hundreds of queries per second served, the following characteristics will be required:
- CPU: 4-8 cores (e.g., Intel Xeon Gold/Platinum or latest generation AMD EPYC).
- RAM: 16-32 GB. This will allow Qdrant to keep a significant portion of indexes and data in memory, ensuring low latencies.
- Disk: 200-500 GB NVMe SSD. Considering data growth and the need for backup storage.
- Network: 1 Gbps. For high-load APIs and fast vector transfer.
To start with Qdrant on a VPS for AI applications, you can choose a VPS with the specified characteristics, for example, with 4 CPU cores, 16 GB RAM, and 200 GB NVMe SSD. This configuration will provide a good balance between cost and performance for most medium tasks.
When a dedicated server is needed, not a VPS
A dedicated server becomes necessary when:
- Very large data volumes: Billions of vectors or terabytes of data that require more RAM and disk space than most VPS can offer.
- Extreme performance requirements: Thousands of queries per second or critically low latencies that demand maximum CPU and I/O performance without virtualization overhead.
- Complete isolation: Security requirements or regulations that mandate full physical isolation of hardware.
- Specialized equipment: The need to use GPUs for accelerating embedding generation or other tasks that are not always available on a VPS.
If your needs exceed the recommended VPS configurations mentioned above, consider renting a suitable dedicated server.
Location: what it affects
The choice of VPS server location affects:
- Latency: The closer the server is to your end-users or other services that will interact with Qdrant, the lower the latency will be. Choose a location as close as possible to the primary audience of your AI application.
- Data residency: Some regulatory requirements (e.g., GDPR in Europe) mandate storing data in specific geographical regions. Ensure that the chosen location complies with these requirements.
- Cost: VPS prices may vary slightly across different data centers.
Server preparation
After receiving a new VPS server, it is necessary to perform a series of basic configurations to ensure security and stability. We will use the Ubuntu Server 24.04 LTS operating system, which will be current and supported in 2026.
1. Connecting to the server via SSH
Use the credentials provided by your VPS provider for the first connection. This is usually the root user and password.
ssh root@ВАШ_IP_АДРЕС_VPS
2. System update
Always start by updating the package list and installing all available updates.
sudo apt update && sudo apt upgrade -y
3. Creating a new user with sudo privileges
Working as the root user is unsafe. Create a new user and grant them sudo privileges.
# Create a new user "qdrant_admin" (you can choose any other name)
sudo adduser qdrant_admin
# Add the user to the sudo group
sudo usermod -aG sudo qdrant_admin
Now, exit the root session and log in as the new user.
exit
ssh qdrant_admin@ВАШ_IP_АДРЕС_VPS
4. Configuring SSH keys (recommended)
For increased security, use SSH keys instead of passwords. If you don't have a key pair yet, generate them on your local machine:
# On your local machine
ssh-keygen -t rsa -b 4096 -C "[email protected]"
Copy the public key to the server:
# On your local machine
ssh-copy-id qdrant_admin@ВАШ_IP_АДРЕС_VPS
After successfully logging in with the key, disable password authentication for the root user and possibly for all users in the /etc/ssh/sshd_config file. Disable login for root:
# On the server, as qdrant_admin
sudo nano /etc/ssh/sshd_config
Find the line PermitRootLogin yes and change it to PermitRootLogin no. Also, ensure that PasswordAuthentication is set to no if you want to completely disable password login after configuring SSH keys. Restart the SSH service:
sudo systemctl restart sshd
5. Configuring the firewall (UFW)
UFW (Uncomplicated Firewall) is a convenient interface for managing iptables. Let's configure it to allow only the necessary ports.
# Allow SSH (port 22 by default)
sudo ufw allow OpenSSH
# Allow HTTP (for Caddy)
sudo ufw allow http
# Allow HTTPS (for Caddy)
sudo ufw allow https
# Allow Qdrant port (default 6333 for gRPC and REST)
sudo ufw allow 6333/tcp
# Enable the firewall
sudo ufw enable
# Confirm "y"
Check the firewall status:
sudo ufw status verbose
6. Installing Fail2ban
Fail2ban protects against brute-force attacks by automatically blocking IP addresses that make too many failed login attempts.
# Install Fail2ban
sudo apt install fail2ban -y
# Create a copy of the configuration file for customization
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
# Open the file for editing (optional, can be left as default)
sudo nano /etc/fail2ban/jail.local
In jail.local, you can configure bantime (block duration), findtime (period for detecting attempts), and maxretry (maximum number of attempts). Make sure the [sshd] section is enabled (enabled = true). After making changes, restart Fail2ban:
sudo systemctl restart fail2ban
sudo systemctl enable fail2ban
Your server now has basic protection and is ready for Qdrant installation.
Software Installation — Step-by-Step
We will deploy Qdrant using Docker Compose, which is the recommended approach for a production environment. This ensures isolation, ease of management, and updates. The software versions will be current for 2026.
1. Install Docker Engine
First, let's install Docker Engine, which will manage the containers.
# Удалить старые версии Docker, если они есть
sudo apt remove docker docker-engine docker.io containerd runc
# Установить необходимые пакеты для установки Docker через HTTPS
sudo apt install ca-certificates curl gnupg lsb-release -y
# Добавить официальный GPG ключ Docker
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# Добавить репозиторий Docker в APT источники
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Обновить список пакетов с учетом нового репозитория
sudo apt update
# Установить Docker Engine, Docker CLI и Containerd (версия будет актуальной на 2026 год, например, 26.x)
sudo apt install docker-ce docker-ce-cli containerd.io -y
# Добавить текущего пользователя в группу docker для выполнения команд без sudo
sudo usermod -aG docker ${USER}
# Применить изменения группы (потребуется выйти и снова войти в SSH)
newgrp docker
Check Docker installation:
docker run hello-world
You should see the message "Hello from Docker!".
2. Install Docker Compose
Docker Compose allows you to define and run multi-container Docker applications. In modern Docker versions, Docker Compose is integrated into the Docker CLI.
# Проверить, установлен ли Docker Compose (начиная с Docker 20.10, он обычно уже есть)
docker compose version
# Если команда не найдена, установите его отдельно:
# sudo apt install docker-compose-plugin -y
3. Create Directory for Qdrant
Let's create the directory structure for storing Qdrant configuration and data.
# Создать основную директорию для Qdrant
mkdir -p ~/qdrant
cd ~/qdrant
# Создать директорию для хранения данных Qdrant
mkdir -p ./data
# Создать директорию для конфигурации Caddy
mkdir -p ./caddy/Caddyfile
mkdir -p ./caddy/data
mkdir -p ./caddy/config
4. Configure Docker Compose File
Create the docker-compose.yml file in the ~/qdrant directory.
nano docker-compose.yml
Insert the following content:
# docker-compose.yml
version: '3.8'
services:
qdrant:
image: qdrant/qdrant:1.14.0 # Актуальная версия Qdrant на 2026 год
container_name: qdrant_db
restart: unless-stopped
volumes:
- ./data:/qdrant/data # Хранение данных Qdrant
- ./qdrant_config.yaml:/qdrant/config/production.yaml # Опциональный файл конфигурации
ports:
- "6333:6333" # REST API и gRPC
- "6334:6334" # gRPC для внутреннего кластера (если используется)
environment:
# Настройки для производительности и памяти
QDRANT__STORAGE__PERFORMANCE_CONFIG__MAX_SEARCH_THREADS: 4 # Количество потоков для поиска
QDRANT__STORAGE__PERFORMANCE_CONFIG__MAX_OPTIMIZATION_THREADS: 2 # Количество потоков для оптимизации
QDRANT__SERVICE__GRPC_PORT: 6334 # gRPC порт
QDRANT__SERVICE__HTTP_PORT: 6333 # REST API порт
caddy:
image: caddy:2.8.0-alpine # Актуальная версия Caddy на 2026 год
container_name: caddy_proxy
restart: unless-stopped
ports:
- "80:80" # HTTP для Let's Encrypt challenge
- "443:443" # HTTPS
volumes:
- ./caddy/Caddyfile:/etc/caddy/Caddyfile # Файл конфигурации Caddy
- ./caddy/data:/data # Сертификаты Let's Encrypt и данные Caddy
- ./caddy/config:/config # Конфигурация Caddy
depends_on:
- qdrant # Caddy зависит от Qdrant
Explanations:
qdrant/qdrant:1.14.0: Specifies the use of Qdrant image version 1.14.0, which will be stable and current by 2026../data:/qdrant/data: Mounts the local./datadirectory into the Qdrant container for persistent data storage../qdrant_config.yaml: Optional, allows mounting a custom Qdrant configuration file. If not needed, it can be removed.ports: Maps ports 6333 (REST API) and 6334 (gRPC) from the container to the host.environment: Passes environment variables for Qdrant configuration (e.g., number of threads).caddy:2.8.0-alpine: Uses the lightweight Caddy image version 2.8.0.caddy/Caddyfile: Mounts the Caddy configuration file.caddy/dataandcaddy/config: Mount directories for storing Let's Encrypt certificates and Caddy's internal configuration.
5. Start Qdrant and Caddy
After saving docker-compose.yml, start the services:
# Запустить контейнеры в фоновом режиме
docker compose up -d
Check the status of the containers:
docker compose ps
You should see that the qdrant_db and caddy_proxy containers are running.
At this stage, Qdrant is installed and running, but currently only accessible via HTTP on port 6333. Next, we will configure Caddy to provide HTTPS.
Configuration
After installing Qdrant and Caddy, the next step is their proper configuration. The main task is to ensure access to Qdrant via HTTPS using a domain name, and, if necessary, fine-tune Qdrant itself.
1. Configure Caddy for HTTPS
Caddy automatically generates and renews SSL certificates from Let's Encrypt, making it an ideal choice for this task. For this, you will need a domain name pointing to your VPS's IP address. Let's assume your domain is qdrant.example.com.
Edit the ./caddy/Caddyfile file (which we created earlier):
nano ./caddy/Caddyfile
Insert the following content, replacing qdrant.example.com with your actual domain:
# Caddyfile
qdrant.example.com {
# Проксирование всех запросов к контейнеру Qdrant
reverse_proxy qdrant:6333 {
# Дополнительные заголовки для Qdrant (опционально)
header_up Host {host}
header_up X-Real-IP {remote_ip}
header_up X-Forwarded-For {remote_ip}
header_up X-Forwarded-Proto {scheme}
}
# Включить логирование (опционально, для отладки)
log {
output file /var/log/caddy_access.log
}
# Сжатие ответов (опционально, может улучшить производительность)
encode gzip zstd
}
Explanations:
qdrant.example.com: Specifies the domain for which Caddy will handle requests and obtain an SSL certificate.reverse_proxy qdrant:6333: Redirects all incoming requests to the internal Qdrant service (service name fromdocker-compose.yml) on port 6333. Docker Compose creates an internal network where containers can communicate with each other by their service names.log: Configures request logging.encode gzip zstd: Enables response compression, which can speed up data loading for clients.
Save the file and restart the Caddy container to apply the changes:
docker compose restart caddy
Caddy will automatically attempt to obtain an SSL certificate for your domain. Ensure that the DNS A-record for qdrant.example.com points to your VPS's IP address.
2. Qdrant Configuration (Optional)
Qdrant has many settings that can be changed via environment variables in docker-compose.yml or through the production.yaml configuration file. We have already configured some environment variables in docker-compose.yml. If you require more in-depth configuration, create a qdrant_config.yaml file in the ~/qdrant directory.
nano ~/qdrant/qdrant_config.yaml
Example content (for demonstration, not all necessarily used):
# ~/qdrant/qdrant_config.yaml
service:
grpc_port: 6334
http_port: 6333
max_request_size_mb: 256 # Увеличить максимальный размер запроса
enable_cors_for_all: true # Включить CORS для всех источников (для разработки, в продакшене лучше ограничить)
storage:
storage_path: /qdrant/data
snapshots_path: /qdrant/snapshots # Путь для сохранения снапшотов
wal_capacity_mb: 32
segments:
max_indexing_threads: 4
max_search_threads: 8
max_optimization_threads: 2
telemetry_disabled: true # Отключить отправку анонимной телеметрии (рекомендуется)
If you created and mounted this file in docker-compose.yml, restart Qdrant:
docker compose restart qdrant
Important: For a production environment, if enabling CORS, always restrict enable_cors_for_all to specific frontend domains, rather than true.
3. Verify Functionality
After all configurations, let's ensure that Qdrant is accessible and responsive.
Verify Caddy and HTTPS:
Open your domain in a browser: https://qdrant.example.com. You should see a response from Qdrant, for example, a JSON message indicating that it is the Qdrant API. Also, ensure that the certificate is valid (green padlock in the browser).
Verify Qdrant API via curl:
# Проверить статус Qdrant через настроенный домен с HTTPS
curl -k https://qdrant.example.com/collections
# Или если вы не доверяете сертификату (для тестирования)
# curl -k https://qdrant.example.com/collections
# Проверить состояние службы Qdrant внутри контейнера
docker exec qdrant_db curl -s http://localhost:6333/collections
Both commands should return a JSON response, for example: {"result":{"collections":[]},"status":"ok","time":...}, which means Qdrant is running and ready. If you see an error, check the container logs:
docker compose logs qdrant
docker compose logs caddy
Your Qdrant vector database is now fully deployed and secured with HTTPS!
Backups and Maintenance
Backup and regular maintenance are critically important aspects for any production system, including Qdrant. Loss of vector data can be catastrophic for AI applications.
1. What to Back Up
For Qdrant, the following components must be backed up regularly:
- Qdrant Data: This is the most important component, including all collections, vectors, and metadata. They are stored in the directory we mounted as
./data(e.g.,~/qdrant/data). - Configuration Files: If you are using a custom
qdrant_config.yaml, it should also be backed up. - Caddy Configuration: The
Caddyfileand thecaddy/dataandcaddy/configdirectories (for storing SSL certificates). - Docker Compose File:
docker-compose.yml, so that the entire infrastructure can be quickly restored.
2. Simple Auto-Backup Script
We will create a simple script that will create Qdrant snapshots and then archive them along with other important files. Qdrant provides an API for storing snapshots.
Create the script backup_qdrant.sh in the ~/qdrant/scripts directory:
mkdir -p ~/qdrant/scripts
nano ~/qdrant/scripts/backup_qdrant.sh
Script content:
#!/bin/bash
# --- Settings ---
BACKUP_DIR="/var/backups/qdrant" # Directory for storing backups on the server
QDRANT_CONTAINER_NAME="qdrant_db"
QDRANT_HOST="localhost:6333" # Internal access to Qdrant from inside Docker
TIMESTAMP=$(date +%Y%m%d%H%M%S)
SNAPSHOT_NAME="qdrant_snapshot_${TIMESTAMP}.snapshot"
QDRANT_DATA_PATH="/qdrant/data" # Data path inside the Qdrant container
LOCAL_QDRANT_DATA_PATH="/home/qdrant_admin/qdrant/data" # Data path on the host
# --- Create backup directory ---
mkdir -p "${BACKUP_DIR}"
# --- 1. Create Qdrant snapshot ---
echo "Creating Qdrant snapshot..."
# Use Docker exec to create a snapshot via Qdrant API
docker exec -it "${QDRANT_CONTAINER_NAME}" curl -X POST "http://${QDRANT_HOST}/collections/{collection_name}/snapshots" -H "Content-Type: application/json" -d '{}'
# Qdrant saves snapshots to its data directory.
# We will back up the entire Qdrant data directory, which includes snapshots.
# This simplifies the process, as snapshots are already in the mounted directory.
# --- 2. Archiving all necessary files ---
echo "Archiving Qdrant data and configurations..."
tar -czf "${BACKUP_DIR}/qdrant_backup_${TIMESTAMP}.tar.gz" -C /home/qdrant_admin/qdrant data docker-compose.yml qdrant_config.yaml caddy/Caddyfile caddy/data caddy/config
# --- 3. Clean up old backups (e.g., keep the last 7 days) ---
echo "Cleaning up old backups..."
find "${BACKUP_DIR}" -type f -name "qdrant_backup_*.tar.gz" -mtime +7 -delete
echo "Qdrant backup completed: ${BACKUP_DIR}/qdrant_backup_${TIMESTAMP}.tar.gz"
Important notes:
- The script creates snapshots for each collection. If there are many collections, this can be slow. Qdrant 1.14.0 (estimated version for 2026) may have an API for creating global snapshots. In the current script, for simplicity, we rely on Qdrant saving snapshots to its data directory, and we back up this entire directory.
- To create a collection snapshot, you will need to replace
{collection_name}with the name of your collection. For automation, you can get a list of collections via API and create a loop. For simplicity, the entire data directory, which already contains snapshots, is backed up here. tar -czf ... -C /home/qdrant_admin/qdrant data docker-compose.yml ...: This command archives thedatadirectory (which contains Qdrant data and snapshots created by it), as well asdocker-compose.ymland Caddy configurations.
Make the script executable:
chmod +x ~/qdrant/scripts/backup_qdrant.sh
3. Scheduling Backups with Cron
Add the script to Cron for automatic execution. For example, daily at 3:00 AM.
crontab -e
Add the following line to the end of the file:
0 3 * * * /home/qdrant_admin/qdrant/scripts/backup_qdrant.sh >> /var/log/qdrant_backup.log 2>&1
This line means: "Every day at 3 hours 0 minutes, run the script and redirect its output to a log file."
4. Where to Store Backups (External Storage)
Storing backups on the same server as the data is risky. If the server fails, you will lose both data and backups. It is recommended to use external storage:
- S3-compatible storage: Cloud services such as AWS S3, Backblaze B2, DigitalOcean Spaces. You can use
rcloneors3cmdto automatically synchronize archives from/var/backups/qdrantto S3. - Separate VPS: You can set up a second, less powerful VPS and use
rsyncover SSH to copy backups. - Restic/BorgBackup: These tools provide deduplicated and encrypted backup, supporting many backends, including S3 and SSH.
Example of using rclone for S3 (assuming rclone is installed and configured):
# Add to backup_qdrant.sh script after tar archiving
echo "Synchronizing backups with S3..."
rclone sync "${BACKUP_DIR}" "s3_remote:qdrant-backups" --include "*.tar.gz"
5. Updates: rolling vs maintenance window
- Qdrant Update: To update Qdrant to a new version (e.g., from 1.14.0 to 1.15.0), it is sufficient to change the image tag in
docker-compose.ymland restart the container:# Change image: qdrant/qdrant:1.14.0 to qdrant/qdrant:1.15.0 nano docker-compose.yml docker compose pull qdrant # Download new image docker compose up -d # Restart with new imageQdrant is usually backward compatible, but always read the release notes. For critical updates, it is better to plan a maintenance window to minimize risks.
- OS and Docker Update: Regularly update the operating system and Docker Engine. You can use
sudo apt update && sudo apt upgrade -yfor this. This is also recommended to be done during a maintenance window, as a server reboot may be required. - Rolling updates (for a cluster): If you are using Qdrant in cluster mode (more than one node), you can perform rolling updates by updating nodes one by one to maintain service availability. This is not relevant for a single VPS.
Always test updates in a staging environment before applying them to production.
Troubleshooting + FAQ
This section collects typical problems that may arise during Qdrant deployment and operation, as well as answers to frequently asked questions.
Caddy does not get an SSL certificate or fails to start
Error: Caddy does not start, or you receive a "Your connection is not private" error in your browser.
What to check:
- Ensure that the DNS record (A type) for your domain (e.g.,
qdrant.example.com) points to the public IP address of your VPS. Usedig qdrant.example.comor online tools to verify. - Check Caddy container logs:
docker compose logs caddy. Look for errors related to Let's Encrypt or port binding. - Ensure that ports 80 and 443 are open in the UFW firewall:
sudo ufw status verbose. - Check
Caddyfilesyntax:docker run --rm -it -v ~/qdrant/caddy/Caddyfile:/etc/caddy/Caddyfile caddy:2.8.0-alpine caddy validate --config /etc/caddy/Caddyfile.
How to fix: Correct the DNS record, open ports in UFW, fix Caddyfile syntax, and restart Caddy: docker compose restart caddy.
Qdrant is unavailable or returns errors
Error: Requests to Qdrant (via Caddy or directly to port 6333) fail or return 500/502 errors.
What to check:
- Check Qdrant container status:
docker compose ps. Ensure it is in a "running" state. - Check Qdrant container logs:
docker compose logs qdrant. Look for error messages or exceptions. - Ensure Qdrant is accessible within the Docker network:
docker exec qdrant_db curl -s http://localhost:6333/collections. - Check if the server has enough RAM. If Qdrant uses too much memory, it might be killed by the OOM killer.
How to fix: Restart the Qdrant container: docker compose restart qdrant. If there is a memory issue, consider increasing VPS RAM or optimizing Qdrant configuration (e.g., reducing cache sizes). Check the qdrant_config.yaml file for errors.
Slow search or vector indexing
Error: Search queries or indexing operations take too long.
What to check:
- Disk I/O: Ensure your VPS uses NVMe SSD. A slow disk significantly impacts Qdrant performance.
- RAM: Qdrant actively uses RAM for indexes. If RAM is insufficient, data is constantly loaded from disk, which slows down operations. Check memory usage:
docker stats. - CPU: Search and indexing are CPU-intensive operations. Check CPU load:
htop. - Qdrant Configuration: Parameters
max_search_threadsandmax_optimization_threadsinqdrant_config.yamlor environment variables. Increase them if there are free CPU cores. - Vector dimensionality and index type: Very high dimensionality or an unsuitable index type (e.g., without using HNSW) can slow down search.
How to fix: Increase VPS resources (RAM, CPU). Optimize Qdrant configuration. Ensure you are using an HNSW index for collections. Consider reducing vector dimensionality if possible.
What is the minimum suitable VPS configuration?
For small projects, testing, and development, a VPS with 2 CPU cores, 4 GB RAM, and 50 GB NVMe SSD will be minimally suitable. This will be enough to store several hundred thousand medium-dimensionality vectors and handle low load. However, for a production environment with millions of vectors and active queries, a minimum of 4 CPU cores, 16 GB RAM, and 200 GB NVMe SSD is recommended.
What to choose — VPS or dedicated for this task?
The choice between a VPS and a dedicated server depends on the scale of your project. A VPS is ideal for most medium to large AI applications, providing a good balance between cost, flexibility, and performance. It is suitable if you are working with millions of vectors and moderate to high load. A dedicated server is necessary for very large projects (billions of vectors, terabytes of data), extremely high load, or if specialized hardware resources (e.g., GPU) are required, which are not always available on a VPS. A dedicated server also provides complete physical isolation and predictable performance without "noisy neighbor" effects of virtualization.
How to update Qdrant to a new version?
Updating Qdrant deployed via Docker Compose is very simple. You need to change the image tag in the docker-compose.yml file (e.g., from qdrant/qdrant:1.14.0 to qdrant/qdrant:1.15.0), save the file, then run docker compose pull qdrant to download the new image and docker compose up -d to restart the container with the new version. Always read Qdrant documentation on version compatibility before updating.
Can I use Qdrant without Caddy (without HTTPS)?
Yes, you can access Qdrant directly via HTTP using your VPS IP address and port 6333 (e.g., http://YOUR_VPS_IP_ADDRESS:6333). However, this is highly not recommended for a production environment, as all traffic will be transmitted unencrypted, which is insecure. Caddy provides HTTPS automatically and for free, so its use is a security standard.
Conclusions and Next Steps
Congratulations! You have successfully deployed Qdrant Vector Database on your VPS server, securing it with SSH keys, UFW, Fail2ban, and HTTPS via Caddy. Your own vector database is ready to operate, providing a powerful foundation for your AI applications.
Now that Qdrant is up and running, you can:
- Integrate Qdrant with your AI applications: Start uploading vectors (embeddings) from your data and use Qdrant for semantic search, recommendations, or in RAG architectures. Use official Qdrant clients for Python, Rust, Go, or TypeScript.
- Monitoring and Optimization: Set up a monitoring system (e.g., Prometheus + Grafana) to track Qdrant performance (CPU, RAM, I/O usage, query latencies) and optimize the configuration as needed.
- Scaling: As requirements grow, consider horizontally scaling Qdrant by deploying it in cluster mode on multiple VPS or dedicated servers to increase fault tolerance and throughput.