Why self-host Typesense on a VPS
Managed search services (Algolia, etc.) bill per query and per indexed document: the bill climbs quickly as soon as your catalogue grows. Typesense offers instant search (p95 latency under 50 ms) with typo tolerance and relevance-based sorting, all in a single binary with no JVM. By deploying it on your own VPS, you set a predictable monthly cost, you keep your user indexes out of a third-party cloud, and you can place your instance as close as possible to your application to minimize network latency.
What you gain in concrete terms
- A fixed cost instead of per-query billing that explodes with traffic
- Minimal latency by placing Typesense on the same private network as your app
- Fault tolerance and search-as-you-type (typo-tolerance) with no complex tuning
- Index data and search logs kept on your infrastructure
- A reduced memory footprint: no JVM, a single process to supervise
- A simple REST API and scoped API keys (search-only / admin) to secure the front-end
Realistic prerequisites
Typesense loads its indexes into memory: size the RAM according to the size of your corpus. For a catalogue of up to a few hundred thousand documents, a 2 vCPU / 4 GB RAM VPS is more than enough. Count on 8 GB beyond a million documents or for vector fields (semantic search). Plan for an SSD for data persistence, Docker and Docker Compose installed, as well as a subdomain such as search.yourdomain.com pointing to the VPS IP.
Step-by-step deployment
Prepare the VPS and Docker
Update the system, install Docker and the Compose plugin, then create a dedicated folder: mkdir -p /opt/typesense/data. This volume will host the indexes persisted on the SSD.
Define the service with a strong API key
In a docker-compose.yml, declare the typesense/typesense:0.25.2 image, mount /opt/typesense/data:/data, expose port 8108 locally only (127.0.0.1:8108) and pass --api-key via a variable generated with openssl rand -base64 32.
Launch and check health
Start with docker compose up -d then test: curl http://127.0.0.1:8108/health should return {"ok":true}. Then create a first collection via the REST API to validate indexing.
Place a reverse proxy + SSL
Configure Nginx (or Caddy) to expose search.yourdomain.com to 127.0.0.1:8108. With Caddy, a simple reverse_proxy 127.0.0.1:8108 block generates the Let's Encrypt certificate automatically; with Nginx, use certbot --nginx.
Compartmentalize the API keys
Never distribute the admin key on the browser side. Generate a search-only scoping key (actions: documents:search) and expose only that one in your JavaScript front-end.
Automate backups
Schedule a docker exec of the /operations/snapshot endpoint or a tar of the /opt/typesense/data volume pushed each night to a remote object storage.
Enabling a single node in persistent mode is enough for most projects, but if your search becomes critical, set up a 3-node Raft cluster (--nodes) across 3 VPS for high availability: Typesense handles replication itself and automatically fails over the leader in case of failure, with no application-level load balancer on the write side.