2.3 KiB
2.3 KiB
06. Database Connection Pooling & Query Optimization
meta: id: web-production-06 feature: web-production priority: P1 depends_on: [] tags: [performance, database, production, turso, sqlite]
objective:
- Optimize database connections and queries for production load
deliverables:
- Connection pooling configuration
- Query performance audit
- Index optimization
- Slow query logging
steps:
- Configure connection handling:
- Turso/libsql handles connection management internally — no external pool needed
- Configure
@libsql/clientwith appropriate timeout settings - Leverage Turso's edge distribution for low-latency reads
- Audit all Drizzle queries for performance:
- Check web/src/server/db/schema/*.ts for missing indexes
- Review web/src/server/api/routers/*.ts for N+1 queries
- Add pagination to all list endpoints (default 50, max 100)
- Add database indexes:
- createdAt indexes for time-range queries (alerts, exposures)
- Composite indexes for common filter combinations
- userId indexes on all user-scoped tables
- Implement query result caching:
- Cache user profile lookups (5 min TTL)
- Cache subscription status (1 min TTL)
- Cache dashboard summary (30 sec TTL)
- Add slow query logging:
- Log queries taking >500ms
- Alert on >1s queries
- Set up database performance monitoring
tests:
- Unit: Test query execution plans for major endpoints
- Load: Run 1000 concurrent dashboard loads, verify <200ms p95
- Integration: Test pagination boundaries
acceptance_criteria:
- Database connection pool configured with max 20 connections
- No N+1 queries in any API endpoint
- All list endpoints paginated with cursor or offset
- Slow query logging active
- Dashboard load query <100ms p95
- Alert endpoint query <50ms p95
validation:
- EXPLAIN ANALYZE on major queries shows index usage
- Load test with k6: 1000 concurrent users, p95 < 200ms
- Database CPU <50% under normal load
notes:
- Current schema has some indexes but may need more for production scale
- Turso/libsql handles connection management internally — no PgBouncer or connection pool needed
- Turso provides edge read replicas automatically — configure primary for writes, edges for reads
- SQLite has different query patterns than PostgreSQL — avoid heavy JOINs on large tables, prefer indexed lookups