High-performance pool tracking application for Charter House at Princeton University.
# 1. Apply database indexes (2 minutes)
python3 archive/migrate_add_composite_indexes.py
# 2. Build minified assets (1 minute)
python3 archive/build_assets.py
# 3. Restart application (1 minute)
sudo rcctl restart gunicorn_chool
# 4. Verify deployment (1 minute)
python3 archive/verify_performance.pyVersion 2.0.0 delivers significant performance improvements:
| Metric | Before | After | Improvement |
|---|---|---|---|
| Dashboard Load | 800-1200ms | 150-250ms | 5x faster |
| Database Queries | 150-200ms | 30-50ms | 4x faster |
| Queries per Page | 15-20 | 3-5 | 4x reduction |
| Cache Hit Rate | 40% | 85% | 2x improvement |
| Concurrent Users | Baseline | 2-3x | 3x capacity |
- 9 composite indexes for complex queries
- Optimized connection pooling (20 workers)
- Eliminated N+1 query problems
- Database-level aggregations
- Multi-level caching with smart invalidation
- Tag-based cache dependencies
- Automatic cache warming on startup
- Per-user result caching (5-minute TTL)
- CSS and JavaScript minification (~40% size reduction)
- Lazy loading for images and content
- Link prefetching on hover
- Virtual scrolling for large tables
- Batch DOM updates
- Real-time performance metrics
- Slow query detection (>50ms logged)
- Cache effectiveness tracking
- Performance dashboard at /health endpoint
- PostgreSQL database running
- Python 3.7+
- Write permissions in project directory
- Ability to restart application
# Backup database
pg_dump charter_pool > backup_$(date +%Y%m%d_%H%M%S).sql
# Backup code (if using git)
git commit -am "Pre-v2.0.0 backup"python3 archive/migrate_add_composite_indexes.pyExpected output:
======================================================================
Adding composite database indexes for maximum performance...
======================================================================
[1/9] Creating idx_users_active_elo... ✓
[2/9] Creating idx_games_p1_timestamp... ✓
[3/9] Creating idx_games_p2_timestamp... ✓
[4/9] Creating idx_games_p3_timestamp... ✓
[5/9] Creating idx_games_p4_timestamp... ✓
[6/9] Creating idx_games_winner_timestamp... ✓
[7/9] Creating idx_tournaments_status_created... ✓
[8/9] Creating idx_tournament_participants_composite... ✓
[9/9] Creating idx_tournament_matches_composite... ✓
✓ Composite index migration completed successfully!
python3 archive/build_assets.pyExpected output:
======================================================================
Building and minifying static assets...
======================================================================
Minifying static/style.css...
Original: 45,123 bytes
Minified: 27,456 bytes
Savings: 39.2%
✓ Created static/style.min.css
Minifying static/main.js...
Original: 12,345 bytes
Minified: 8,012 bytes
Savings: 35.1%
✓ Created static/main.min.js
✓ Asset build completed successfully!
# For OpenBSD with rcctl
sudo rcctl restart gunicorn_chool
# Or manually
pkill -f gunicorn
gunicorn -c gunicorn.conf.py app:app# Run comprehensive verification
python3 archive/verify_performance.py
# Check health endpoint
curl http://localhost:8000/healthExpected health check response:
{
"status": "ok",
"database": "ok",
"templates": "ok",
"cache": "ok"
}Enhanced in config.py:
- Pool size: 20 connections (increased from 10)
- Pool recycle: 300 seconds (optimized for OpenBSD)
- Max overflow: 30 connections (increased from 20)
- LIFO connection reuse enabled
New configuration in config.py:
- Cache type: SimpleCache
- Default timeout: 300 seconds (5 minutes)
- Cache threshold: 500 items
- Strategic caching for leaderboard, tournaments, user stats
Production settings in gunicorn.conf.py:
- Workers: CPU cores * 2 + 1
- Worker class: sync
- Max requests: 1000 (prevents memory leaks)
- Preload app: True (saves memory)
curl http://localhost:8000/healthResponse includes:
- Database connection status
- Cache status
- Performance metrics (admin only)
curl -u admin:password http://localhost:8000/healthIncludes:
- Average response time
- Cache hit rate
- Slow query count
- Request statistics
# Watch for slow queries
tail -f /var/log/gunicorn_chool.log | grep "Slow"
# Check for errors
tail -f /var/log/gunicorn_chool.log | grep "ERROR"Problem: Migration script fails
# Check database connection
python3 -c "from config import Config; from sqlalchemy import create_engine; create_engine(Config.SQLALCHEMY_DATABASE_URI).connect()"
# Verify PostgreSQL is running
sudo rcctl check postgresql
# Check permissions
psql -U charter_pool -d charter_pool -c "SELECT 1"Problem: Indexes already exist
- Safe to run migration multiple times
- Uses IF NOT EXISTS clause
- No harm in re-running
Problem: Build script fails
# Verify files exist
ls static/style.css static/main.js
# Check permissions
ls -la static/
# Run with verbose output
python3 build_assets.pyProblem: Slow queries persist
# Verify indexes were created
python3 verify_performance.py
# Check index usage
psql charter_pool -c "SELECT indexname FROM pg_indexes WHERE indexname LIKE 'idx_%'"Problem: Low cache hit rate
# Check cache configuration
python3 -c "from config import Config; print(f'Cache: {Config.CACHE_TYPE}, Timeout: {Config.CACHE_DEFAULT_TIMEOUT}')"
# Monitor /health endpoint for cache metricsProblem: Application won't start
# Check logs
tail -100 /var/log/gunicorn_chool.log
# Verify configuration
python3 -c "from config import Config; print('Config OK')"
# Check if port is in use
netstat -an | grep 8000If needed (unlikely), rollback is simple:
# 1. Stop application
sudo rcctl stop gunicorn_chool
# 2. Restore database
psql charter_pool < backup_YYYYMMDD_HHMMSS.sql
# 3. Restore code (if using git)
git checkout <previous-commit>
# 4. Restart
sudo rcctl start gunicorn_choolNote: Database indexes can be left in place - they don't cause any issues.
cache_utils.py- Advanced caching systemperformance.py- Performance monitoringgunicorn.conf.py- Production configuration
archive/migrate_add_composite_indexes.py- Database optimizationarchive/build_assets.py- Asset minificationarchive/verify_performance.py- Comprehensive testing
archive/PERFORMANCE_IMPROVEMENTS.md- Technical detailsarchive/CHANGELOG_v2.md- Complete changelogarchive/DEPLOYMENT_CHECKLIST.txt- Operations guidearchive/MIGRATION_GUIDE.txt- Step-by-step migration
- Python 3.7+
- PostgreSQL 12+
- OpenBSD 7.0+ (recommended)
- Gunicorn 20+
- 2GB RAM minimum
- 10GB disk space
For maximum performance, add to /etc/sysctl.conf:
kern.maxfiles=20000
kern.maxproc=4096
kern.seminfo.semmni=256
kern.seminfo.semmns=512
net.inet.tcp.sendspace=65536
net.inet.tcp.recvspace=65536
hw.perfpolicy=highApply with:
sudo sysctl -f /etc/sysctl.conf# Activate virtual environment
source venv/bin/activate
# Run development server
python3 app.pypython3 init_db.pypython3 verify_performance.pySee archive/DEPLOYMENT_CHECKLIST.txt for complete deployment procedures including:
- Pre-deployment backup
- Step-by-step verification
- Post-deployment monitoring
- Rollback procedures
For detailed migration instructions, see archive/MIGRATION_GUIDE.txt
- Health Check:
curl http://localhost:8000/health - Verification:
python3 archive/verify_performance.py - Logs:
/var/log/gunicorn_chool.log - Documentation: See
archive/directory for detailed guides
MIT License - See repository for details
Created for Charter House at Princeton University Version 2.0.0 - October 2025