Statistics & Limits Audit
Overview
This document tracks all statistics fields, their sources, and implementation status.Organization Limits (OrganizationLimitsResponse)
✅ Fully Implemented
| Field | Source | Status | Notes |
|---|---|---|---|
tier | Organization.tier | ✅ Set | From organization record |
max_projects | Organization.max_projects | ✅ Set | Set by tier in organizations.py:get_tier_limits() |
max_users | Organization.max_users | ✅ Set | Set by tier |
max_devices | Organization.max_devices | ✅ Set | Set by tier |
max_storage_gb | Organization.max_storage_gb | ✅ Set | Set by tier |
max_mqtt_inbound_messages | Organization.max_mqtt_inbound_messages | ✅ Set | Set by tier |
max_mqtt_outbound_messages | Organization.max_mqtt_outbound_messages | ✅ Set | Set by tier |
max_ecr_images | Organization.max_ecr_images | ✅ Set | Set by tier |
✅ Calculated Correctly
| Field | Calculation | Status | Location |
|---|---|---|---|
current_projects | COUNT(projects) WHERE org_id | ✅ | organizations.py:372-376 |
current_users | COUNT(organization_members) | ✅ | organizations.py:378-380 |
current_devices | COUNT(fleet_devices) JOIN projects | ✅ | organizations.py:385-390 |
current_storage_gb | SUM(project_stats.current_month_storage_bytes) / 1GB | ✅ | organizations.py:420-421 |
current_mqtt_inbound_messages | SUM(project_stats.current_month_mqtt_inbound_messages) | ✅ | organizations.py:422 |
current_mqtt_outbound_messages | SUM(project_stats.current_month_mqtt_outbound_messages) | ✅ | organizations.py:423 |
current_ecr_images | SUM(project_stats.current_ecr_images) | ✅ | organizations.py:424 |
✅ Enforcement
| Resource | Enforcement Point | Status | Location |
|---|---|---|---|
| Projects | Project creation | ✅ | projects.py:198-199 via LimitService |
| Users | Invitation creation | ✅ | organizations.py:495-499 via LimitService |
| Devices | Device registration | ✅ | fleet.py:97-98 via LimitService |
| Storage | Not yet enforced | ⚠️ | Should check before file uploads |
| MQTT Inbound | Not yet enforced | ⚠️ | Should check in Lambda/IoT Rule |
| MQTT Outbound | Not yet enforced | ⚠️ | Should check before publishing |
| ECR Images | Image push check | ✅ | projects.py:733-734 via LimitService |
Project Statistics (ProjectStatsResponse)
Database Fields (project_stats table)
| Field | Type | Updated By | Status | Notes |
|---|---|---|---|---|
current_month_logs | int | ❌ Manual | ⚠️ | Needs automation via StatsUpdaterService |
current_month_sessions | int | ❌ Manual | ⚠️ | Needs automation via StatsUpdaterService |
current_month_mqtt_messages | int | ❌ Manual | ⚠️ | Legacy field, kept for compatibility |
current_month_mqtt_inbound_messages | int | ✅ LimitService.increment_mqtt_inbound() | ✅ | Called by Lambda/API |
current_month_mqtt_outbound_messages | int | ✅ LimitService.increment_mqtt_outbound() | ✅ | Called by Lambda/API |
current_month_api_calls | int | ❌ Manual | ⚠️ | Should use middleware to track |
current_month_deployments | int | ❌ Manual | ⚠️ | Track in deployment API |
current_month_storage_bytes | int | ❌ Manual | ⚠️ | Needs StatsUpdaterService |
total_docker_storage_bytes | int | ❌ Manual | ⚠️ | Query ECR API |
total_s3_storage_bytes | int | ❌ Manual | ⚠️ | Query S3/CloudWatch |
total_logs_storage_bytes | int | ❌ Manual | ⚠️ | Estimate from log count |
current_ecr_images | int | ✅ StatsUpdaterService | ✅ | Queries ECR API |
current_month_docker_upload_bytes | int | ❌ Manual | ⚠️ | Track in ECR push |
current_month_docker_download_bytes | int | ❌ Manual | ⚠️ | Track in device pulls |
current_month_data_transfer_bytes | int | ❌ Manual | ⚠️ | CloudWatch metrics |
total_devices | int | ✅ StatsUpdaterService | ✅ | COUNT(fleet_devices) |
active_devices | int | ✅ StatsUpdaterService | ✅ | COUNT WHERE status=ONLINE/ACTIVE |
total_sessions | int | ✅ StatsUpdaterService | ✅ | COUNT(sessions) |
total_logs | int | ✅ StatsUpdaterService | ✅ | COUNT(error_logs) |
lifetime_logs | int | ✅ reset_monthly_stats() | ✅ | Accumulated monthly |
lifetime_sessions | int | ✅ reset_monthly_stats() | ✅ | Accumulated monthly |
lifetime_mqtt_messages | int | ✅ increment methods | ✅ | Accumulated on each message |
lifetime_api_calls | int | ❌ Manual | ⚠️ | Needs middleware tracking |
last_calculated_at | datetime | ✅ StatsUpdaterService | ✅ | Updated on stats refresh |
month_start_date | datetime | ✅ reset_monthly_stats() | ✅ | Reset monthly |
AWS Integration Status
✅ Implemented
| AWS Service | Metric | Integration | Status |
|---|---|---|---|
| ECR | Image count | StatsUpdaterService._update_ecr_metrics() | ✅ |
| RDS | Database connection | sqlalchemy | ✅ |
| S3 | Bucket exists | storageBucket in CDK | ✅ |
⚠️ Needs Implementation
| AWS Service | Metric | Where to Implement | Priority |
|---|---|---|---|
| IoT Core CloudWatch | PublishIn.Success (inbound) | Lambda function or scheduled job | 🔴 HIGH |
| IoT Core CloudWatch | PublishOut.Success (outbound) | Lambda function or scheduled job | 🔴 HIGH |
| S3 CloudWatch | BucketSize (storage) | StatsUpdaterService | 🟡 MEDIUM |
| ECR | ImageSize (storage) | StatsUpdaterService | 🟡 MEDIUM |
| CloudWatch Logs | Log storage | StatsUpdaterService | 🟢 LOW |
Recommended AWS Lambda Functions
1. MQTT Message Counter Lambda
Trigger: AWS IoT Rule on all MQTT topics Purpose: Increment mqtt_inbound counters in real-time Code Location:backend/lambdas/mqtt-counter/
2. Hourly Stats Updater Lambda
Trigger: EventBridge (every hour) Purpose: Update all project stats from AWS services Code Location:backend/lambdas/stats-updater/
3. Monthly Stats Reset Lambda
Trigger: EventBridge (1st of month at 00:00 UTC) Purpose: Reset monthly counters and archive to lifetime Code Location:backend/lambdas/monthly-reset/
Action Items
🔴 Critical (Needed for MVP)
-
Implement MQTT message tracking Lambda
- Create IoT Rule to capture all device messages
- Lambda function to increment inbound/outbound counters
- Deploy to CDK stack
-
Add MQTT limit enforcement
- Check limits before allowing device to publish (IoT Policy?)
- Check limits before backend publishes to device
- Return 402 error when limit exceeded
-
Fix storage tracking
- Query S3 bucket size via CloudWatch
- Query ECR image sizes
- Update storage fields in stats
🟡 Important (Post-MVP)
-
Add API call tracking middleware
- FastAPI middleware to count requests
- Increment
current_month_api_calls - Enforce API rate limits
-
Add deployment tracking
- Increment counter when capsule is deployed
- Track in sessions API
-
Create scheduled Lambda for stats updates
- Deploy hourly stats updater
- Deploy monthly reset function
🟢 Nice to Have
-
Add CloudWatch dashboards
- Visualize MQTT message rates
- Show storage trends
- Alert on approaching limits
-
Historical data warehouse
- Archive monthly stats to S3/Redshift
- Enable trend analysis
- Billing report generation
Testing Checklist
- Create free tier organization
- Verify all limits are set correctly
- Create project and verify device limit enforcement
- Register device up to limit
- Try to register one more device (should fail with 402)
- Send MQTT messages and verify counters increment
- Check that limit enforcement works for MQTT
- Push ECR images up to limit
- Try to push one more (should fail)
- Verify frontend displays all limits correctly
- Check that stats endpoint returns all fields
- Test monthly reset (mock date to next month)
CDK Stack Integration
Required Environment Variables
Required IAM Permissions
Backend ECS Task Role:ecr:ListImages- List images in repositoryecr:DescribeImages- Get image details (size)cloudwatch:GetMetricStatistics- Query MQTT metricss3:GetBucketSize- Query bucket size (via CloudWatch)iot:ListThings- List devices (for filtering)
dynamodb:GetItem/dynamodb:UpdateItem- Access project_stats- Or use RDS Proxy to access PostgreSQL
Summary
✅ Working
- Organization limits are properly defined
- Limit enforcement for projects, users, devices, ECR images
- Basic stats collection (devices, sessions, logs)
- Frontend displays limits correctly
⚠️ Needs Attention
- MQTT message tracking is NOT implemented - counters exist but never increment
- Storage tracking is incomplete - no S3/ECR size queries
- Stats are created but never updated - need scheduled updates
- Monthly reset is not automated - need Lambda trigger
🔴 Critical Missing Pieces
- IoT Rule + Lambda for MQTT tracking
- MQTT limit enforcement in publish operations
- Scheduled Lambda for stats updates
- S3/ECR storage size queries