On ORIGAMI, the healthcare business application I build for SOS Médecins (see the case study), patient search ran on Algolia. A hosted search service, fast, forgiving of typos. Last week I unplugged it entirely. The whole change comes down to two numbers: 33 lines added, 331 removed. And on the user’s side, nobody noticed a thing. That was exactly the outcome I was after.
Why Algolia was there
The reflex is a familiar one. You need a “real” search, instant, typo-tolerant, surfacing the right patient even when you fat-finger three letters. You glance at Postgres, decide it’ll be a hassle, and wire in a specialised service. Algolia does that job very well. Within a few hours the search feels smooth and the matter seems settled.
Except “wiring in Algolia” is never a single line. In the code it meant: a Ruby gem, an npm package on the front end, an initializer to configure, API keys exposed to the browser, a job that reindexed patients into Algolia in parallel with the database on every change, and three Stimulus controllers talking directly to the Algolia client. A dependency isn’t a button you flip: it’s a surface you adopt, upgrade, monitor, and pay for every month.
The real requirement, once you lay it flat
The question I hadn’t asked myself in a long time: what search do I actually need here?
The answer is modest. We look up patients within the scope of a care structure. The dataset runs to hundreds of thousands of records, not tens of millions. The fields are simple: a last name, a first name, a few identifiers. The real need is to find “Smith” when you type “smth”, and to find it fast.
For that, Postgres is more than enough, even at that scale. The pg_trgm extension computes trigram similarity: it absorbs typos and partial prefixes without you writing a single distance algorithm by hand. A dedicated table materialises each patient’s search document, a job keeps it fresh on change, and the query runs in the same database, in the same transaction, with no network round-trip to a third party. That internal backend already existed and had been the default for a few weeks. Algolia was just a second engine we kept around out of caution.
The real argument: health data on the move
KISS is a good reason. It isn’t the best one here.
Sending patient names to a search index hosted abroad means letting health data leave its own infrastructure. It pulls in health-data hosting rules, GDPR, the principle of data minimisation. Even when everything is contractually airtight, it’s one more governance surface: another place sensitive data flows through, another processor to audit, another clause to defend the day someone asks the question.
So removing Algolia isn’t just dropping a dependency and a €250-a-month bill. It’s removing a reason to worry. Patient data no longer leaves the database. There’s no external index to secure, no API keys to leak from the front end, no processing agreement to keep an eye on, for a feature we already knew how to do in-house.
What the switch was really about: nobody feeling a thing
Swapping one search engine for another on software used in production isn’t a matter of flipping a global switch. The bar was clear: on the user’s side, search response times had to stay rigorously identical. Not “roughly as fast”, identical. A patient search that lags by a tenth of a second, on a dispatch desk, gets noticed immediately.
To validate that without risk, I’d added a per-user boolean, internal_patient_search, that turned the new engine on for a handful of accounts only. A selective activation mechanism, not a forgotten flag: long enough to run both backends side by side, compare response times in real conditions, and confirm that the move to Postgres was felt nowhere.
Once that validation was done, the flag had done its job. I removed it at the same time as Algolia, in the same pass: the database column, the checkbox in settings, the permitted params in the controller, the labels in two languages, and three now-pointless tests. A single boolean already touches six corners of the code; the discipline isn’t never adding one, it’s dismantling it the moment it has stopped being useful.
What this is not
This isn’t a case against Algolia. It’s an excellent product, and there are contexts where I’d wire it back in without hesitation: a large e-commerce catalogue, a public-facing search, typo tolerance across millions of documents. The tool isn’t the point.
The point is the question you ask before adopting it. Not “what’s the best search?”, but “what search do I need, for this dataset, in this context?”. When you take the time to answer that honestly, you often avoid importing a dependency, a recurring bill, and, in healthcare, a piece of sensitive data that had no reason to travel.
Simplicity is a decision
Absorbing complexity on the provider’s side so the software stays simple for the client applies just as much to the complexity you inflict on yourself. The best code isn’t the one you write most elegantly: it’s the one you remove because you no longer need it, and will never have to maintain again. 331 fewer lines, one fewer dependency, health data that stays home, and a strictly identical interface for the user, response times included. That’s what a good day looks like.
If you’ve got an external dependency under the hood costing you every month without you really knowing what it buys you, we can look together at what deserves to stay and what can come back home.