From 3-minute queries to sub-second search
Some of the most satisfying engineering wins aren’t new features — they’re the moments a system stops fighting the people who depend on it. One of those, for me, was search.
I worked for over a decade on a large legal-process management platform at the Ministério Público de Goiás. As the data grew into millions of records, the search that everyone used dozens of times a day got slower and slower. At its worst, some queries took two to three minutes — long enough that people would start one, switch to another task, and come back hoping it had finished.
The database wasn’t the enemy; it was just the wrong tool for the job. Relational
queries with LIKE '%term%' across many joined tables can’t be indexed
effectively, and every search became a full scan. We were asking Postgres to do
something it was never designed to do well.
The shift
The fix was to stop searching the database for text and start searching a system built for it. We introduced Elasticsearch, indexed the relevant documents, and moved the heavy text queries there. The same searches that took minutes dropped to under three seconds — usually well under one.
The interesting part wasn’t installing Elasticsearch. It was everything around it:
- Modelling what to index. You don’t mirror your database into Elasticsearch. You decide what users actually search by, and shape documents around those access patterns — denormalising on purpose.
- Keeping it in sync. Indexing happens through background jobs so a write never blocks on the search cluster, and so a reindex of millions of documents doesn’t take the app down with it.
- Relevance is a product decision. Sorting by score, boosting certain fields, handling accents and partial terms — these aren’t database concerns, they’re about what a good result means to the person searching.
What I took from it
Performance work is rarely about a clever trick. It’s about noticing when a component is being used against its grain, and being willing to introduce the right tool — then doing the unglamorous work of syncing, reindexing, and tuning relevance so it stays fast as the data keeps growing.
Cutting a three-minute wait to three seconds didn’t add a single feature. But it gave hundreds of people back a piece of their day, every day. That’s the kind of result I keep chasing.