Why Self-Host Your Search Engine on a VPS
A dedicated search engine replaces slow LIKE '%...%' queries with instant search that is typo-tolerant and ranked by relevance. Self-hosting it on a VPS spares you the per-search or per-document billing of SaaS solutions and keeps your index (and therefore your customer data, your catalog) on your own infrastructure. Meilisearch and Typesense are designed for 'search-as-you-type': responses in a few milliseconds, a simple REST API, typo tolerance, and facets included. Meilisearch shines with its ease of use and default relevance quality; Typesense emphasizes raw performance, fine-grained ranking control, and high-availability clustering. Typesense keeps the entire searchable index in RAM; Meilisearch stores it on disk (LMDB, a memory-mapped file) and uses RAM as a cache: either way, memory directly sizes your VPS.
The Strengths of a Self-Hosted Search Engine
- Instant search with typo tolerance, without coding the algorithm
- No billing per indexed document or per query
- Index and business data kept on your VPS
- Facets, filters, and sorting to build rich catalog interfaces
- A REST API and scoped keys for secure frontend-side use
- Synonyms and relevance rules adjustable to your business vocabulary
Prerequisites: RAM Above All
RAM is the critical resource: Typesense loads the entire searchable index into memory (its documentation counts 2 to 3 times the size of the searchable fields), and Meilisearch answers faster the more of its index fits in memory. For a few tens of thousands of documents, 1 to 2 GB of RAM and 1 vCPU are enough. For hundreds of thousands to a few million documents with facets, aim for 4 GB and 2 vCPUs. An SSD disk speeds up persistence and reloading at startup. You'll need Docker and Compose, a subdomain (search.yourdomain.com) if you expose the API to the frontend, and a reverse proxy for TLS. Plan for a strong master key and search keys with limited scope so that you never expose the admin key on the browser side.
Deploy Meilisearch (or Typesense) on a VPS
Define the Docker Service
Declare
getmeili/meilisearch(ortypesense/typesense), mount a volume for index persistence, and pass the master key via an environment variable (MEILI_MASTER_KEYorTYPESENSE_API_KEY), generated withopenssl rand -base64 32and kept in.env. For Meilisearch, addMEILI_ENV=production: the master key (at least 16 bytes) becomes mandatory and the built-in search preview is disabled. Bind port7700/8108locally only.Launch and Check Health
Run
docker compose up -d, then testcurl http://127.0.0.1:7700/health. Anavailableresponse confirms that the engine is ready to receive documents.Create the Index and Feed in the Data
Send your documents as JSON through the API (POST to
/indexes/produits/documents). Define the searchable, filterable, and sortable attributes; in a search engine, the declaration order of the searchable attributes directly influences relevance.Expose the API Behind a Reverse Proxy
Proxy search.yourdomain.com to the local port with Caddy or Nginx for HTTPS. Restrict CORS to your application domain: in the proxy for Meilisearch, which has no CORS option, and with
--cors-domainsfor Typesense. CORS only blocks browsers: the scoped key is what actually protects the engine.Generate Scoped Keys
Create a key limited to search operations on a given index, to be used on the browser side. The master key must never leave the server or appear in the frontend code.
Sync with Your Database
Set up a job (webhook or scheduled task) that pushes creations and updates to the index on every database change, to keep search consistent with the source of truth.
Scroll the table
| Criterion | Meilisearch | Typesense |
|---|---|---|
| Getting started | Very simple, excellent default relevance | Simple, more explicit control |
| Typo tolerance | Native and tunable | Native, configurable per field |
| Ranking control | Ordered ranking rules | Very granular (per-field ranking, weights) |
| Facets / filters | Complete | Complete and high-performance |
| High availability | Replication and sharding reserved for the Enterprise Edition | Built-in Raft clustering |
| Memory usage | Index on disk, RAM used as a cache | Entire searchable index in RAM |
| Vector search | Supported | Supported |
| Language / deployment | Rust, single binary (MIT; Enterprise Edition under BUSL 1.1) | C++, single binary (GPL v3) |
Before oversizing your VPS, only index the fields that are actually searchable. Storing a large, full HTML text in the index needlessly inflates RAM: index the title, the tags, and a summary, and keep the heavy content in the database, fetched after the click. You'll noticeably reduce the memory footprint without losing relevance.