Typesense
Fast and typo-tolerant open-source search engine. Supports instant search experience, geo-search, and faceted search. Lightweight alternative to Elasticsearch.
Server
Typesense
Overview
Typesense is a fast, developer-friendly open-source search engine built in C++. Featuring sub-millisecond search responses, excellent typo tolerance, and support for vector and hybrid search, it provides an intuitive API that's easy to set up. With its in-memory architecture enabling ultra-fast search and real-time index updates, it delivers exceptional user experiences.
Details
Typesense 2024 edition features vector search, hybrid search (vector + keyword), conversational search, multi-language typo tolerance, advanced filtering, geospatial search, and real-time analytics capabilities. Built with an optimized C++ architecture that significantly outperforms Elasticsearch and Solr in search performance, it provides intuitive REST APIs and GraphQL support for rapid implementation.
Key Features
- Ultra-Fast Search: Sub-millisecond search responses through in-memory architecture
- AI Capabilities: Vector search and hybrid search for semantic search functionality
- Powerful Typo Tolerance: Advanced spell correction and fuzzy matching
- Real-time Processing: Real-time indexing and query processing
- Multi-language Support: Comprehensive internationalization support and language-specific optimizations
- Geospatial Search: High-performance geo-search and location-based filtering
Pros and Cons
Pros
- Simple setup with intuitive APIs providing high development efficiency
- Dramatically faster search performance compared to Elasticsearch and Solr
- Cost reduction and technical freedom through open-source nature
- High performance with small footprint and low resource consumption
- Easy implementation of comprehensive search features (facets, filtering, sorting)
- Complete data control with self-hosted deployment options
Cons
- Increased memory usage due to in-memory architecture
- Limited distributed processing capabilities for large datasets compared to Elasticsearch
- Smaller plugin ecosystem compared to other mature search engines
- May underperform Elasticsearch in complex analytical queries
- Limited commercial support options
- Some enterprise-grade features may have constraints for large-scale deployments
Reference Pages
- Typesense Official Website
- Typesense Documentation
- Typesense GitHub Repository
- Typesense API Reference
Code Examples
Setup and Installation
# Docker execution
docker run -p 8108:8108 -v /tmp/typesense-data:/data typesense/typesense:0.25.2 \
--data-dir /data --api-key=xyz --enable-cors
# macOS installation (Homebrew)
brew install typesense-server
# Linux binary installation
wget https://dl.typesense.org/releases/0.25.2/typesense-server-0.25.2-linux-amd64.tar.gz
tar -xzf typesense-server-0.25.2-linux-amd64.tar.gz
cd typesense-server-0.25.2-linux-amd64
# Server startup
./typesense-server --data-dir=/tmp/typesense-data --api-key=xyz --enable-cors
# Docker Compose configuration
cat > docker-compose.yml << 'EOF'
version: '3.8'
services:
typesense:
image: typesense/typesense:0.25.2
ports:
- "8108:8108"
volumes:
- ./typesense-data:/data
command: '--data-dir /data --api-key=your-api-key --enable-cors'
environment:
- TYPESENSE_API_KEY=your-secure-api-key
- TYPESENSE_DATA_DIR=/data
restart: unless-stopped
EOF
docker-compose up -d
# Kubernetes deployment
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: typesense
spec:
replicas: 3
selector:
matchLabels:
app: typesense
template:
metadata:
labels:
app: typesense
spec:
containers:
- name: typesense
image: typesense/typesense:0.25.2
ports:
- containerPort: 8108
env:
- name: TYPESENSE_API_KEY
valueFrom:
secretKeyRef:
name: typesense-secret
key: api-key
args:
- --data-dir=/data
- --api-key=$(TYPESENSE_API_KEY)
- --enable-cors
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: typesense-pvc
EOF
Collection Creation and Document Management
# Create collection schema
curl -X POST "http://localhost:8108/collections" \
-H "X-TYPESENSE-API-KEY: xyz" \
-H "Content-Type: application/json" \
-d '{
"name": "movies",
"fields": [
{"name": "id", "type": "string"},
{"name": "title", "type": "string"},
{"name": "overview", "type": "string"},
{"name": "genre", "type": "string[]"},
{"name": "release_date", "type": "int64"},
{"name": "rating", "type": "float"},
{"name": "director", "type": "string"},
{"name": "duration", "type": "int32"},
{"name": "location", "type": "geopoint"},
{"name": "embedding", "type": "float[]", "num_dim": 384}
],
"default_sorting_field": "rating"
}'
# Add single document
curl -X POST "http://localhost:8108/collections/movies/documents" \
-H "X-TYPESENSE-API-KEY: xyz" \
-H "Content-Type: application/json" \
-d '{
"id": "1",
"title": "The Shawshank Redemption",
"overview": "Two imprisoned men bond over a number of years",
"genre": ["Drama", "Crime"],
"release_date": 748569600,
"rating": 9.3,
"director": "Frank Darabont",
"duration": 142,
"location": [41.1179, -81.6804]
}'
# Bulk import multiple documents (JSONL format)
curl -X POST "http://localhost:8108/collections/movies/documents/import" \
-H "X-TYPESENSE-API-KEY: xyz" \
-H "Content-Type: application/octet-stream" \
--data-binary @- << 'EOF'
{"id": "2", "title": "The Godfather", "overview": "The aging patriarch of an organized crime dynasty", "genre": ["Drama", "Crime"], "release_date": 69379200, "rating": 9.2, "director": "Francis Ford Coppola", "duration": 175}
{"id": "3", "title": "The Dark Knight", "overview": "Batman begins his war on crime", "genre": ["Action", "Crime", "Drama"], "release_date": 1216339200, "rating": 9.0, "director": "Christopher Nolan", "duration": 152}
{"id": "4", "title": "Pulp Fiction", "overview": "The lives of two mob hitmen intertwine", "genre": ["Crime", "Drama"], "release_date": 782092800, "rating": 8.9, "director": "Quentin Tarantino", "duration": 154}
EOF
# Update document
curl -X PATCH "http://localhost:8108/collections/movies/documents/1" \
-H "X-TYPESENSE-API-KEY: xyz" \
-H "Content-Type: application/json" \
-d '{
"rating": 9.4,
"updated_at": 1705392000
}'
# Delete document
curl -X DELETE "http://localhost:8108/collections/movies/documents/1" \
-H "X-TYPESENSE-API-KEY: xyz"
# Get document
curl -X GET "http://localhost:8108/collections/movies/documents/1" \
-H "X-TYPESENSE-API-KEY: xyz"
Search Query Implementation
# Basic search
curl -X GET \
"http://localhost:8108/collections/movies/documents/search?q=shawshank&query_by=title,overview" \
-H "X-TYPESENSE-API-KEY: xyz"
# Advanced search options
curl -X GET \
"http://localhost:8108/collections/movies/documents/search" \
-H "X-TYPESENSE-API-KEY: xyz" \
-G \
-d "q=crime drama" \
-d "query_by=title,overview,director" \
-d "filter_by=rating:>=8.0 && genre:Crime" \
-d "sort_by=rating:desc,release_date:desc" \
-d "facet_by=genre,director" \
-d "max_facet_values=10" \
-d "per_page=20" \
-d "page=1" \
-d "highlight_full_fields=title,overview" \
-d "snippet_threshold=15" \
-d "typo_tokens_threshold=1" \
-d "drop_tokens_threshold=2"
# Faceted search
curl -X GET \
"http://localhost:8108/collections/movies/documents/search" \
-H "X-TYPESENSE-API-KEY: xyz" \
-G \
-d "q=*" \
-d "query_by=title" \
-d "facet_by=genre,director,release_date" \
-d "max_facet_values=20" \
-d "facet_query=genre:Drama"
# Geospatial search
curl -X GET \
"http://localhost:8108/collections/theaters/documents/search" \
-H "X-TYPESENSE-API-KEY: xyz" \
-G \
-d "q=cinema" \
-d "query_by=name,description" \
-d "filter_by=location:(40.7589, -73.9851, 5 km)" \
-d "sort_by=location(40.7589, -73.9851):asc"
# Multi-search
curl -X POST "http://localhost:8108/multi_search" \
-H "X-TYPESENSE-API-KEY: xyz" \
-H "Content-Type: application/json" \
-d '{
"searches": [
{
"collection": "movies",
"q": "action",
"query_by": "title,overview",
"filter_by": "rating:>=8.0"
},
{
"collection": "books",
"q": "science fiction",
"query_by": "title,description"
}
]
}'
# Fuzzy search (typo tolerance)
curl -X GET \
"http://localhost:8108/collections/movies/documents/search" \
-H "X-TYPESENSE-API-KEY: xyz" \
-G \
-d "q=shawshenk redemtion" \
-d "query_by=title,overview" \
-d "typo_tokens_threshold=1" \
-d "num_typos=2" \
-d "min_len_1typo=4" \
-d "min_len_2typo=7"
Vector Search and AI Features
# Create collection for vector search
curl -X POST "http://localhost:8108/collections" \
-H "X-TYPESENSE-API-KEY: xyz" \
-H "Content-Type: application/json" \
-d '{
"name": "documents",
"fields": [
{"name": "id", "type": "string"},
{"name": "title", "type": "string"},
{"name": "content", "type": "string"},
{"name": "embedding", "type": "float[]", "num_dim": 384}
]
}'
# Execute vector search
curl -X GET \
"http://localhost:8108/collections/documents/documents/search" \
-H "X-TYPESENSE-API-KEY: xyz" \
-G \
-d "q=*" \
-d "vector_query=embedding:([0.1, 0.2, 0.3, ...], k:10)" \
-d "per_page=10"
# Hybrid search (text + vector)
curl -X GET \
"http://localhost:8108/collections/documents/documents/search" \
-H "X-TYPESENSE-API-KEY: xyz" \
-G \
-d "q=artificial intelligence" \
-d "query_by=title,content" \
-d "vector_query=embedding:([0.15, 0.25, 0.35, ...], k:10)" \
-d "rank_tokens_by=default_score" \
-d "per_page=10"
# Semantic search configuration
curl -X POST "http://localhost:8108/collections" \
-H "X-TYPESENSE-API-KEY: xyz" \
-H "Content-Type: application/json" \
-d '{
"name": "semantic_search",
"fields": [
{"name": "id", "type": "string"},
{"name": "title", "type": "string"},
{"name": "content", "type": "string"},
{"name": "embedding", "type": "float[]", "num_dim": 768, "embed": {"from": ["title", "content"], "model_config": {"model_name": "ts/all-MiniLM-L12-v2"}}}
]
}'
# Search with automatic embeddings
curl -X GET \
"http://localhost:8108/collections/semantic_search/documents/search" \
-H "X-TYPESENSE-API-KEY: xyz" \
-G \
-d "q=machine learning applications" \
-d "query_by=embedding" \
-d "per_page=10"
Performance Optimization
# Check collection statistics
curl -X GET "http://localhost:8108/collections/movies" \
-H "X-TYPESENSE-API-KEY: xyz"
# Monitor search performance
curl -X GET "http://localhost:8108/stats.json" \
-H "X-TYPESENSE-API-KEY: xyz"
# Check memory usage
curl -X GET "http://localhost:8108/debug" \
-H "X-TYPESENSE-API-KEY: xyz"
# Configuration optimization (server startup)
./typesense-server \
--data-dir=/data \
--api-key=xyz \
--enable-cors \
--num-memory-shards=4 \
--search-only-mode=false \
--healthy-read-lag=1000 \
--healthy-write-lag=1000 \
--log-level=INFO \
--max-memory-ratio=0.8
# Cache configuration
curl -X POST "http://localhost:8108/collections/movies/documents/search" \
-H "X-TYPESENSE-API-KEY: xyz" \
-H "Content-Type: application/json" \
-d '{
"q": "action",
"query_by": "title,overview",
"cache_ttl": 300
}'
# Index optimization
curl -X POST "http://localhost:8108/collections/movies/compact" \
-H "X-TYPESENSE-API-KEY: xyz"
SDK and Framework Integration
// JavaScript/Node.js SDK
import { Client as TypesenseClient } from 'typesense'
const client = new TypesenseClient({
'nodes': [{
'host': 'localhost',
'port': '8108',
'protocol': 'http'
}],
'apiKey': 'xyz',
'connectionTimeoutSeconds': 2
})
// Create collection
const moviesSchema = {
'name': 'movies',
'fields': [
{'name': 'id', 'type': 'string'},
{'name': 'title', 'type': 'string'},
{'name': 'overview', 'type': 'string'},
{'name': 'genre', 'type': 'string[]'},
{'name': 'rating', 'type': 'float'},
{'name': 'release_date', 'type': 'int64'}
],
'default_sorting_field': 'rating'
}
await client.collections().create(moviesSchema)
// Add documents
const documents = [
{
'id': '1',
'title': 'The Shawshank Redemption',
'overview': 'Two imprisoned men bond over a number of years',
'genre': ['Drama', 'Crime'],
'rating': 9.3,
'release_date': 748569600
}
]
await client.collections('movies').documents().import(documents)
// Execute search
const searchResults = await client
.collections('movies')
.documents()
.search({
'q': 'shawshank',
'query_by': 'title,overview',
'filter_by': 'rating:>=8.0',
'sort_by': 'rating:desc'
})
console.log(searchResults.hits)
// Real-time search (instant search)
const searchParams = {
'q': 'sha',
'query_by': 'title,overview',
'typo_tokens_threshold': 1,
'prefix': true,
'per_page': 5
}
const instantResults = await client
.collections('movies')
.documents()
.search(searchParams)
# Python SDK
import typesense
client = typesense.Client({
'nodes': [{
'host': 'localhost',
'port': '8108',
'protocol': 'http'
}],
'api_key': 'xyz',
'connection_timeout_seconds': 2
})
# Create collection
movies_schema = {
'name': 'movies',
'fields': [
{'name': 'id', 'type': 'string'},
{'name': 'title', 'type': 'string'},
{'name': 'overview', 'type': 'string'},
{'name': 'genre', 'type': 'string[]'},
{'name': 'rating', 'type': 'float'},
{'name': 'release_date', 'type': 'int64'}
],
'default_sorting_field': 'rating'
}
client.collections.create(movies_schema)
# Add documents
documents = [
{
'id': '1',
'title': 'The Shawshank Redemption',
'overview': 'Two imprisoned men bond over a number of years',
'genre': ['Drama', 'Crime'],
'rating': 9.3,
'release_date': 748569600
}
]
client.collections['movies'].documents.import_(documents)
# Execute search
search_results = client.collections['movies'].documents.search({
'q': 'shawshank',
'query_by': 'title,overview',
'filter_by': 'rating:>=8.0',
'sort_by': 'rating:desc'
})
print(search_results['hits'])
# Advanced search
advanced_search = client.collections['movies'].documents.search({
'q': 'crime',
'query_by': 'title,overview,director',
'filter_by': 'genre:Crime && rating:>=8.0',
'facet_by': 'genre,director',
'sort_by': 'rating:desc',
'typo_tokens_threshold': 1,
'prefix': True,
'per_page': 10
})
Advanced Configuration and Cluster Setup
# High availability setup (3-node cluster)
# Node 1
./typesense-server \
--data-dir=/data/node1 \
--api-key=xyz \
--peering-address=192.168.1.100 \
--peering-port=8107 \
--api-port=8108 \
--nodes=192.168.1.100:8107:8108,192.168.1.101:8107:8108,192.168.1.102:8107:8108
# Node 2
./typesense-server \
--data-dir=/data/node2 \
--api-key=xyz \
--peering-address=192.168.1.101 \
--peering-port=8107 \
--api-port=8108 \
--nodes=192.168.1.100:8107:8108,192.168.1.101:8107:8108,192.168.1.102:8107:8108
# Node 3
./typesense-server \
--data-dir=/data/node3 \
--api-key=xyz \
--peering-address=192.168.1.102 \
--peering-port=8107 \
--api-port=8108 \
--nodes=192.168.1.100:8107:8108,192.168.1.101:8107:8108,192.168.1.102:8107:8108
# Replication configuration
curl -X PATCH "http://localhost:8108/collections/movies" \
-H "X-TYPESENSE-API-KEY: xyz" \
-H "Content-Type: application/json" \
-d '{
"replication_factor": 3
}'
# Create backup
curl -X POST "http://localhost:8108/snapshots" \
-H "X-TYPESENSE-API-KEY: xyz" \
-d '{
"snapshot_path": "/backups/snapshot_$(date +%Y%m%d_%H%M%S)"
}'
# SSL/TLS configuration
./typesense-server \
--data-dir=/data \
--api-key=xyz \
--ssl-certificate=/path/to/certificate.pem \
--ssl-certificate-key=/path/to/private.key \
--enable-cors
# API rate limiting
curl -X POST "http://localhost:8108/collections/movies/documents/search" \
-H "X-TYPESENSE-API-KEY: xyz" \
-H "X-TYPESENSE-USER-ID: user123" \
-H "Content-Type: application/json" \
-d '{
"q": "search query",
"query_by": "title"
}'
# Health monitoring
curl -X GET "http://localhost:8108/health" \
-H "X-TYPESENSE-API-KEY: xyz"
# Metrics collection
curl -X GET "http://localhost:8108/metrics.json" \
-H "X-TYPESENSE-API-KEY: xyz"
Analytics and Monitoring
# Search analytics
curl -X GET "http://localhost:8108/analytics/events" \
-H "X-TYPESENSE-API-KEY: xyz" \
-G \
-d "type=search" \
-d "from=2024-01-01" \
-d "to=2024-01-31"
# Popular searches
curl -X GET "http://localhost:8108/analytics/rules" \
-H "X-TYPESENSE-API-KEY: xyz"
# Click analytics
curl -X POST "http://localhost:8108/analytics/events" \
-H "X-TYPESENSE-API-KEY: xyz" \
-H "Content-Type: application/json" \
-d '{
"type": "click",
"data": {
"q": "batman",
"collections": ["movies"],
"search_id": "search_123",
"user_id": "user_456",
"object_id": "movie_789",
"position": 1
}
}'
# Conversion tracking
curl -X POST "http://localhost:8108/analytics/events" \
-H "X-TYPESENSE-API-KEY: xyz" \
-H "Content-Type: application/json" \
-d '{
"type": "conversion",
"data": {
"search_id": "search_123",
"user_id": "user_456",
"object_id": "movie_789",
"conversion_type": "purchase"
}
}'
Typesense is a modern search engine that prioritizes ultra-fast performance and simplicity, delivering exceptional performance especially for real-time search and typo tolerance functionality. It offers an excellent choice for achieving high-performance search capabilities with low resource consumption while leveraging the benefits of open-source software.