Query Analysis with EXPLAIN ANALYZE

Prefix every slow query with EXPLAIN ANALYZE. Look out for Seq Scan, Nested Loop, and high cost values.

Related guides: Advanced Git commands · What is Redis · Deploying with Docker · Docker Compose guide · KEYDAL software development

EXPLAIN ANALYZE SELECT u.name, COUNT(o.id)
FROM users u
JOIN orders o ON o.user_id = u.id
WHERE o.created_at > '2026-01-01'
GROUP BY u.name
ORDER BY COUNT(o.id) DESC
LIMIT 10;

Indexing Strategies

B-tree (default): equality and range queries. GIN: full-text search, JSONB, arrays. GiST: geometric and range data. Partial index: indexes only rows matching a condition.

-- Composite index (frequent WHERE + ORDER BY)
CREATE INDEX idx_orders_user_date ON orders(user_id, created_at DESC);

-- Partial index (active rows only)
CREATE INDEX idx_active_users ON users(email) WHERE active = true;

-- GIN index for JSONB
CREATE INDEX idx_product_tags ON products USING GIN(tags);

Connection Pooling

Each connection consumes about 10MB of RAM. Use PgBouncer or an application-level pool. Do not set max_connections higher than you really need.

Vacuum and Autovacuum

PostgreSQL uses MVCC — DELETE and UPDATE leave dead tuples behind. VACUUM reclaims them. Never disable autovacuum; tune its parameters instead.

-- Check table bloat
SELECT relname, n_dead_tup, n_live_tup,
       ROUND(n_dead_tup::numeric / GREATEST(n_live_tup, 1) * 100, 1) AS dead_pct
FROM pg_stat_user_tables
WHERE n_dead_tup > 1000
ORDER BY n_dead_tup DESC;

Baseline postgresql.conf Tuning

shared_buffers = '256MB'          # ~25% of RAM
work_mem = '16MB'                 # per query (watch: connections * work_mem)
maintenance_work_mem = '128MB'    # for VACUUM, CREATE INDEX
effective_cache_size = '1GB'      # OS cache estimate
random_page_cost = 1.1            # SSD (HDD: 4.0)

Modern Software Development and DevOps Practices

Professional software development rests on three pillars: version control (Git + GitHub/GitLab pull request flow, mandatory code review), CI/CD pipeline (automated test + lint + build + deploy), and observability (Sentry/Datadog/Grafana for logs, metrics, traces). The test pyramid (unit > integration > e2e) ensures code quality, microservice architecture uses Docker containers with Kubernetes orchestration, and REST or GraphQL APIs follow OpenAPI/GraphQL Schema contracts. Across the SDLC (requirements → design → implementation → test → deploy → maintenance), Agile/Scrum sprints last 1-2 weeks while DevOps teams practice continuous delivery.

Conclusion

PostgreSQL tuning boils down to four moves: find the bottleneck with EXPLAIN, add the right index, use a connection pool, and tune autovacuum. Those four steps solve the majority of performance issues KEYDAL sees in production.

WhatsApp