Install Typesense on Linux
Install Typesense on Debian, Ubuntu, Fedora, or Arch; configure a secure API key; define a collection schema; index documents; and run filtered search queries.
Before you start
- ▸A Linux server with at least 512 MB RAM and curl installed
- ▸sudo or root access to install packages and write system config files
- ▸Port 8108 available and not blocked by a local firewall for localhost testing
Typesense is a fast, open-source search engine built for low-latency full-text search. It is simpler to operate than Elasticsearch, ships as a single binary, and stores data on disk so restarts are safe. This guide walks through installing Typesense on a Linux server, securing it with an API key, creating a collection with a schema, indexing documents, and running basic queries against the HTTP API.
Install Typesense
Debian / Ubuntu
Add the official apt repository and install the package. Replace 27.0 with the latest stable release shown on the Typesense releases page.
curl -sL https://dl.typesense.org/deb/pubkey.gpg | sudo gpg --dearmor -o /usr/share/keyrings/typesense-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/typesense-archive-keyring.gpg] https://dl.typesense.org/deb stable main" \
| sudo tee /etc/apt/sources.list.d/typesense.list
sudo apt update
sudo apt install typesense
Fedora / RHEL / Rocky
Use the RPM repository. The repo file works for RHEL 8/9, Rocky, and Fedora.
sudo tee /etc/yum.repos.d/typesense.repo <<'EOF'
[typesense]
name=Typesense
baseurl=https://dl.typesense.org/rpm/stable/
enabled=1
gpgcheck=1
gpgkey=https://dl.typesense.org/rpm/pubkey.gpg
EOF
sudo dnf install typesense
Arch Linux
Typesense is available in the AUR. Use your preferred AUR helper.
yay -S typesense-bin
Binary fallback (any distro)
If none of the above suits your setup, download the prebuilt binary directly. Adjust the version and architecture as needed.
TSVER=27.0
curl -Lo typesense-server.tar.gz \
"https://dl.typesense.org/releases/${TSVER}/typesense-server-${TSVER}-linux-amd64.tar.gz"
tar -xf typesense-server.tar.gz
sudo mv typesense-server /usr/local/bin/
sudo chmod +x /usr/local/bin/typesense-server
Configure Typesense
The package installs a default config at /etc/typesense/typesense-server.ini. The most important values are the data directory and the API key. The API key is a shared secret that every client must present — treat it like a password.
sudo mkdir -p /var/lib/typesense
sudo tee /etc/typesense/typesense-server.ini <<'EOF'
[server]
api-address = 0.0.0.0
api-port = 8108
data-dir = /var/lib/typesense
api-key = YOUR_STRONG_API_KEY_HERE
log-dir = /var/log/typesense
EOF
sudo chown -R typesense:typesense /var/lib/typesense /var/log/typesense
Replace YOUR_STRONG_API_KEY_HERE with a random string of at least 32 characters. You can generate one with:
openssl rand -hex 24
If you are exposing Typesense beyond localhost, place it behind a reverse proxy (nginx, Caddy) with TLS, or restrict port 8108 in your firewall to trusted sources only.
Start and Enable the Service
The package installs a systemd unit. Enable it at boot and start it now.
sudo systemctl enable --now typesense-server
If you installed via the binary fallback, create a minimal unit file first:
sudo tee /etc/systemd/system/typesense-server.service <<'EOF'
[Unit]
Description=Typesense Search Server
After=network.target
[Service]
ExecStart=/usr/local/bin/typesense-server --config=/etc/typesense/typesense-server.ini
Restart=on-failure
User=typesense
Group=typesense
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now typesense-server
Verify the Installation
Check that the service is healthy and the API responds. Substitute your actual API key.
sudo systemctl status typesense-server
curl -H "X-TYPESENSE-API-KEY: YOUR_STRONG_API_KEY_HERE" \
http://localhost:8108/health
A healthy node returns:
{"ok":true}
Create a Collection with a Schema
In Typesense, a collection is equivalent to a table or an index. You define a schema upfront — field names, data types, and which fields are facetable or sortable. The schema drives how Typesense indexes and serves queries.
The example below creates a books collection. Fields marked facet: true can be used for aggregated filtering; sort: true fields can be used in order-by clauses.
curl -X POST http://localhost:8108/collections \
-H "X-TYPESENSE-API-KEY: YOUR_STRONG_API_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{
"name": "books",
"fields": [
{"name": "title", "type": "string"},
{"name": "author", "type": "string", "facet": true},
{"name": "year", "type": "int32", "facet": true, "sort": true},
{"name": "rating", "type": "float", "sort": true},
{"name": "genres", "type": "string[]", "facet": true}
],
"default_sorting_field": "rating"
}'
Typesense returns the created collection object including a document count of 0. Supported field types include string, int32, int64, float, bool, geopoint, and array variants such as string[].
Index Documents
Index individual documents with a POST to /collections/books/documents. Typesense requires each document to have an id field of type string.
curl -X POST http://localhost:8108/collections/books/documents \
-H "X-TYPESENSE-API-KEY: YOUR_STRONG_API_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{"id":"1","title":"The Linux Command Line","author":"William Shotts","year":2019,"rating":4.7,"genres":["technology","education"]}'
For bulk imports, use the /import endpoint with newline-delimited JSON (JSONL). This is significantly faster than one-document-at-a-time for large datasets.
cat <<'EOF' | curl -X POST \
"http://localhost:8108/collections/books/documents/import?action=create" \
-H "X-TYPESENSE-API-KEY: YOUR_STRONG_API_KEY_HERE" \
-H "Content-Type: text/plain" \
--data-binary @-
{"id":"2","title":"Unix and Linux System Administration Handbook","author":"Evi Nemeth","year":2017,"rating":4.8,"genres":["technology"]}
{"id":"3","title":"How Linux Works","author":"Brian Ward","year":2021,"rating":4.6,"genres":["technology","education"]}
EOF
Run Search Queries
Queries go to /collections/{name}/documents/search as GET requests with query parameters. The two required parameters are q (search term) and query_by (comma-separated fields to search).
Basic keyword search
curl -G http://localhost:8108/collections/books/documents/search \
-H "X-TYPESENSE-API-KEY: YOUR_STRONG_API_KEY_HERE" \
--data-urlencode "q=linux" \
--data-urlencode "query_by=title,author"
Filter and sort
Use filter_by for structured filtering and sort_by to order results. The syntax for filters is field:operator:value.
curl -G http://localhost:8108/collections/books/documents/search \
-H "X-TYPESENSE-API-KEY: YOUR_STRONG_API_KEY_HERE" \
--data-urlencode "q=linux" \
--data-urlencode "query_by=title" \
--data-urlencode "filter_by=year:>2018 && rating:>4.5" \
--data-urlencode "sort_by=rating:desc"
Faceted search
Request facet counts by adding facet_by. The response includes a facet_counts array useful for building filter sidebars.
curl -G http://localhost:8108/collections/books/documents/search \
-H "X-TYPESENSE-API-KEY: YOUR_STRONG_API_KEY_HERE" \
--data-urlencode "q=*" \
--data-urlencode "query_by=title" \
--data-urlencode "facet_by=author,genres" \
--data-urlencode "max_facet_values=5"
Passing q=* matches all documents, which is handy for browsing or listing everything in the collection.
Troubleshooting
- Service fails to start: Run
journalctl -u typesense-server -n 50and look for permission errors on the data directory or a port conflict on 8108. Confirm the data directory is owned by thetypesenseuser. - 401 Unauthorized from the API: The
X-TYPESENSE-API-KEYheader value does not match theapi-keyin the ini file. Check for trailing whitespace or copy-paste encoding issues. - Collection creation fails with type error: Field types are strict. Sending a float value for an
int32field causes a rejection. Validate your JSON schema against the Typesense type table before indexing. - Slow queries on large collections: Ensure the fields you search are listed in
query_byand that numeric sort fields have"sort": truein the schema. Adding"index": falseto fields you never search on reduces memory usage. - Binary fallback: service user missing: Create a dedicated user before starting:
sudo useradd --system --no-create-home typesense.
Frequently asked questions
- Does Typesense persist data across restarts?
- Yes. Typesense stores all indexed data on disk in the configured data-dir. As long as that directory is intact, data survives service restarts and reboots.
- Can I run Typesense on a low-memory VPS?
- Typesense is designed to be memory-efficient. A 1 GB RAM VPS is workable for small to medium collections. Mark fields you never search with "index": false to reduce the in-memory index footprint.
- How do I create scoped API keys for read-only clients?
- Generate a scoped search-only key via the /keys endpoint. These keys can be locked to specific collections and actions, so you can safely expose them in client-side JavaScript without granting write access.
- Is it possible to update a document after indexing?
- Yes. Send a PATCH request to /collections/{name}/documents/{id} with only the fields you want to change, or use PUT to replace the entire document. The id field must match an existing document.
- How do I upgrade Typesense to a newer version?
- If installed from the repo, run apt upgrade typesense or dnf upgrade typesense and then systemctl restart typesense-server. Always check the release notes for breaking schema or API changes before upgrading major versions.
Related guides
Configure Prometheus Alertmanager
Configure Prometheus Alertmanager with routing trees, receivers, inhibition rules, grouping, Go templates, and PagerDuty/Slack on-call integrations.
Build an Intranet Server on Linux
Set up a complete small-office intranet on one Linux box: Nginx web server, dnsmasq local DNS, Samba file sharing, and a Wiki.js team wiki.
Build an nftables Firewall Script
Build a complete nftables firewall from scratch: tables, chains, sets, default-deny input policy, service allowlisting, and persistent systemd configuration.
Caddy as a Reverse Proxy
Set up Caddy as a reverse proxy with automatic HTTPS, load balancing, WebSocket passthrough, reusable snippets, and header control — no certbot required.