Back to Blog
Blog/Engineering

Instant Search Results Under 50ms: Integrating Meilisearch in Next.js

How to implement typo-tolerant, ultra-fast search in web applications with PostgreSQL, Prisma, and Meilisearch.

Akram Hafaiedh
Akram Hafaiedh
Full Stack Developer
2026-01-153 min read
// SYSTEM ARCHITECTURE PATTERN
PRODUCTION VERIFIED
TECHNICAL CASE STUDY

Instant Search Results Under 50ms: Integrating Meilisearch in Next.js

LARAVELREDISMULTI-TENANT

Instant Search Results Under 50ms in Next.js

Modern web search expects instant feedback. Standard SQL LIKE queries degrade rapidly when filtering thousands of rows or when typos occur. Let's look at how to implement Meilisearch alongside Next.js and Prisma to search listings under 50ms.


Why Meilisearch?

Unlike Elasticsearch, which requires massive memory overhead and complex setups, Meilisearch is lightweight, typo-tolerant out of the box, and built for instant search-as-you-type interfaces.


1. Synchronizing Data with Prisma Middleware

Whenever a property listing is created or updated in PostgreSQL, we must synchronize it to our Meilisearch index. You can do this elegantly using Prisma middleware or DB events:

ts
class=class="text-emerald-500 dark:text-emerald-400 font-medium">"text-slate-500 italic">// lib/prisma.ts
import { PrismaClient } from '@prisma/client';
import { MeiliSearch } from 'meilisearch';

const prisma = new PrismaClient();
const searchClient = new MeiliSearch({ host: 'http:class=class="text-emerald-500 dark:text-emerald-400 font-medium">"text-slate-500 italic">//localhost:7700', apiKey: 'masterKey' });

prisma.$use(async (params, next) => {
  const result = await next(params);

  class=class="text-emerald-500 dark:text-emerald-400 font-medium">"text-slate-500 italic">// Sync to Meilisearch index on listing modifications
  if (params.model === 'Listing' && ['create', 'update'].includes(params.action)) {
    const searchIndex = searchClient.index('listings');
    await searchIndex.addDocuments([{
      id: result.id,
      title: result.title,
      description: result.description,
      price: result.price,
      city: result.city,
    }]);
  }

  return result;
});

2. Searching Index from Next.js Server Actions

Querying the search engine is incredibly straightforward and keeps your API response latency minimal.

ts
class=class="text-emerald-500 dark:text-emerald-400 font-medium">"text-slate-500 italic">// app/actions/search.ts
'use server';

import { MeiliSearch } from 'meilisearch';

const searchClient = new MeiliSearch({ host: 'http:class=class="text-emerald-500 dark:text-emerald-400 font-medium">"text-slate-500 italic">//localhost:7700', apiKey: 'masterKey' });

export async function searchListings(query: string) {
  try {
    const index = searchClient.index('listings');
    const searchResults = await index.search(query, {
      limit: 10,
      attributesToHighlight: ['title'],
    });

    return { success: true, hits: searchResults.hits };
  } catch (error) {
    console.error('Meilisearch search error:', error);
    return { success: false, hits: [] };
  }
}

By offloading searching search filters to a specialized search-index, your main database operations remain fast, and users get a lightning-fast responsive interface.

Engineering Collaboration

Building a High-Scale SaaS or Complex System?

Let’s discuss your architecture, full-stack development, or system modernization needs.

Related Articles

// SYSTEM ARCHITECTURE PATTERN
PRODUCTION VERIFIED
TECHNICAL CASE STUDY

Resolving Session Loss: State Persistence in Multi-Company SaaS Dashboards

LARAVELREDISMULTI-TENANT
Engineering
2026-02-22•Engineering

Resolving Session Loss: State Persistence in Multi-Company SaaS Dashboards

Read Article
// SYSTEM ARCHITECTURE PATTERN
PRODUCTION VERIFIED
TECHNICAL CASE STUDY

Hybrid Architecture: Embedding Vue 3 Datatables in a Laravel Blade Application

LARAVELREDISMULTI-TENANT
Engineering
2026-02-12•Engineering

Hybrid Architecture: Embedding Vue 3 Datatables in a Laravel Blade Application

Read Article