$linuxjunkies
>

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.

BeginnerUbuntuDebianFedoraArch8 min readUpdated June 7, 2026

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).

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"

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 50 and look for permission errors on the data directory or a port conflict on 8108. Confirm the data directory is owned by the typesense user.
  • 401 Unauthorized from the API: The X-TYPESENSE-API-KEY header value does not match the api-key in 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 int32 field 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_by and that numeric sort fields have "sort": true in the schema. Adding "index": false to 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.
tested on:Ubuntu 24.04Debian 12Fedora 40Arch rolling

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