Data

500 million records a day into OpenSearch, without losing any

Four months building the ingestion and search layer for a Magento 2 estate: Kinesis Firehose buffering, Lambda cleaning records in flight, OpenSearch with rotating indices and S3 lifecycle rules behind it.

Confidential, e-commerce4 months3 engineersUpdated August 18, 2026
500M+
records ingested daily
Sub-second
queries over billions of rows
60%
lower archive storage cost

A Magento 2 estate was producing more event and log data than its search layer could take. Queries that used to return instantly were timing out, and the ingestion path dropped records whenever a sale doubled traffic. The requirement was blunt: take everything, lose nothing, keep search under a second.

What was breaking

Applications wrote to the search cluster directly. That works until traffic spikes, at which point the cluster applies back-pressure, the application times out, and the record is gone. There was no buffer between producer and consumer, so the fastest producer set the pace for everyone.

The pipeline

  • Producers write to Kinesis Firehose, which absorbs bursts and hands downstream a rate it can cope with
  • Lambda transforms records in flight: normalising fields, dropping malformed entries into a separate stream rather than the main one, and enriching with the identifiers search needs
  • Firehose delivers to OpenSearch Service, and in parallel writes the raw batch to S3
  • Aurora holds the reference data the transform needs, cached in the Lambda execution environment

The parallel S3 write is what makes "lose nothing" true. If OpenSearch rejects a batch, the raw records are still in S3 and can be replayed. Without it, a rejected batch is a lost batch.

Keeping search fast

  • Time-based index rotation, so a query for last week touches last week's indices and not the entire history
  • Shard count sized against actual document counts rather than the default, which had produced thousands of tiny shards
  • Index State Management moving older indices to warm nodes and eventually out of the cluster
  • Field mappings defined explicitly instead of relying on dynamic mapping, which had been indexing fields nobody queried

The shard fix alone accounted for most of the query improvement. It usually does.

Storage

Batches land in S3 gzipped and partitioned by date. A lifecycle policy moves partitions past the hot window to infrequent access and then to Glacier tiers. The data stays queryable through Athena, which covers the occasional historical question without keeping years of records on search-cluster storage.

Where it landed

  • 500M+ records ingested per day with no dropped entries in the failure modes we can reproduce
  • Sub-second search over billions of documents
  • About 60% lower storage cost from compression and lifecycle tiering
  • Spikes now queue instead of failing, so a sale is a graph shape rather than an incident

What was hard

Mapping conflicts. Years of dynamic mapping had produced fields typed differently in different indices, and reindexing that history without a search outage took longer than building the pipeline did.

What we still do

Cluster sizing review each quarter, ingestion monitoring, and the alerting on Firehose delivery failures.

Project

Client

Confidential, e-commerce

Duration

4 months

Team

3 engineers

Category

Data

Amazon OpenSearch ServiceKinesis FirehoseAWS LambdaAmazon S3Amazon Aurora
Questions

Questions about this build

Anything missing, email [email protected].

Why Firehose instead of writing straight to OpenSearch?

Because traffic spikes. Firehose absorbs the burst, batches and compresses, and hands OpenSearch a rate it can index. A direct write path drops records the first time a sale doubles the traffic.

How do you keep OpenSearch queries fast as data grows?

Rotate indices on a schedule so a query touches the period it needs rather than the whole history, size shards against the actual document count instead of a default, and push anything past the retention window to S3.

Where did the 60% storage saving come from?

Gzip on the archived batches and an S3 lifecycle policy moving old partitions to Glacier tiers. The data is still there and still queryable through Athena; it just stopped being billed at hot-storage rates.

Can this run on OpenSearch Serverless?

For a new workload of this shape, it is worth pricing. On this one the estate already had provisioned domains with reserved capacity, so moving would have cost more than it saved for the term.

More work

Two others we can talk about

Kubernetes

EKS Cluster Setup for Enterprise Application

Complete Amazon EKS cluster setup with advanced networking, security, and monitoring for a large-scale enterprise application serving millions of users.

Read it
Migration

Moving an insurance ledger to AWS without stopping the business

Nine months moving core policy and transaction services off on-premises virtualisation into a multi-account AWS Organization, with Transit Gateway carrying traffic between 30+ VPCs and the remaining datacentre.

Read it

Send us your AWS bill

Thirty minutes with an engineer, no slide deck. We will tell you what we would change first and what it would cost to have us do it.

Talk to an engineer