-
Notifications
You must be signed in to change notification settings - Fork 0
Measurement Scalability
The measurement system also uses in-memory std::map storage, which has the same scalability limitations as the user registry.
// 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
};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
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 bytesYear 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
| 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
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 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 β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
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: Archived2. 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)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
With LevelDB + Cache:
- Cache hit rate: 95% (recent data)
- Average lookup: 0.001 ms
- Throughput: 1M+ queries/second
- Storage: Scales linearly
- Urgency: π΄ CRITICAL (will hit limit at ~10M users)
- Impact: Blocks user growth
- Timeline: Needed before reaching millions of users
- Urgency: π‘ IMPORTANT (will hit limit at ~100M measurements)
- Impact: Affects long-term data storage
- Timeline: Needed within 1-2 years of operation
- Slower Growth: Measurements accumulate over time (not instant like users)
- Pruning Possible: Can delete old invites and archive old measurements
- Higher Limit: Can handle ~100M measurements vs ~10M users
- Daily Averages: Only need recent data for most operations
β
Current in-memory design is FINE for:
- Initial launch (first 1-2 years)
- Up to 100 million measurements
- Testing and development
- Pilot programs
β οΈ Implement database backend for measurements:
- Before reaching 50M measurements
- Add pruning for old invites
- Archive historical data
- Estimated effort: 2-3 weeks
π― Full database integration:
- Both users and measurements in database
- Distributed storage for global scale
- Sharding by region/currency
- Estimated effort: 2-3 months
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
Active (0-14 days):
- In-memory β
- Fast validation required
Expired (14+ days):
- Can be deleted β
- No longer needed
- Saves memory
All time periods:
- Keep forever (small size)
- Only 518 records per year
- 5,180 records per 10 years
- Total: ~500 KB per 10 years β
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:
- Pruning: Can delete expired invites (users can't be deleted)
- Archiving: Can archive old measurements (users must stay active)
- Daily Averages: Only need recent data for most operations
- 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
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:
- π΄ User Registry: Critical (implement database first)
- π‘ Measurement System: Important (can wait 1-2 years)
- π’ Other Systems: Fine as-is
The measurement system is in better shape than the user registry for scaling! πβ
Β© O International
A Nonprofit Association Focused on the Creation of a Water Price-Based Stable Coin
Association de Loi 1901 β France NumΓ©ro de Siret (French SIREN): 924 014 467 00014