Let me provide the detailed implementation that transformed our dashboard performance from 8-12 seconds to under 2 seconds.
Widget Query Optimization Strategy:
Our original dashboard had severe inefficiencies:
- 25 widgets making 40+ individual service calls on load
- Each widget querying raw device properties and ValueStreams
- No data reuse across widgets
- Database CPU spiking to 90% on every dashboard open
Solution - Consolidated Data Services: Created a single aggregation service that pre-calculates all dashboard metrics:
Service structure:
- Scheduled execution every 5 seconds
- Queries all required device data in batch
- Performs calculations and aggregations
- Stores results in DashboardDataThing properties
Widgets now bind to DashboardDataThing properties instead of making individual queries. This reduced 40 queries to a single property read per widget.
Backend Data Aggregation Implementation:
Created specialized aggregation Things for each production line:
- ProductionLineMetrics Thing stores pre-calculated KPIs
- Equipment status aggregated across all devices
- Production counts rolled up from individual machines
Aggregation service pattern:
// Pseudocode - Aggregation service execution:
1. Query all production line devices in single batch call
2. Calculate aggregate metrics (OEE, throughput, quality)
3. Update ProductionLineMetrics properties
4. Trigger property change events for widget updates
// Executes every 5 seconds via scheduler
This approach reduced database load by 85% - instead of 40 queries per dashboard load, we have one scheduled service making optimized batch queries every 5 seconds.
Dashboard Caching Strategy:
Implemented two-tier caching:
-
Initial Load Cache: Dashboards load last-known values immediately from cached Thing properties (sub-second load time)
-
Incremental Updates: After initial load, widgets subscribe to property changes for real-time updates
Caching configuration:
- DashboardDataThing properties cached at Thing level
- 5-second TTL aligns with aggregation service schedule
- Stale data never displayed - cache refresh synchronized with data updates
Implementation Results:
Performance Improvements:
- Dashboard load time: 8-12 seconds → 1.5-2 seconds (85% reduction)
- Database CPU during dashboard access: 90% → 15% (83% reduction)
- Concurrent user capacity: 20 users → 150+ users
- Widget update latency: 2-3 seconds → <500ms
Architecture Benefits:
- Single point of optimization for all dashboards
- Consistent data across all widgets (no synchronization issues)
- Predictable database load (scheduled vs. on-demand)
- Easy to add new dashboards without performance degradation
Critical Success Factors:
-
Differentiated Real-Time Requirements: We separated truly real-time metrics (safety, alarms) from monitoring metrics (production counts, efficiency). Real-time data uses direct subscriptions; monitoring data uses 5-second aggregation.
-
Efficient Backend Design: The aggregation service uses optimized batch queries and in-memory calculations, completing all work in under 1 second per execution.
-
Smart Caching: Initial cached load provides instant dashboard rendering, while incremental updates maintain data freshness.
Operator Feedback: The transformation was dramatic. Operators went from avoiding dashboards due to slow performance to actively using them throughout their shifts. The 5-second aggregation delay is imperceptible in practice, and the smooth, responsive interface more than compensates.
Scalability: This architecture now supports 15 production lines with 150+ concurrent users accessing dashboards simultaneously. Database and application server resources remain at comfortable levels (40-50% utilization), leaving substantial headroom for growth.
Key Takeaway: Widget query optimization through backend aggregation is the single most impactful dashboard performance improvement. Moving from per-widget queries to centralized data services reduced our query volume by 95% while actually improving data freshness and consistency.