We Switched to Typesense

When we first built 3DSEARCH, we relied on MariaDB FULLTEXT indexes to power our search. With hundreds of thousands of models, it worked — until it didn't. CPU usage hit 380%, response times climbed above 500ms, and the experience suffered. That's when we moved to Meilisearch, which served us well for over a year. But as our index grew past 4.8 million models, we started hitting limitations. Today, we're excited to announce that 3DSEARCH now runs on Typesense.

Why We Left Meilisearch

Meilisearch was a great starting point. It brought response times down from 200–500ms to under 20ms and gave us typo tolerance, stop words, and synonym support out of the box. But as we scaled, a few issues became harder to ignore:

Memory consumption: Our Meilisearch instance was consuming up to 12GB of RAM for 4.8M documents. On a dedicated server with 32GB total, that left little room for our scrapers, database, and other services. We even had to increase swap from 0 to 8GB at one point — and it filled up completely.

Indexing speed: Re-indexing the full dataset or syncing large batches of updates was slow. Our sync cron jobs had to be carefully managed with flock to avoid overlap, and full re-indexes could take hours.

Limited filtering and sorting flexibility: We had to implement workarounds like restricting attributesToSearchOn to name-only when a sort was active to prevent tag-spam from polluting results. Combining search queries with multi-field sorting was often unintuitive.

No built-in analytics: Understanding what users searched for and which queries returned poor results required building a completely separate tracking system.

Why Typesense

Typesense is an open-source search engine built in C++ with a focus on performance and developer experience. After evaluating several alternatives — including Elasticsearch, OpenSearch, and Zinc — we chose Typesense for several reasons:

Lower memory footprint: Typesense uses significantly less RAM for the same dataset. Our 4.8M model index now runs comfortably without pushing our server to its limits.

Faster response times: Average search latency dropped from ~20ms to around 5–8ms. For a search engine that processes thousands of queries daily, every millisecond matters.

Better relevance tuning: Typesense gives us more fine-grained control over ranking, including field-level weighting, pinning, and custom scoring functions. This means searches for "benchy" now consistently return the classic 3DBenchy calibration model at the top — not random models that happen to include "benchy" in their tags.

Built-in geo search and faceting: While we don't use geo search today, the faceted filtering support has already improved our category and source filtering, making it snappier and more reliable.

Scoped API keys: Typesense natively supports scoped, rate-limited API keys — useful for securing our various endpoints (main site, app API, autocomplete) without a proxy layer.

The Migration

Migrating 4.8 million documents from Meilisearch to Typesense was a multi-step process:

1. Schema definition: Unlike Meilisearch's schema-less approach, Typesense requires a defined collection schema. We mapped our existing fields — name, designer, source, category, tags, likes, downloads, makes, published date — to typed fields with appropriate indexing options.

2. Batch import: We wrote a PHP sync script that reads from our MariaDB database and pushes documents to Typesense in batches of 1,000. The full initial import of 4.8M models completed in under 40 minutes.

3. Search wrapper update: Our meilisearch_search.php was replaced with a new typesense_search.php that translates our existing query parameters (sort, source filter, category filter) into Typesense's search API format.

4. Autocomplete migration: The autocomplete endpoint was updated to use Typesense's prefix search, which returns suggestions even faster than before.

5. Synonym and stop word migration: We ported our 16 English stop words and 11 synonym groups (e.g., "pla" ↔ "filament", "stl" ↔ "3d model") to Typesense's synonym API.

6. Testing and cutover: We ran both engines in parallel on our test environment for a week, comparing result quality and latency before switching production traffic.

Results

After two weeks in production, here's what we're seeing:

Search latency: Down from ~20ms to ~5–8ms average. P99 latency dropped even more dramatically.

Memory usage: Reduced by roughly 40%. The server is breathing again, and we've been able to reclaim swap entirely.

Relevance: Subjectively better. Exact name matches now consistently rank above tag-only matches. We've received positive feedback from users who noticed the improvement without knowing we changed anything.

Indexing: Incremental sync is near-instant. Our cron job that pushes new and updated models from MariaDB to Typesense runs every 5 minutes and typically completes in under 10 seconds.

What's Next

With Typesense in place, we're now exploring features that weren't practical before:

Semantic search: Typesense has built-in vector search support. We're evaluating embedding models to enable "search by meaning" — so a query like "phone holder for car" also finds models tagged as "smartphone mount" or "mobile clip".

Search analytics: Using Typesense's analytics features to identify popular queries, zero-result searches, and trending terms — feeding this data back into our trending section and helping us improve result quality.

Federated search: Querying across multiple collections (models, blog posts, community feed) in a single request for a unified search experience.

If you're running a search-heavy application and considering alternatives to Meilisearch or Elasticsearch, we'd highly recommend giving Typesense a look. It's been a significant upgrade for us — and for the nearly 5 million models our users search through every day.

Happy searching!
— The 3DSEARCH Team