postgres-best-practices

Postgres Best Practices

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "postgres-best-practices" with this command: npx skills add santiagoxor/pintureria-digital/santiagoxor-pintureria-digital-postgres-best-practices

Postgres Best Practices

Postgres performance optimization guidelines from Supabase, prioritized by impact.

Categories (Priority Order)

  1. Query Performance (Critical)
  • Use EXPLAIN ANALYZE to understand query plans

  • Add indexes on frequently queried columns (WHERE, JOIN, ORDER BY)

  • **Avoid SELECT *** - specify only needed columns

  • Use LIMIT for large result sets

  • Optimize JOINs - ensure foreign keys are indexed

  • Use prepared statements (Supabase client does this automatically)

  • Batch operations when possible

  1. Connection Management (Critical)
  • Use connection pooling (Supabase provides this)

  • Close connections properly

  • Avoid connection leaks - use connection limits

  • Monitor connection usage in Supabase dashboard

  • Use server-side clients for server components

  • Use client-side clients only in client components

  1. Schema Design (High)
  • Choose appropriate data types (UUID vs INTEGER, VARCHAR vs TEXT)

  • Use NOT NULL constraints where appropriate

  • Add foreign key constraints for data integrity

  • Use ENUMs for fixed value sets

  • Normalize appropriately - balance with query performance

  • Use JSONB for flexible schema (products, metadata)

  1. Concurrency & Locking (Medium-High)
  • Use transactions for atomic operations

  • Keep transactions short - avoid long-running transactions

  • Use appropriate isolation levels

  • Avoid deadlocks - acquire locks in consistent order

  • Use SELECT FOR UPDATE carefully (can cause blocking)

  1. Security & RLS (Medium-High)
  • Enable RLS on all tables

  • Create policies for tenant isolation in multitenant systems

  • Test RLS policies thoroughly

  • Use service role only when necessary (bypasses RLS)

  • Validate inputs before database operations

  • Use parameterized queries (Supabase client does this)

  1. Data Access Patterns (Medium)
  • Use pagination for large datasets (.range() in Supabase)

  • Implement caching for frequently accessed data

  • Use materialized views for complex aggregations

  • Consider read replicas for read-heavy workloads

  • Optimize for common query patterns

  1. Monitoring & Diagnostics (Low-Medium)
  • Monitor slow queries in Supabase dashboard

  • Use pg_stat_statements for query analysis

  • Set up alerts for performance degradation

  • Review query logs regularly

  • Track connection pool usage

  1. Advanced Features (Low)
  • Use full-text search (PostgreSQL tsvector)

  • Consider partitioning for very large tables

  • Use triggers judiciously

  • Leverage Postgres extensions when needed

Common Patterns

Index Creation

-- Single column index CREATE INDEX idx_products_tenant_id ON products(tenant_id);

-- Composite index (order matters!) CREATE INDEX idx_products_tenant_category ON products(tenant_id, category_id);

-- Partial index (for filtered queries) CREATE INDEX idx_products_active ON products(tenant_id) WHERE active = true;

-- Unique index CREATE UNIQUE INDEX idx_products_sku ON products(tenant_id, sku);

Query Optimization

// ❌ Bad: SELECT * and no limit const { data } = await supabase .from('products') .select('*');

// ✅ Good: Specific columns with limit const { data } = await supabase .from('products') .select('id, name, price, image') .eq('tenant_id', tenant.id) .eq('active', true) .order('created_at', { ascending: false }) .limit(20);

Pagination

// Use range for pagination const pageSize = 20; const page = 1;

const { data, error } = await supabase .from('products') .select('id, name, price') .eq('tenant_id', tenant.id) .range((page - 1) * pageSize, page * pageSize - 1);

RLS Policy Best Practices

-- Enable RLS ALTER TABLE products ENABLE ROW LEVEL SECURITY;

-- Tenant isolation policy CREATE POLICY "tenant_isolation" ON products FOR ALL USING ( tenant_id = ( SELECT id FROM tenants WHERE slug = current_setting('app.tenant_slug', true) ) );

-- Public read policy (if needed) CREATE POLICY "public_read_active" ON products FOR SELECT USING ( active = true AND tenant_id = ( SELECT id FROM tenants WHERE slug = current_setting('app.tenant_slug', true) ) );

Connection Usage

// ✅ Server component - use server client import { createClient } from '@/lib/supabase/server';

export async function ServerComponent() { const supabase = createClient(); // Use supabase }

// ✅ Client component - use client 'use client'; import { createClient } from '@/lib/supabase/client';

export function ClientComponent() { const supabase = createClient(); // Use supabase }

Performance Checklist

  • Queries use indexes on WHERE/JOIN columns

  • SELECT statements specify columns (not *)

  • Large queries use LIMIT or pagination

  • RLS policies are optimized (not too complex)

  • Foreign keys have indexes

  • Transactions are kept short

  • Connection pooling is configured

  • Slow queries are identified and optimized

Key Files

  • supabase/migrations/

  • Schema and indexes

  • src/lib/supabase/

  • Client configuration

  • Supabase Dashboard - Query performance monitoring

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

checkout-payments

No summary provided by upstream source.

Repository SourceNeeds Review
General

authentication

No summary provided by upstream source.

Repository SourceNeeds Review
General

error-handling

No summary provided by upstream source.

Repository SourceNeeds Review
General

git-commit-push

No summary provided by upstream source.

Repository SourceNeeds Review