From 8-Second Load Times to Instant: How We Rebuilt a Proptech Analytics Dashboard Handling 2 Million Property Records

(Case Studies) - A proptech startup's dashboard was dying under 2M property records. We rebuilt it in 6 weeks with a Vietnamese team and AI orchestration, slashing load times from 8 seconds to under 200ms. Here's the exact architecture and playbook.

From 8-Second Load Times to Instant: How We Rebuilt a Proptech Analytics Dashboard Handling 2 Million Property Records

I’ll be honest: when the client first showed me their dashboard, I almost laughed.

It was a real estate analytics platform. 2 million property records. 47 different filter combinations. And every single page load took 8.2 seconds on average.

How to Master Outsourcing Software Development: A CTO’s Playbook for 2025

How to Master Outsourcing Software Development: A CTO’s Playbook for 2025

TL;DR: Outsourcing software development isn’t dead—it’s getting smarter. This guide shares real strategies to cut costs by 30-50%,… ...

Their users weren’t just annoyed—they were leaving. The bounce rate on the dashboard page was 67%. The CEO told me, “We’re losing a deal every week because our demo looks like a PowerPoint from 2005.”

So we rebuilt it. From scratch. In 6 weeks. With a team of 4 Vietnamese developers and our AI orchestration layer.

Outsourcing Software Development in 2025: The CTO’s Playbook for Real Results

Outsourcing Software Development in 2025: The CTO’s Playbook for Real Results

TL;DR: Outsourcing software can cut costs by 40-60% and speed up delivery, but only if you pick the… ...

Here’s exactly how we did it.

The Problem Wasn’t Just Slow Queries

The client assumed it was a database issue. “Just throw more indexes at it,” they said.

But when we dug into the stack, we found a bigger mess:

  • N+1 queries everywhere. A single dashboard view fired 142 separate SQL queries.
  • No caching layer. Every page load hit PostgreSQL directly.
  • Client-side rendering with 15MB of JSON. The API returned *everything*, and the browser tried to render it all at once.
  • No pagination on charts. The map view tried to plot 50,000 markers simultaneously.

This wasn’t a performance tuning job. This was a full architectural rewrite.

The Team: 4 Devs in Ho Chi Minh City

We staffed this with a senior full-stack engineer (React + Node.js), a senior data engineer (PostgreSQL + Redis), a middle frontend dev, and a middle backend dev. All based in our Ho Chi Minh City hub.

Price tag for the 6-week sprint: roughly $18,000 in total team cost.

Compare that to the $60,000+ a US-based agency quoted for the same scope. That’s not a typo.

The Architecture: What We Actually Built

1. Materialized Views + Incremental Refresh

We stopped querying raw tables. Instead, we built 4 materialized views that pre-aggregated the data:

sql
CREATE MATERIALIZED VIEW mv_property_summary AS
SELECT 
    region_id,
    property_type,
    COUNT(*) as total_properties,
    AVG(price_per_sqft) as avg_price,
    PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY days_on_market) as median_days
FROM properties p
JOIN transactions t ON p.id = t.property_id
WHERE t.transaction_date >= NOW() - INTERVAL '90 days'
GROUP BY region_id, property_type;

These refreshed every 15 minutes via a cron job. The raw data was still available for drill-downs, but 95% of dashboard queries hit the materialized views.

Result: Query time dropped from 4.2s to 180ms.

2. Redis Caching with Tiered Expiry

We added a Redis layer with smart TTLs:

  • Aggregated stats (region-level): Cache for 5 minutes
  • Property listings (page 1-3): Cache for 2 minutes
  • User-specific filters: Cache for 30 seconds
  • Map tile data: Cache for 10 minutes

The key insight? We cached the *serialized React component state*, not just raw API responses. This meant the frontend could hydrate instantly without re-processing data.

3. Virtualized Rendering for Maps and Tables

The old dashboard tried to render all 50,000 map markers at once. The browser literally crashed on mobile.

We switched to:

  • Mapbox vector tiles with server-side clustering
  • react-window for table virtualization (only renders 20 rows at a time)
  • Debounced filter inputs (300ms delay before firing API calls)

4. API Gateway with Query Batching

This was the sneaky win. We built a lightweight API gateway that batched concurrent requests:

javascript
// Before: 142 separate requests
// After: 8 batched requests
const batchQueries = async (queries) => {
    const response = await fetch('/api/batch', {
        method: 'POST',
        body: JSON.stringify({ queries })
    });
    return response.json();
};

The gateway aggregated requests within a 50ms window, deduplicated identical queries, and returned a single response.

Result: 142 API calls became 8. Network overhead dropped by 82%.

The AI Orchestration Layer: Where ECOA ACP Shined

Here’s the part that surprised even me.

We used the ECOA AI Platform ACP to orchestrate the data pipeline refresh logic. Instead of writing a complex cron scheduler with retry logic, we defined the workflow as a multi-agent system:

  • Agent 1: Monitors raw table changes (CDC via Debezium)
  • Agent 2: Decides which materialized views need refresh
  • Agent 3: Triggers Redis cache invalidation for affected regions
  • Agent 4: Sends Slack alerts if refresh takes > 30 seconds

The agents ran as lightweight Python workers on the ACP runtime. They communicated via a shared Redis stream.

Why does this matter? Because the old system had a single cron job that refreshed *everything* every hour. If one table had a spike in writes, the refresh would time out and the entire dashboard would show stale data for up to 2 hours.

The agent-based approach refreshed only what changed, in real-time. Stale data incidents dropped from 12 per week to zero.

The Results: Hard Numbers

Metric Before After Improvement
Page load time 8.2s 190ms 97.7%
API queries per view 142 8 94.4%
Map render time 14s 400ms 97.1%
Server CPU usage 78% avg 22% avg 71.8%
Monthly hosting cost $4,200 $1,800 57.1%
User bounce rate 67% 12% 82.1%

The client’s CEO sent me a screenshot of the dashboard loading on a 4G connection in under 2 seconds. His Slack message: *”I forgot what instant felt like.”*

What Most Teams Get Wrong About Dashboard Performance

They optimize the wrong thing.

Everyone focuses on SQL query optimization. But in this case, the real bottleneck was *data transfer and rendering*. We could have made every query run in 50ms, and the dashboard still would have taken 6 seconds to load, because the frontend was drowning in JSON.

Here’s the rule I use now: If your API response is larger than 500KB for a dashboard view, you have an architecture problem, not a query problem.

Why Vietnam? Why This Team?

I’ve worked with offshore teams in India, Eastern Europe, and Latin America. The Vietnamese team stood out for one reason: they didn’t just implement specs—they challenged them.

On day 3, the senior backend dev (let’s call him Minh) said: “Your proposed materialized view structure will break when we add new property types. Let me redesign it with JSONB columns for flexibility.”

He was right. His redesign saved us a full week of rework later.

That’s the kind of engineering judgment you can’t buy with a lower hourly rate. You get it by hiring *senior* developers who think like architects, not ticket-closers.

And at $3,000/month for a senior? That’s not cheap labor. That’s a strategic arbitrage.

Frequently Asked Questions

Why did you choose materialized views over a data warehouse like ClickHouse or Redshift?

Cost and complexity. The client’s data volume (2M records) didn’t justify a separate OLAP system. Materialized views in PostgreSQL handled the load with zero additional infrastructure. We only recommend dedicated data warehouses when you’re dealing with 50M+ records or real-time streaming requirements.

How did you handle the 6-week timeline without cutting corners?

We used the ECOA AI Platform ACP to automate all the boilerplate: CI/CD pipelines, infrastructure provisioning, and data pipeline orchestration. This freed the developers to focus on business logic. The AI layer handled about 40% of the “plumbing” work that normally eats up sprint time.

What was the biggest technical risk during the migration?

Data consistency during the cutover. We ran both the old and new dashboards in parallel for 3 days, comparing query results. We found 17 discrepancies—all in the old system’s data. The new system was actually *more* accurate because it used a consistent snapshot strategy.

Can this architecture scale beyond 2 million records?

Yes. We designed the materialized views to work with partitioning. When the client hits 10M records, we’ll add monthly partitions and the query patterns won’t change. The Redis layer also supports clustering, so we can scale horizontally. The architecture is good for at least 50M records before needing a redesign.

Related reading: Why Outsourcing Software Development Is Your Smartest Move in 2025

Leave a Comment

Your email address will not be published. Required fields are marked *

Ready to Build with AI-Powered Developers?

Hire Vietnamese engineers augmented by ECOA AI Platform + Claude Code. 5x faster, 40% cheaper.