Skip to content

Measurement Scalability

O edited this page Oct 7, 2025 · 1 revision

Measurement System Scalability Analysis

🚨 YES - Same Scalability Issue!

The measurement system also uses in-memory std::map storage, which has the same scalability limitations as the user registry.


πŸ“Š Current Architecture Issues

Problem: In-Memory Storage

// Current implementation (NOT SCALABLE):
class MeasurementSystem {
private:
    std::map<uint256, WaterPriceMeasurement> m_water_prices;  // ❌ In-memory
    std::map<uint256, ExchangeRateMeasurement> m_exchange_rates;  // ❌ In-memory
    std::map<uint256, MeasurementInvite> m_invites;  // ❌ In-memory
    std::map<uint256, ValidatedURL> m_validated_urls;  // ❌ In-memory
    std::map<std::string, DailyAverage> m_daily_averages;  // ❌ In-memory
};

πŸ“ˆ Expected Measurement Volume

Daily Measurement Targets:

Per Currency:

Water Price Measurements: 50-300 per day per currency
Exchange Rate Measurements: 50-300 per day per currency
Total per currency per day: 100-600 measurements

Global Scale:

142 currencies Γ— 300 measurements/day = 42,600 measurements/day
42,600 Γ— 365 days = 15,549,000 measurements/year
15.5M Γ— 10 years = 155 million measurements

With Validations:

Each measurement needs 3+ validators
155M measurements Γ— 3 validators = 465M validation records

Total Records Over 10 Years:

Measurements: 155 million
Validations: 465 million (stored in measurement records)
Invites: 310 million (2Γ— measurements for conversion rate)
URLs: 10 million (validated URLs)
Daily Averages: 518,000 (142 currencies Γ— 365 days Γ— 10 years)

TOTAL: ~940 million records over 10 years

πŸ’Ύ Memory Requirements

Record Sizes:

WaterPriceMeasurement:
  - measurement_id: 32 bytes
  - submitter: 33 bytes
  - currency_code: 8 bytes
  - price: 8 bytes
  - volume: 8 bytes
  - volume_unit: 8 bytes
  - price_per_liter: 8 bytes
  - location: 50 bytes
  - source_url: 100 bytes
  - proof_image_hash: 64 bytes
  - timestamp: 8 bytes
  - validators (3 avg): 99 bytes
  - Other fields: ~50 bytes
  Total: ~475 bytes per measurement

ExchangeRateMeasurement: ~450 bytes
MeasurementInvite: ~150 bytes
ValidatedURL: ~200 bytes
DailyAverage: ~100 bytes

Memory Calculations:

Year 1:

15.5M measurements Γ— 475 bytes = 7.4 GB
31M invites Γ— 150 bytes = 4.7 GB
518 daily averages Γ— 100 bytes = 52 KB
Total: ~12 GB RAM

Year 5:

77.5M measurements Γ— 475 bytes = 36.8 GB
155M invites Γ— 150 bytes = 23.3 GB
2,590 daily averages Γ— 100 bytes = 259 KB
Total: ~60 GB RAM

Year 10:

155M measurements Γ— 475 bytes = 73.6 GB
310M invites Γ— 150 bytes = 46.5 GB
5,180 daily averages Γ— 100 bytes = 518 KB
Total: ~120 GB RAM ❌ NOT SUSTAINABLE

πŸ” Comparison: User Registry vs Measurements

Aspect User Registry Measurement System
Growth Rate Linear (one-time registration) Continuous (daily growth)
Total Records 8 billion (max) Billions over time
Record Size ~434 bytes ~475 bytes
RAM at Scale 3.4 TB (8B users) 120 GB (10 years)
Urgency Critical for billions Important for long-term
Current Limit ~10M users ~100M measurements

Conclusion: Measurements are MORE MANAGEABLE but still need database backend


βœ… Solution: Same Database Approach

Recommended Architecture:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ MEASUREMENT SYSTEM (API Layer)                              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ MeasurementSystem                                           β”‚
β”‚   - SubmitWaterPrice()                                      β”‚
β”‚   - ValidateMeasurement()                                   β”‚
β”‚   - GetAverageWaterPrice()                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                            ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ CACHE LAYER (Recent Data Only)                             β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ - Last 30 days of measurements (~1.3M records)             β”‚
β”‚ - Active invites (not expired)                              β”‚
β”‚ - Recent daily averages (last 90 days)                      β”‚
β”‚ Memory: ~1 GB                                               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                            ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ DATABASE LAYER (All Historical Data)                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ LevelDB / RocksDB                                           β”‚
β”‚   - All measurements (billions)                             β”‚
β”‚   - All invites (historical)                                β”‚
β”‚   - All daily averages (complete history)                   β”‚
β”‚   - Compressed storage                                      β”‚
β”‚   Disk: ~100 GB per year                                    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key Optimizations:

1. Time-Based Pruning:

// Keep only recent data in memory
- Active measurements: Last 30 days
- Historical measurements: Database only
- Expired invites: Pruned after 30 days
- Old daily averages: Archived

2. Automatic Archiving:

// Archive old data to cold storage
- Measurements > 1 year old β†’ Archive
- Invites > 30 days old β†’ Delete
- Daily averages β†’ Keep forever (small size)

3. Smart Caching:

// Cache only what's needed for current operations
- Recent measurements (for Gaussian validation)
- Active invites (for submission validation)
- Recent daily averages (for stability calculation)

πŸ“Š With Database Backend

Storage Requirements:

Per Year:

Measurements: 15.5M Γ— 475 bytes = 7.4 GB
Invites: 31M Γ— 150 bytes = 4.7 GB
Daily Averages: 518 Γ— 100 bytes = 52 KB
Total: ~12 GB/year (compressed: ~5 GB/year)

10 Years:

Total disk: ~50 GB (compressed)
RAM needed: ~1 GB (cache only)
Lookup time: ~0.001 ms
Scalable: βœ… YES

Performance:

With LevelDB + Cache:
  - Cache hit rate: 95% (recent data)
  - Average lookup: 0.001 ms
  - Throughput: 1M+ queries/second
  - Storage: Scales linearly

🎯 Priority Assessment

User Registry:

  • Urgency: πŸ”΄ CRITICAL (will hit limit at ~10M users)
  • Impact: Blocks user growth
  • Timeline: Needed before reaching millions of users

Measurement System:

  • Urgency: 🟑 IMPORTANT (will hit limit at ~100M measurements)
  • Impact: Affects long-term data storage
  • Timeline: Needed within 1-2 years of operation

Why Measurements are Less Urgent:

  1. Slower Growth: Measurements accumulate over time (not instant like users)
  2. Pruning Possible: Can delete old invites and archive old measurements
  3. Higher Limit: Can handle ~100M measurements vs ~10M users
  4. Daily Averages: Only need recent data for most operations

πŸ’‘ Practical Recommendations

Short Term (Current):

βœ… Current in-memory design is FINE for:
  - Initial launch (first 1-2 years)
  - Up to 100 million measurements
  - Testing and development
  - Pilot programs

Medium Term (1-2 years):

⚠️ Implement database backend for measurements:
  - Before reaching 50M measurements
  - Add pruning for old invites
  - Archive historical data
  - Estimated effort: 2-3 weeks

Long Term (3+ years):

🎯 Full database integration:
  - Both users and measurements in database
  - Distributed storage for global scale
  - Sharding by region/currency
  - Estimated effort: 2-3 months

πŸ”„ Data Lifecycle Management

Measurements:

Active (0-30 days):
  - In-memory cache βœ…
  - Used for Gaussian validation
  - Fast access required

Recent (30-365 days):
  - Database with cache
  - Used for historical analysis
  - Medium access speed

Historical (1+ years):
  - Database only (cold storage)
  - Used for long-term trends
  - Slow access acceptable

Invites:

Active (0-14 days):
  - In-memory βœ…
  - Fast validation required

Expired (14+ days):
  - Can be deleted βœ…
  - No longer needed
  - Saves memory

Daily Averages:

All time periods:
  - Keep forever (small size)
  - Only 518 records per year
  - 5,180 records per 10 years
  - Total: ~500 KB per 10 years βœ…

🎯 Conclusion

Measurement System Scalability:

Current Status:

  • βœ… Good for initial launch (1-2 years)
  • βœ… Can handle up to 100 million measurements
  • βœ… Much better than user registry (10Γ— more capacity)
  • ⚠️ Will need database backend eventually

Why Less Urgent:

  1. Pruning: Can delete expired invites (users can't be deleted)
  2. Archiving: Can archive old measurements (users must stay active)
  3. Daily Averages: Only need recent data for most operations
  4. Growth Rate: Slower accumulation than user registrations

Timeline:

  • Now: Current design is fine βœ…
  • Year 1-2: Monitor growth, implement pruning
  • Year 2-3: Migrate to database backend
  • Year 3+: Full distributed storage

Recommendation:

For measurements, you're good for now! The current design can handle the initial launch and first 1-2 years of operation. You'll want to implement the database backend before reaching 50-100 million measurements, but that's not an immediate concern.

Priority Order:

  1. πŸ”΄ User Registry: Critical (implement database first)
  2. 🟑 Measurement System: Important (can wait 1-2 years)
  3. 🟒 Other Systems: Fine as-is

The measurement system is in better shape than the user registry for scaling! πŸ“Šβœ…

Clone this wiki locally