Real Estate PropTech on AWS (2026): MLS Ingest, Geo Search, and Image Pipeline Reference Architecture
Quick summary: For a regional PropTech platform (~420k listings, 38 MLS connectors), DynamoDB canonical store + OpenSearch geo cut median search latency from 340 ms to 48 ms — image CDN cost −62% with Intelligent-Tiering.
Key Takeaways
- Amazon OpenSearch Service supports k-NN vectors up to 16,000 dimensions per field (vector search docs) — enough for listing embedding similarity at regional scale
- AWS HealthImaging-scale lesson does not apply here; PropTech wins on ingest discipline and geo index design, not petabyte imaging
- Benchmark pattern (not a cited client) — Regional PropTech, ~420k active listings, 38 MLS connectors, median search 340 ms, image storage $28k/mo on Standard
- Phase 1: DynamoDB canonical + OpenSearch (search p95 340 ms → 48 ms)
- Phase 2: S3 Intelligent-Tiering + CloudFront WebP (image CDN cost −62%)

Table of Contents
Amazon OpenSearch Service supports k-NN vectors up to 16,000 dimensions per field (vector search docs) — enough for listing embedding similarity at regional scale. AWS HealthImaging-scale lesson does not apply here; PropTech wins on ingest discipline and geo index design, not petabyte imaging.
This post is the real estate / PropTech reference architecture — MLS to mobile map. It is not retail lakehouse analytics, not fintech payments architecture, and not the industry hub FAQ alone.
Artifacts: listing search tier matrix, MLS ingest cost worksheet.
Benchmark pattern (not a cited client) — Regional PropTech, ~420k active listings, 38 MLS connectors, median search 340 ms, image storage $28k/mo on Standard. Phase 1: DynamoDB canonical + OpenSearch
geo_point(search p95 340 ms → 48 ms). Phase 2: S3 Intelligent-Tiering + CloudFront WebP (image CDN cost −62%). No MLS vendor replacement.
Four lanes — MLS to mobile
| Lane | Question | Default AWS path |
|---|---|---|
| Ingest | How do feeds land safely? | Per-connector Lambda + Step Functions |
| Canonical | What is source of truth? | DynamoDB single-table |
| Search | How do users query map + text? | OpenSearch geo_point + optional k-NN |
| Media | How do photos load fast? | S3 → CloudFront WebP variants |
Opinionated take: DynamoDB canonical store before OpenSearch cluster. Teams that index MLS JSON directly into OpenSearch rebuild dedupe logic twice.
Reference architecture
MLS/IDX APIs ──► Lambda connector ──► SQS ──► Normalize ──► DynamoDB (canonical)
│
├──► OpenSearch (geo_point, facets, k-NN)
│
Images ──► S3 ingest ──► Lambda resize (WebP) ──► CloudFront ──► mobile/web
│
Optional ──► Rekognition labels ──► listing enrichment
Optional ──► Bedrock ──► listing copy (human review gate)Ingest — one connector, one failure domain
Per feed:
- Independent Lambda + DLQ — one MLS outage does not poison others
- Normalize to unified schema; key
(marketId, listingId)+addressHashfor cross-MLS dedupe - Fill mls-ingest-cost-worksheet.csv after pilot week in Cost Explorer
Do not schedule full image re-sync 12×/day on large feeds — delta + ETag only.
Canonical — DynamoDB single-table
See DynamoDB single-table SaaS patterns:
- PK:
MARKET#<id>, SK:LISTING#<id> - GSI:
geoHash+statusfor bbox pre-filter before OpenSearch - Stream → OpenSearch indexer (idempotent upsert)
Search — OpenSearch geo + optional k-NN
- Map
locationasgeo_pointforgeo_distanceand polygon filters - Enable k-NN when marketing needs “homes like this” — watch memory: HNSW footprint scales with vector count (OpenSearch quantization blog)
- Amazon Location Place Index for autocomplete if address parsing is messy — do not geocode twice in app and index
Images — cost control
- Generate
thumb,card,galleryWebP at ingest - Intelligent-Tiering after 90 days for stale listings
- CloudFront cache keys per variant — never serve raw MLS TIFF to mobile
What broke — Spring season week 2. Search p95 jumped 48 ms → 410 ms while CPU looked fine. Root cause: OpenSearch shard hot-spot on single high-traffic metro + unbounded
geo_polygonqueries from a partner widget. Detection:SearchLatency+ slow query log. Fix: route top metros to dedicated index alias + rate limit partner API key. p95 back under 80 ms within 12 hours.
When NOT to escalate
| Situation | Stay lighter |
|---|---|
| MVP, one MLS, map-only | API Gateway + DynamoDB GSI |
| < 50k listings | Skip k-NN and second index |
| No OpenSearch ops owner | Managed cluster minimum + runbook first |
| CRE analytics / portfolio | Data lake post — not consumer search |
What to Do This Week
- Inventory MLS connectors — fill mls-ingest-cost-worksheet.csv.
- Run listing-search-tier-decision-matrix.md with product + finance.
- Implement DynamoDB canonical + one OpenSearch index for top market only.
- Switch image bucket to Intelligent-Tiering; measure CloudFront bytes-out for 7 days.
- Defer Bedrock listing copy until human review workflow exists.
Reproduce this — Download mls-ingest-cost-worksheet.csv. Set
sync_frequency_per_daytruthfully; flag any feed >4×/day with full image sync for cost review.
What This Post Doesn’t Cover
- Title / escrow transaction workflows — downstream of search
- Commercial CRE lease abstraction — document AI separate path
- Mortgage origination — fintech compliance cluster
- Specific MLS vendor contracts — legal/commercial, not architecture
We have not load-tested k-NN above 2M vectors on a single domain — run OpenSearch sizing calculator before national semantic search rollout.
Related: Real estate industry hub · Serverless services · Data analytics · Cost optimization
AWS Cloud Architect & AI Expert
AWS-certified cloud architect and AI expert with deep expertise in cloud migrations, cost optimization, and generative AI on AWS.




