Your Indexing Pipeline Is Not Broken — It’s Just Incomplete
There’s a recurring pattern in how teams diagnose slow or stale search results: they assume they made the wrong architectural choice. Real-time indexing feels expensive and fragile, so they switch to batch. Batch feels too slow, so they swing back. The cycle repeats.
The actual problem is almost never which approach they chose. It’s that they’re treating the two as mutually exclusive when production systems almost always need both running in the same pipeline at the same time.
The Case Each One Actually Wins
Real-time indexing earns its place in one specific scenario: when the cost of showing a user something stale is measurable. Live dashboards where a number that’s 90 seconds old triggers a wrong decision. User-facing search where a product that just went out of stock still shows as available. Event feeds where sequence matters.
In those cases, sub-second freshness is not a luxury — it’s a correctness requirement. The compute overhead is real, but so is the alternative.
Batch indexing wins everywhere else. Large historical backfills, embedding refreshes when you swap out a model, rebuilding an index after a schema migration, processing a week of events after an outage recovery — all of this belongs in batch. The throughput is higher, the cost per record is lower, and the consistency guarantees are easier to reason about. You’re not fighting a live data stream while trying to reconstruct three million documents.
The tradeoff is accepting that data behind the freshness window will be hours old. For most of those workloads, that’s completely fine.
Where Teams Actually Get Into Trouble
The failure mode is not choosing the wrong one. It’s designing a pipeline that only has one.
A system built purely on real-time indexing will eventually hit a spike — a traffic surge, a bulk import, a backfill after downtime — and the indexing layer will fall behind or drop events. You patch it with retries, then backpressure handling, then a queue, and six months later you’ve reinvented batch processing badly.
A system built purely on batch indexing will get a requirement for live features — a notification, a search result, a dashboard widget — and someone will start polling the batch job more frequently until it’s running every two minutes and costing more than a streaming pipeline would have.
The hybrid approach is not a compromise. It’s what the workload actually looks like.
What a Hybrid Pipeline Looks Like in Practice
The architecture that holds up well in production looks roughly like this:
Incoming events
|
+--> Stream processor (Kafka / Kinesis / etc.)
| |
| v
| Real-time index (last N minutes / hours)
|
+--> Object storage / data lake
|
v
Batch processor (scheduled or triggered)
|
v
Full historical index
Enter fullscreen mode Exit fullscreen mode
The stream processor handles the freshness window — whatever “recent” means for your use case, whether that’s 15 minutes or 6 hours. The batch layer owns everything behind that window.
Queries fan out to both layers and merge results, with the real-time layer taking precedence for any document that appears in both. The boundary between them can be adjusted without redesigning either side.
The operational challenge is making sure events reach both layers reliably without writing duplicated ingestion logic for each. This is where purpose-built streaming infrastructure pays off — tools like Turboline are built around exactly this problem, routing events once and guaranteeing delivery to both the streaming and batch consumers without you maintaining two separate pipelines with diverging behavior.
The Freshness Window Is a Product Decision
One thing worth making explicit: where you draw the freshness boundary is not primarily an engineering decision. It’s a product decision that engineering then has to implement.
“How old can this data be before it causes a user-visible problem?” is a question your product team can answer faster and more accurately than your infrastructure team can guess. Get that number first, then design the pipeline around it.
If the answer is “under 10 seconds,” you have a hard real-time requirement and the compute budget needs to reflect that. If the answer is “a few hours is fine,” you have a batch workload with a thin real-time layer on top for anything created in the last couple of hours.
Most systems land somewhere in the middle. The teams that stop debating real-time versus batch and start asking “what freshness does each part of this system actually need” ship better pipelines faster and spend less time rebuilding them.
답글 남기기