Your listing search is slow, your product manager wants typo-tolerant autocomplete, and someone in the sprint review said 'just add Elasticsearch'. Before you commit to running a second stateful cluster, it is worth asking what Postgres vs Elasticsearch for property search actually looks like in production. The honest answer: most PropTech platforms can stay on Postgres far longer than they think.
Postgres vs Elasticsearch for property search: the short answer
Postgres wins when your catalog fits on one well-indexed instance, your queries combine structured filters with geography, and your ranking logic is simple. That description covers the majority of listing platforms up to a few million rows. Elasticsearch wins when you need advanced linguistic analysis, heavy faceting at high cardinality, or throughput that one relational primary cannot serve.
The mistake we see most often is treating this as a religion instead of an engineering trade-off. A search engine is a second system of record with its own failure modes, its own upgrade cadence, and its own on-call rotation. You should only pay that price when Postgres genuinely cannot meet a measured requirement.
If your catalog fits on one well-indexed Postgres instance and your ranking is simple, adding Elasticsearch buys you complexity, not performance.
What property search actually demands
Listing search looks simple from the outside and is not. A real PropTech search box combines at least six distinct problems, and each one stresses a different part of your data layer.
- Geographic filtering: radius search around a point, plus polygon filters for neighbourhoods and school districts.
- Fuzzy matching on street and city names, because users type 'Kloveniersburgwal' wrong in creative ways.
- Faceted filters on price, living area, rooms, build year, and energy label, with counts per facet.
- Relevance ranking that blends text match, freshness, and commercial boosts like featured listings.
- Autocomplete that responds in tens of milliseconds while the user is still typing.
- Correct handling of local address formats. In the Netherlands that means BAG data from the Basisregistratie Adressen en Gebouwen, where one street can have multiple spellings and official house number suffixes.
Notice how many of these are structured queries with a text component, not pure full-text search. That shape is exactly where a relational database with the right extensions is strongest.
There is also a consistency requirement unique to listings. When an agent marks a property as sold or changes an asking price, the search index must reflect it immediately, because stale results directly erode user trust. Every hour of replication lag between your database and a separate search engine shows up as a user calling about a home that is no longer available.
Where Postgres full-text search wins
Postgres ships with a serious search toolkit that most teams underuse. tsvector and tsquery give you stemmed, language-aware keyword matching, and a GIN index makes those queries fast. The pg_trgm extension adds trigram similarity, which covers typo-tolerant street name matching and autocomplete. PostGIS adds real geography types with GiST indexes, so 'listings within 2 km of this point' becomes an indexed operator instead of a table scan.
| Search feature | Postgres tool | Practical note |
|---|---|---|
| Keyword match | tsvector + GIN | Stemmed, per-language dictionaries |
| Fuzzy street names | pg_trgm | Similarity threshold tunable per query |
| Radius and polygons | PostGIS geography | GiST index, meter-accurate distances |
| Facet counts | SQL aggregates | Fine to roughly 1M rows, then cache |
| Autocomplete | pg_trgm similarity | Prefix-weighted, under 20 ms achievable |
| Relevance ranking | ts_rank + ORDER BY | Blend with recency and boosts in SQL |
Two patterns do most of the heavy lifting in practice. First, store the tsvector in a generated column and put the GIN index on that column, so documents stay in sync with the source text automatically. Second, use partial indexes scoped to active listings, since sold and archived properties rarely need to rank. On a listing table where two thirds of the rows are historical, a partial index cuts index size and query time roughly proportionally.
The deeper advantage is operational. Your listings, your search index, and your transactional writes live in one system with one consistency model. When an agent marks a property as sold, the search result updates in the same transaction. There is no sync pipeline to monitor, no drift between two stores, and no backfill job to write when the mapping changes.
Where Elasticsearch earns its keep
Elasticsearch is genuinely better at a specific class of problems. Per-field analyzers give you control over tokenization, synonyms, and language-specific stemming that tsvector cannot match. Its aggregation engine produces facet counts over tens of millions of documents without breaking a sweat. And it scales horizontally: when one node is not enough, you add nodes and shards rebalance.
The costs are real and recurring. You are running a JVM cluster with its own heap tuning, cluster state, shard allocation quirks, snapshot and restore discipline, and version upgrade path. Mapping changes often require a full reindex, so you need alias-based reindex workflows from day one. Someone on your team needs to understand yellow cluster states at 3 a.m.
Managed offerings take the edge off but not away. Elastic Cloud or a managed OpenSearch service removes hardware work, yet you still own index design, mapping migrations, query tuning, and the bill. Budget that operational load honestly before you adopt a second engine for a catalog that fits in Postgres memory.
A worked example: 1.2 million Dutch listings
Last year we benchmarked exactly this decision for a SelectCursor client running a Dutch rental platform. The dataset was 1.2 million active listings with BAG addresses, PostGIS geometries, and roughly 40 search requests per second at peak. We built the same five queries on both stacks and measured p95 latency on production-shaped hardware with warmed caches.
| Query | Postgres p95 | Elasticsearch p95 |
|---|---|---|
| Radius + price filters | 38 ms | 11 ms |
| Fuzzy street match | 24 ms | 9 ms |
| Autocomplete prefix | 15 ms | 6 ms |
| Facet counts (6 facets) | 210 ms | 30 ms |
| Polygon neighbourhood | 45 ms | 22 ms |
Read the table carefully. Elasticsearch is faster on every row, but Postgres is already under 50 ms on the four queries that dominate traffic. For a human typing into a search box, the difference between 15 ms and 6 ms is invisible once you add network and rendering time.
The only genuinely weak result was facet counting at 210 ms. We fixed that with a materialized summary table refreshed every five minutes, which dropped facet rendering below 30 ms and kept the entire platform on one database. That one table replaced an entire planned Elasticsearch cluster.
These numbers are from one benchmark on one dataset, so treat them as representative rather than universal. The pattern is what matters: measure your actual query mix before you adopt a second engine. Your mileage will vary with data shape, hardware, and how much tuning you are willing to do.
Postgres vs Elasticsearch: cost and operations compared
Latency is only half the decision. The other half is what each option costs you every month, in infrastructure and in engineering attention. The figures below are estimates from our delivery work, so validate them against your own contracts and team rates.
| Cost item | Postgres only | Postgres + Elasticsearch |
|---|---|---|
| Infra per month | 1 managed instance | Instance + 3-node cluster |
| Sync pipeline | None | CDC plus backfill jobs |
| Data consistency | Transactional | Eventual, with drift risk |
| Upgrade surface | One system | Two systems, two cadences |
| On-call knowledge | Common SQL skills | Specialist cluster expertise |
Remember that you are already paying for Postgres. A managed instance on RDS, Cloud SQL, or Azure Database sits in your budget regardless, so the marginal infrastructure cost of search on Postgres is close to zero. A search cluster is pure addition: typically three nodes minimum for production resilience, plus the staging environment you will inevitably need.
The sync pipeline deserves special attention. Keeping Elasticsearch in step with Postgres means change data capture through logical replication or a tool like Debezium, plus a backfill path for mapping changes, plus alerting when the two stores drift. Teams routinely underestimate this by a factor of three. It is the line item that turns a search improvement into a permanent maintenance tax.
A decision checklist for your next sprint
When the question comes up in planning, run through these rules in order. They reflect what we have seen across PropTech and FinTech delivery engagements.
- Under roughly 2 to 3 million listings with structured filters and geo: stay on Postgres with tsvector, pg_trgm, and PostGIS.
- Autocomplete slow: tune pg_trgm similarity thresholds and add a partial index before reaching for a new system.
- Facet counts above 200 ms: cache them in a materialized table or a Redis layer first.
- Need synonyms, multilingual analyzers, or learning-to-rank: that is genuine Elasticsearch territory.
- Search traffic saturating one Postgres primary after read replicas: now horizontal scaling justifies the move.
- Whichever you pick, benchmark with your own data and your own query mix. Vendor benchmarks will not save you.
Whichever side you land on, instrument before you optimize. Enable pg_stat_statements and log slow search queries for two weeks, then rank them by total time rather than average latency. In our experience the top three queries account for the overwhelming majority of search load, and fixing those is usually cheaper than adopting any new engine. It also gives you the baseline you will need to prove that any future migration actually improved things for your users.
If you do migrate, keep Postgres as the system of record and treat Elasticsearch as a disposable, rebuildable projection. Teams that invert that relationship regret it during the first incident.
Frequently asked questions
Is Postgres full-text search good enough for a property portal? For most portals, yes. With tsvector for keywords, pg_trgm for typos and autocomplete, and PostGIS for geography, Postgres handles catalogs up to a few million listings at p95 latencies under 50 ms for the queries that dominate traffic. Measure your own query mix before assuming otherwise.
When should I switch from Postgres to Elasticsearch? Switch when you have a measured requirement Postgres cannot meet: heavy faceting at high cardinality, advanced linguistic analysis with synonyms, or search throughput that saturates a primary plus read replicas. Do not switch on speculation, because the sync pipeline and cluster operations become a permanent cost.
Can I use Postgres and Elasticsearch together? Yes, and that hybrid is the most common end state at scale. Postgres stays the system of record, and a change data capture pipeline feeds Elasticsearch as a read-optimized projection. Budget for the pipeline itself: backfills, drift detection, and reindexing are where the real engineering time goes.
How do I make Postgres autocomplete fast? Use pg_trgm with a GIN index on the searchable name column, rank by trigram similarity, and prefer prefix-weighted queries. Keep the indexed expression narrow, for example street and city only. On a few million rows this reliably lands in the 10 to 20 ms range without any additional infrastructure.
What about OpenSearch, Meilisearch, or Typesense? They fill the same architectural slot as Elasticsearch with different trade-offs in licensing, operations, and feature depth. The decision framework in this article still applies: first confirm that Postgres with the right extensions cannot meet a measured requirement, then evaluate engines against that requirement.
The bottom line
Postgres vs Elasticsearch for property search is not a binary choice made once. Start on Postgres with tsvector, pg_trgm, and PostGIS, cache the queries that fall outside your latency budget, and add a search engine only when a measured requirement forces you to. You will ship faster now and keep the migration path open for when you genuinely need it.
If you are scoping a listing platform or untangling a search stack that grew faster than expected, SelectCursor builds and rescues exactly these systems. Tell us about your project and we will give you an honest read on whether you need a search engine at all.
Written by Bart Korpershoek
Co-founder & Technical Lead
Part of the SelectCursor engineering team. We build lending platforms, property marketplaces, and fintech infrastructure for European companies.
Connect on LinkedInMore posts from our teamBuilding something similar?
Our team has shipped 50+ Proptech and Fintech platforms. Book a 25-minute call to discuss your architecture, team structure, or product roadmap.
Book a Call