← All playbooks
Hosted search migration

Meilisearch → Elastic Cloud

Move a Meilisearch index to Elastic Cloud when you need mappings, bulk updates, or aggregations Meilisearch is not covering. Define the mapping first. A 2023 report of indexing lag is a workload to retest, not a current benchmark.

Typical timeline12–28 business days40–90 hours active work
Statusneeds review
Source profileMeilisearch primary key docs reviewed 2026-11-01
Destination profileElasticsearch bulk API docs reviewed 2026-11-01
Documentation date
Review window
Evidence6 sources
This route needs review.Use it as a planning baseline, then verify the dated sources and test with representative data before production.
Before you migrate

Should you make this move?

Both platforms have a case. Compare what you gain with what you give up before scheduling the cutover.

Current platform

Meilisearch

Reasons to stay
  • Open-source typo-tolerant search with a small API and an optional managed cloud
  • Managed indexing, relevance, filtering, and globally available query APIs reduce search operations
Reasons to leave
  • Primary keys, ranking rules, and heavy update workloads need explicit setup that a hosted index used to hide
  • Ranking behavior, analyzers, schemas, and learned signals require careful revalidation after migration
New platform

Elastic Cloud

What gets better
  • Managed Elasticsearch delivers powerful full-text, vector, analytics, and observability capabilities at scale
  • Managed indexing, relevance, filtering, and globally available query APIs reduce search operations
What gets worse
  • Mappings, analyzers, cluster sizing, upgrades, and query complexity require search expertise
  • Ranking behavior, analyzers, schemas, and learned signals require careful revalidation after migration
Best of the move

Elastic Cloud: Managed Elasticsearch delivers powerful full-text, vector, analytics, and observability capabilities at scale. This removes a major source-side concern: Primary keys, ranking rules, and heavy update workloads need explicit setup that a hosted index used to hide.

Worst of the move

What you lose: Open-source typo-tolerant search with a small API and an optional managed cloud. What you inherit: Mappings, analyzers, cluster sizing, upgrades, and query complexity require search expertise.

Jump to a section
01At a glance

Know the shape of the move.

Transfer outcome12 features audited
Transfer outcome distributionClean transfer: 0, Partial transfer: 5, Manual rebuild: 7, Not transferred: 0.
Clean0
Partial5
Manual7
Lost0
Mapping route10 of 10 fields have a destination path

This timeline assumes

  • Elastic Cloud is the managed Elasticsearch cluster. schappim's 2023 note says Elastic, not a named Cloud region.
  • The site already documents Algolia → Elastic Cloud and Meilisearch → Typesense Cloud.
  • You can create an index with an explicit mapping before the first bulk load.
  • The database or the Meilisearch index is identified as the source of truth before you copy anything.
  • Meilisearch stays up until Elastic Cloud has served a representative update day.
02What transfers

What survives the move.

“Partial” and “manual” are not footnotes. They are work that must be scheduled and verified.

ItemOutcomeImpactWhat happensMitigation
DocumentspartialcriticalElasticsearch's bulk API indexes batches of action-and-document lines. Meilisearch documents become _source documents. Nothing in a settings export creates the Elasticsearch index for you.Bulk load into an empty index and compare counts after the cluster reports the bulk as done.
IdspartialcriticalMeilisearch ids are integers or strings limited to letters, digits, hyphens, and underscores. Use that value as Elasticsearch _id so a rerun overwrites instead of duplicating.Set _id from the primary key on every bulk line.
MappingsmanualcriticalMeilisearch will index a new field it has not seen before. Elasticsearch dynamic mapping can guess a type you did not want, and a later conflict rejects the document.Put the mapping in the index template before the first document. Turn dynamic mapping off if you want rejects instead of guesses.
FilterspartialhighMeilisearch filter expressions become Elasticsearch filters in the query DSL. The syntax is not a rename.Rewrite each production filter and run it against a known document.
RankingmanualcriticalMeilisearch rankingRules do not become a BM25 query. Meilisearch's own comparison says Elasticsearch relevancy takes analyzers, mappings, and fuzziness, and their product is aimed at less of that setup.Build the query you mean. Compare it with Meilisearch on a saved list before cutover.
Typo tolerancemanualhighMeilisearch applies typo tolerance unless you disable it. Elasticsearch needs a fuzzy query or an equivalent. The default match query will not behave the same.Decide which fields are fuzzy. Test a one-character typo on each.
AggregationspartialhighThis is a common reason to leave. On 11 October 2025, dewey wrote on Hacker News that a Rails app moved from Meilisearch to Elastic for more complex aggregation queries. Facets you had in Meilisearch still need an aggregation that matches the mapping.List the facet queries. Write the aggregation and compare bucket counts.
Update throughputmanualhighOn 8 February 2023, schappim wrote that about 50,000 constantly changing ecommerce records fell hours behind in Meilisearch, so that part of the app moved to Elastic. Kerollmops replied that indexing had improved and asked which version they ran. Measure your version. Do not treat 2023 lag as today's number.Replay a day of updates against the Meilisearch version you run, and against Elastic Cloud, before you commit.
Stop words and synonymsmanualmediumMeilisearch stop words and synonyms are index settings. Elasticsearch uses analyzers and synonym token filters, which belong in the mapping.Translate them into the analyzer. Reindex if you change that analyzer later.
Client librariesmanualmediumschappim also wrote that Meilisearch Rails gems lagged the server. An Elastic client is a separate dependency with its own version pin.Pin the Elasticsearch client to the Cloud version you deploy.
GeopartialmediumA Meilisearch _geo field becomes a geo_point mapping. Queries change from _geoRadius filters to geo queries.Map the field as geo_point before load. A wrong first mapping means a reindex.
OperationsmanualhighMeilisearch's comparison says Elasticsearch clusters involve shards, replicas, and heap sizing, and that this is a reason some teams leave. Elastic Cloud manages the machines and still leaves index design to you.Set shard and replica counts with the data size you measured, then load.
03Field and feature mapping

Where each thing goes.

SourceDestinationMethodNotes
IndexElasticsearch index or aliasmanualCreate the mapping first.
Primary key_idtransformSo a rerun overwrites.
Document fieldMapped propertytransformType it. Do not trust dynamic mapping for production.
Filter expressionQuery DSL filtermanualRewrite. Do not string-replace.
Ranking ruleQuery and field boostsmanualBM25 is not rankingRules.
Typo toleranceFuzzy querymanualOnly on the fields you choose.
FacetAggregationmanualBucket counts need a check.
SynonymSynonym token filtermanualLives in the analyzer. Reindex to apply.
Stop wordStop filtermanualSame analyzer constraint.
_geogeo_pointtransformMap it before the first bulk.
04Before you begin

Make the move recoverable.

Backup procedure

Create the source-of-truth backup

Keep Meilisearch and a mapping file that can recreate the Elastic Cloud index.

  1. Record document counts and the primary key.
  2. Export Meilisearch settings, stop words, and synonyms.
  3. Commit the Elasticsearch mapping and index template.
  4. Snapshot the source database if that is the system of record.
  5. Leave Meilisearch serving until the observation window ends.

Proof to capture: A count, a mapping file, and a Meilisearch host you can still query.

Transformation · Index template

Mapping template

Stop dynamic mapping from guessing types.

  1. Declare types for every field you filter or aggregate.
  2. Set dynamic to strict if unknown fields should fail.
  3. Create the index before the bulk load.

Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.

Transformation · Elasticsearch _bulk

Bulk load

Copy documents with stable ids.

  1. Write action lines with _id set to the Meilisearch primary key.
  2. Send batches the cluster can accept.
  3. Read the bulk response. A 200 can still contain item errors.

Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.

05Handle with care

The things most likely to hurt.

These are operating limits. Treat every “Stop if” condition as a blocked migration, not a suggestion.

Pilot

Dynamic mapping guesses a type

criticalpossible likelihood

The first documents teach Elasticsearch a type, and later documents conflict.

Consequence
Those documents are rejected and the index looks complete.
Mitigation
Use an explicit mapping and read every bulk item error.

Stop if: The bulk response contains mapping errors.

Planning

The 2023 lag story is treated as current

mediumpossible likelihood

A team chooses Elastic Cloud only because of schappim's February 2023 comment.

Consequence
You take on cluster operations you may not need on today's Meilisearch.
Mitigation
Replay your updates on the version you run.

Stop if: Nobody has measured the current task queue.

Cutover

Queries move with the client unchanged

criticallikely likelihood

The app still sends Meilisearch filter syntax.

Consequence
Searches fail or return the wrong set.
Mitigation
Rewrite filters and fuzzy behavior in the same deploy as the client.

Stop if: A production filter has no Elasticsearch equivalent in the branch.

06Precise timeline

Do the work in this order.

Estimate forOne Meilisearch index moving to an Elastic Cloud deployment with an explicit mapping
Total elapsed12–28 business days
Active work40–90 hours
BufferAdd time for aggregations, synonym analyzers, or a full reindex after a mapping change.
01
Days 1–4Queries and types2–4 days
02
Days 4–7Counts and settings1–3 days
03
Days 7–16Load and compare6–10 days
04
Days 16–22Switch writes and reads2–4 days
05
Days 20–28Update day4–8 days
  1. Days 1–4 · inventory

    Queries and types

    8–14 hours active2–4 days elapsedSearch review waiting
    • List fields, filters, fuzzy fields, and aggregations.
    • Decide whether the database or Meilisearch is the source of truth.

    Depends on: Meilisearch admin and an Elastic Cloud deployment

    Stop / go checkpoint

    Write the mapping?

    Go when: Every production field has a type.

    Stop when: An aggregation has no source field.

  2. Days 4–7 · backup

    Counts and settings

    3–6 hours active1–3 days elapsedSnapshot waiting
    • Record counts.
    • Export synonyms and stop words.

    Depends on: Field list

    Stop / go checkpoint

    Bulk load?

    Go when: The mapping file is committed.

    Stop when: The mapping is still being edited on the cluster by hand.

  3. Days 7–16 · pilot

    Load and compare

    16–40 hours active6–10 days elapsedQuery review waiting
    • Bulk load into the empty index.
    • Rewrite a sample of filters, fuzzy queries, and aggregations.

    Depends on: Mapping

    Stop / go checkpoint

    Shadow?

    Go when: Counts match and item errors are zero.

    Stop when: A mapping conflict appears.

  4. Days 16–22 · cutover

    Switch writes and reads

    6–14 hours active2–4 days elapsedDeploy waiting
    • Point updates at Elastic Cloud.
    • Switch reads after the alias is caught up.

    Depends on: Clean pilot

    Stop / go checkpoint

    Stop Meilisearch writes?

    Go when: Reads and writes use Elastic Cloud.

    Stop when: A client still sends Meilisearch syntax.

  5. Days 20–28 · observe

    Update day

    6–12 hours active4–8 days elapsedA busy update day waiting
    • Watch bulk rejections and search errors.
    • Keep Meilisearch queryable.

    Depends on: Cutover

    Stop / go checkpoint

    Close rollback?

    Go when: Updates and the signed queries hold.

    Stop when: Item errors or empty aggregations return.

07The point of change

Cut over with a way back.

Go live

Cutover

Read and write search on Elastic Cloud with stable _ids and a reviewed query set.

Recommended window: After the pilot query review, with someone who can read a bulk response.

  1. Bulk load the delta with the same _ids.
  2. Point the update job at the cluster.
  3. Switch the application query path.
  4. Run the signed filters and one typo query.
  5. Leave Meilisearch in place.

Proof to capture: The app queries Elastic Cloud. Bulk item errors on the delta are zero. Meilisearch is not receiving new writes.

Return to safety

Rollback

Point reads and writes back at Meilisearch.

Deadline: Before you delete the Meilisearch data or the Cloud deployment you might still need for comparison.

  1. Deploy the Meilisearch client.
  2. Point the update job back.
  3. Confirm a search and an update.
  4. Keep the Elastic Cloud index for the retry.
  5. Save the bulk error file if one caused the rollback.

Proof to capture: Meilisearch serves production search again.

Rollback immediately when
  • Mapping conflicts in the bulk response
  • Counts do not match
  • A production filter has no DSL equivalent
  • Aggregation buckets disagree
  • Updates reject after cutover
08Verification report

Prove the migration worked.

Every blocking check must pass. Capture the evidence before cleanup begins.

0%
Interactive report preview0 / 8 checks passed
PassIDCheckMethodExpected resultEvidence
V-01BlockingExplicit typesRead the index mapping and compare it with the template.Production fields match the template. Dynamic surprises are absent.Mapping JSON.
V-02BlockingItem errorsScan the bulk response for errors.Zero item errors.Bulk log.
V-03BlockingDocument countCompare _count with Meilisearch after refresh.Counts match.Count sheet.
V-04Blocking_id stabilityReindex one known document and GET it by the Meilisearch id.One document, updated in place.GET response.
V-05BlockingRewritten filtersRun each signed filter.The same documents come back, or the difference is signed.Filter diff.
V-06BlockingFuzzy fieldsSearch a one-character typo on each fuzzy field.The intended document is returned where you enabled fuzziness.Typo sample.
V-07BlockingBucket countsCompare facet buckets with Meilisearch.Buckets match or the gap is explained.Aggregation diff.
V-08BlockingA busy batchReplay a production-sized update batch.Bulk succeeds and search reflects the new documents.Update log.
09Post-migration cleanup

Remove the scaffolding safely.

Safe after: One busy update day on Elastic Cloud, with Meilisearch still queryable.

  1. Commit the index template.
  2. Archive bulk logs and the query diff.
  3. Rotate the Meilisearch key used for the export.
  4. Keep Meilisearch until rollback closes.
  5. Remove the old client dependency in a later deploy.
  6. Review shard sizing after real volume.
10Experiences from the field

When the plan met reality.

First-hand accounts are preferred. Vendor case studies are labeled, and every note below is an editorial paraphrase—follow the link for the full context.

First-person accountschappim · Hacker News

A fast catalog left Meilisearch for Elastic after indexing fell hours behind2023

On 8 February 2023, schappim wrote that Meilisearch worked for records that rarely change, and fell hours behind on a fast ecommerce catalog of about 50,000 constantly changing records. That part of the app moved to Elastic. He also hit a stretch where the Rails gem did not match the server. Kerollmops from Meilisearch replied the same day that indexing had improved with auto-batching, and asked which version was in use. The comment says Elastic, not Elastic Cloud, and it does not name a cluster size.

What they recommend
  • Replay a production-sized update batch and measure lag before you trust a quiet docs index as your model.
  • Treat the hours of lag as that 2023 install. Kerollmops said indexing had changed and asked for the version.
Worth noticing
  • The split he describes is Meilisearch for quieter data and Elastic for the catalog that changes all day.
  • A gem and server mismatch was a second problem, separate from raw indexing speed.
First-person accountdewey · Hacker News

A Rails app left Meilisearch for Elastic aggregations2025

On 11 October 2025, dewey commented on a Typesense thread that a Rails app had gone from Meilisearch, which he calls great, to Elastic for more complex aggregation queries. He was about to try Typesense for instant-search behavior. The comment is one sentence. It does not include an index size, a mapping, or a statement that the cluster was Elastic Cloud.

What they recommend
  • If aggregations are the reason you are leaving, test those queries on Elastic before you shut Meilisearch off.
  • Keep this comment in its lane. It is a reason, not a migration write-up with counts or a cutover.
Worth noticing
  • Aggregations are the gap he names between Meilisearch and Elastic.
  • He was already looking at Typesense next, so Elastic is not presented as a final home.
Sources and evidence

Verify against the primary material.

Platform behavior changes. Check these sources and the review dates above before executing a production migration.

  1. Elasticsearch: bulk APIAccessed 2026-11-01
  2. Elasticsearch: mappingAccessed 2026-11-01
  3. Meilisearch: primary keyAccessed 2026-11-01
  4. Meilisearch: comparison with ElasticsearchAccessed 2026-11-01
  5. Hacker News: Meilisearch 1.0 indexing threadAccessed 2026-11-01
  6. Hacker News: Meilisearch to Elastic for aggregationsAccessed 2026-11-01