Add configurable database connection pool settings (#281)
* add configurable database connection pool settings
adds comprehensive pool configuration based on production best practices:
timeouts:
- DATABASE_STATEMENT_TIMEOUT (10s) - kills runaway queries
- DATABASE_CONNECTION_TIMEOUT (3s) - fails fast on db issues
- pool_timeout = connection_timeout - fails fast when pool exhausted
pool sizing:
- DATABASE_POOL_SIZE (5) - persistent connections
- DATABASE_MAX_OVERFLOW (0) - strict limit, no burst capacity
- DATABASE_POOL_RECYCLE (7200s) - recycle after 2 hours
- DATABASE_POOL_PRE_PING (true) - verify connection health
all settings are now configurable via env vars with sensible defaults.
also adds comprehensive documentation at docs/backend/database/connection-pooling.md covering:
- configuration reference
- production tuning guidance
- monitoring and troubleshooting
- scaling strategies
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* add database performance dashboard for logfire
new comprehensive dashboard query showing:
- query performance grouped by type (SELECT, INSERT, UPDATE, DELETE) and table
- latency percentiles (avg, p50, p95, p99, max)
- error counts and rates
- sorted by impact (query count × avg duration)
includes 3 alternative query modes:
1. default: aggregated metrics by query pattern and table
2. slowest queries: top 25 individual slow query instances
3. timeline: hourly query volume and performance trends
4. transactions: connection pool and transaction metrics
classifies queries by primary table (tracks, artists, albums, queue_state, etc)
to identify which parts of the schema are under most load.
useful for:
- identifying slow query patterns
- monitoring query volume by table
- tracking database error rates
- analyzing connection pool health
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix database dashboard to extract tables from actual SQL queries
the span_name is just 'SELECT neondb' / 'UPDATE neondb' etc.
the actual SQL query is in attributes->>'db.statement'.
updated dashboard to:
- extract table names from the actual SQL text in attributes
- distinguish between simple queries and JOINs (e.g. 'tracks' vs 'tracks+joins')
- use exact span_name matches instead of LIKE patterns
- show first 150 chars of actual query in slowest queries view
now the dashboard will properly classify queries by table instead of
showing everything as 'other/multiple'.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix query timeline to use per-minute buckets instead of hourly
hourly bucketing was creating artificial spikes at every hour mark
because all queries from 19:00-19:59 were grouped into a single point.
changes:
- use DATE_TRUNC('minute') instead of DATE_TRUNC('hour')
- reduce time window to 2 hours (less noise, better detail)
- rename to 'Time' instead of 'Hour' for clarity
this will create a much smoother time series chart showing
actual query patterns instead of hourly spike artifacts.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
authored by
zzstoatzz.io
Claude
and committed by
GitHub
a27a924c
d6c22c19