Search Module Providers

In this guide, you'll learn about Search Module Providers in Medusa, including how to register them and choose which one holds each index.

Easier setup with Cloud: Cloud provides pre-configured search infrastructure for your Medusa application. You can use it to set up without configuring and managing your own search engine. Learn more in the Medusa Search documentation.

What is a Search Module Provider?#

A Search Module Provider implements the logic of talking to a search engine, including creating indexes, writing documents, and running queries. The Search Module then uses the registered providers to serve every index.

A provider holds the integration logic only. It never decides when a document changes or when an index is filled, as the Search Module drives all of that and calls the provider to carry it out.

The provider is responsible for

The Search Module is responsible for

Creating and migrating the physical indexes in the search engine.

Reading your index definitions and deciding which indexes exist and when they change.

Writing and deleting the documents the module hands it.

Filling an index by running the definition's seed function, then batching the results into provider writes.

Translating a search query into the engine's own query language.

Subscribing to events and routing each one to the definitions that declared it, so indexes stay current.

Reporting whether a write finished, which lets the module wait on engines that apply writes asynchronously.

Versioning an index, rebuilding it when its definition changes, and running the catch-up pass that follows a full run.

Available Search Module Providers#

Medusa provides the following Search Module Providers:

PostgreSQL
Medusa Search
Cloud
Note: Refer to the Compare Search Providers guide for a detailed comparison of the features and capabilities of each provider.

Custom Search Module Providers#

You can also create a custom provider to integrate a search engine that Medusa doesn't support out of the box. You only implement the methods that talk to that engine, as shown in the table above. Refer to the Create Search Module Provider guide for the methods to implement.


Register Multiple Providers#

The Search Module supports more than one provider at a time. Each index definition picks one through its provider property, so a high-traffic index can live on a dedicated engine while quieter indexes stay on PostgreSQL.

For example:

medusa-config.ts
1module.exports = defineConfig({2  // ...3  modules: [4    {5      resolve: "@medusajs/medusa/search",6      options: {7        default_provider: "search-postgres",8        providers: [9          {10            resolve: "@medusajs/medusa/search-postgres",11            id: "search-postgres",12            options: {13              language: "english",14            },15          },16          {17            resolve: "./src/modules/my-search-provider",18            id: "my-engine",19            options: {20              // provider options...21            },22          },23        ],24      },25    },26  ],27})
Note: Register each provider once. Two registrations of the same provider share one identifier, so an index definition couldn't tell them apart, and the module throws at startup.

Default Search Module Provider#

An index definition that names no provider uses the module's default provider. The Search Module resolves the default once when it initializes, so a misconfiguration fails at startup rather than on the first query.

Scenario

Default Provider

One provider is registered.

The registered provider.

Multiple providers are registered and the module has a default_provider option.

The provider whose identifier matches default_provider.

Multiple providers are registered and the module doesn't have a default_provider option.

The module throws at startup because it can't determine a default provider.

Multiple providers are registered and the module has a default_provider option that doesn't match any registered provider.

The module throws at startup because it can't determine a default provider.

Select a Provider by its Identifier#

Every provider declares its own identifier, such as search-postgres for the PostgreSQL provider and search-medusa for the Medusa Search provider. A custom provider declares one too, as a static identifier property on the service it exports:

src/modules/my-search-provider/service.ts
1import {2  AbstractSearchProviderService,3} from "@medusajs/framework/utils"4
5export class MySearchService6  extends AbstractSearchProviderService7{8  static identifier = "my-engine"9  // ...10}

An index definition then selects a provider by that identifier:

src/search/brand.ts
1export const brandIndex = defineSearchIndex({2  provider: "my-engine",3  // ...4})
Was this page helpful?
Ask Bloom
For assistance in your development, use Claude Code Plugins or Medusa MCP server in Cursor, VSCode, etc...FAQ
What is Medusa?
How can I create a module?
How can I create a data model?
How do I create a workflow?
How can I extend a data model in the Product Module?
Recipes
How do I build a marketplace with Medusa?
How do I build digital products with Medusa?
How do I build subscription-based purchases with Medusa?
What other recipes are available in the Medusa documentation?
Chat is cleared on refresh
Line break