SU

supabase-advanced-troubleshooting

Deep diagnostic techniques for identifying performance regressions and database issues in Supabase.

Install

mkdir -p .claude/skills/supabase-advanced-troubleshooting && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/7283" && unzip -o skill.zip -d .claude/skills/supabase-advanced-troubleshooting && rm skill.zip

Installs to .claude/skills/supabase-advanced-troubleshooting

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Deep Supabase diagnostics: pg_stat_statements for slow queries, lock debugging with pg_locks, connection leak detection, RLS policy conflicts, Edge Function cold starts, and Realtime connection drop analysis. Use when standard troubleshooting fails, when investigating performance regressions, when debugging race conditions, or when building evidence for a Supabase support escalation. Trigger with "supabase deep debug", "supabase slow query", "supabase lock contention", "supabase connection leak", "supabase RLS conflict", "supabase cold start".
549 chars✓ has a “when” triggerlonger than Claude Code's old 250-char listing cap (fine on current versions)
Advanced

Key capabilities

  • Identify slow queries using pg_stat_statements
  • Detect lock contention and deadlocks via pg_locks
  • Find connection leaks in idle transactions
  • Analyze RLS policy conflicts

How it works

The workflow uses PostgreSQL system catalogs to query performance metrics and lock states. It provides SQL scripts to rank queries by execution time and identify blocking processes.

Inputs & outputs

You give it
Database connection string or service-role key
You get back
Diagnostic reports on query performance and lock status

When to use supabase-advanced-troubleshooting

  • Debug slow database queries
  • Identify lock contention and deadlocks
  • Detect connection pool leaks
  • Resolve RLS policy conflicts

About this skill

Supabase Advanced Troubleshooting

Overview

When basic debugging does not reveal the root cause, you need deep PostgreSQL diagnostics: pg_stat_statements to find the slowest queries by cumulative execution time, pg_locks to detect lock contention and deadlocks, pg_stat_activity to find connection leaks, RLS policy conflict analysis to diagnose silent data filtering, Edge Function cold start profiling, and Realtime channel drop investigation. This skill covers every advanced diagnostic technique with real SQL queries and createClient from @supabase/supabase-js.

When to use: Slow query investigation, lock contention causing timeouts, connection pool exhaustion from leaks, RLS policies that silently filter or conflict, Edge Functions with unpredictable latency, or Realtime subscriptions that disconnect intermittently.

Prerequisites

  • Supabase project with pg_stat_statements extension enabled
  • Direct database access via SQL Editor or psql
  • @supabase/supabase-js v2+ installed in your project
  • Supabase CLI for Edge Function logs
  • Familiarity with PostgreSQL system catalogs

Authentication

Every technique here runs against your own project's Postgres, so authenticate with project-scoped credentials, never a shared key:

  • psql / SQL Editor — connect with the project's direct connection string or pooled Supavisor URI from Dashboard → Settings → Database. Keep the database password in an env var (PGPASSWORD / .pgpass), never inline in a command.
  • SDK (createClient) — pass the service-role key (SUPABASE_SERVICE_ROLE_KEY) for the diagnostic RPCs below, since they read pg_stat_activity and system catalogs that the anon key cannot. Load it from the environment; never commit it.
  • supabase CLI — run supabase login once (stores a personal access token), then supabase link --project-ref <ref> for Edge Function logs.

Instructions

Work the three diagnostic tracks in the order the symptom points to. Each track's full query set and SDK helper lives in a reference file — SKILL.md carries the skeleton so you can start immediately, then drill in for the complete toolkit.

Step 1: pg_stat_statements and slow query analysis

Enable pg_stat_statements, then rank queries by total execution time, call frequency, and cache-hit ratio to find the real cost centers. Follow up with EXPLAIN (ANALYZE, BUFFERS) on the worst offenders and add targeted indexes with CREATE INDEX CONCURRENTLY. The starter query:

CREATE EXTENSION IF NOT EXISTS pg_stat_statements;

SELECT queryid, calls,
  round(total_exec_time::numeric, 2) AS total_ms,
  round(mean_exec_time::numeric, 2)  AS avg_ms,
  left(query, 150) AS query_preview
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;

The full toolkit — frequency and cache-hit-ratio rankings, the EXPLAIN ANALYZE reading guide, and a timedQuery SDK wrapper that flags any call over 500 ms — is in slow query analysis.

Step 2: lock debugging and connection leak detection

Find blocked/blocking query pairs via pg_locks joined to pg_stat_activity, then hunt connection leaks — especially idle in transaction backends, which hold locks and exhaust the pool. The starter query surfaces who is blocked and who holds the lock:

SELECT blocked.pid AS blocked_pid, blocking.pid AS blocking_pid,
  bl.mode AS lock_mode, left(blocked.query, 80) AS blocked_query
FROM pg_stat_activity blocked
JOIN pg_locks bl ON bl.pid = blocked.pid AND NOT bl.granted
JOIN pg_locks kl ON kl.relation = bl.relation AND kl.granted AND kl.pid != bl.pid
JOIN pg_stat_activity blocking ON blocking.pid = kl.pid
WHERE blocked.state = 'active';

The full toolkit — deadlock detection, idle/idle-in-transaction leak queries with pg_terminate_backend cleanup, and a get_connection_health RPC with utilization alerts — is in lock and connection diagnostics.

Step 3: RLS conflicts, Edge Function cold starts, and Realtime drops

Diagnose silent RLS data filtering, profile Edge Function cold-vs-warm latency, and trace Realtime channel drops. The full walkthrough — RLS policy conflict analysis (SQL and SDK), cold start profiling, channel-state monitoring, and publication configuration — is in RLS, Edge Functions, and Realtime.

Output

This skill produces the following diagnostic artifacts:

  • Slow query identificationpg_stat_statements queries ranking by total time, frequency, and cache hit ratio
  • EXPLAIN ANALYZE proficiency — reading execution plans and creating targeted indexes
  • Lock contention diagnosis — blocked/blocking query pairs with lock modes
  • Connection leak detection — idle and idle-in-transaction connections with kill commands
  • Connection pool monitoring — SDK-based health check RPC with utilization alerts
  • RLS conflict analysis — policy listing with permissive/restrictive classification and multi-level comparison
  • Edge Function profiling — cold start vs warm invocation measurement
  • Realtime debugging — channel state monitoring with system event logging

Error Handling

ErrorCauseSolution
pg_stat_statements not availableExtension not enabledRun CREATE EXTENSION pg_stat_statements;
Seq Scan on large tableMissing index on filter columnCreate index with CREATE INDEX CONCURRENTLY
deadlock detectedCircular lock dependencyEnsure consistent lock ordering across transactions
All connections in idle in transactionApplication not closing transactionsAdd connection timeout; review ORM connection pool settings
RLS returns empty for authenticated userJWT claims don't match policyCheck auth.jwt() output; verify app_metadata is set
Edge Function > 2s cold startLarge dependency bundleLazy-import heavy modules; reduce function size
Realtime TIMED_OUTNetwork/firewall blocking WebSocketCheck port 443 (HTTPS/WSS) is open outbound; verify no proxy strips the Upgrade header
CHANNEL_ERROR on subscribeTable not in Realtime publicationRun ALTER PUBLICATION supabase_realtime ADD TABLE ...

Examples

Example 1 — Quick performance audit:

-- Run this query to get a snapshot of database health
SELECT
  'Connections' AS metric,
  count(*)::text AS value
FROM pg_stat_activity WHERE datname = current_database()
UNION ALL
SELECT 'Cache hit ratio',
  round(100.0 * sum(heap_blks_hit) / nullif(sum(heap_blks_hit + heap_blks_read), 0), 2)::text || '%'
FROM pg_statio_user_tables
UNION ALL
SELECT 'Table bloat (dead tuples)',
  sum(n_dead_tup)::text
FROM pg_stat_user_tables
UNION ALL
SELECT 'Longest running query',
  coalesce(max(age(now(), query_start))::text, 'none')
FROM pg_stat_activity WHERE state = 'active' AND query NOT LIKE '%pg_stat%';

Example 2 — Build a diagnostic bundle for support:

import { createClient } from '@supabase/supabase-js';

const supabase = createClient(url, serviceRoleKey, {
  auth: { autoRefreshToken: false, persistSession: false },
});

async function buildDiagnosticBundle() {
  const bundle: Record<string, any> = {
    timestamp: new Date().toISOString(),
    projectRef: process.env.SUPABASE_PROJECT_REF,
  };

  // Connection stats
  const { data: connHealth } = await supabase.rpc('get_connection_health');
  bundle.connections = connHealth;

  // Table sizes
  const { data: tableSizes } = await supabase.rpc('get_table_sizes');
  bundle.tableSizes = tableSizes;

  // Recent errors from application logs
  const { data: recentErrors } = await supabase
    .from('error_logs')
    .select('message, count, last_seen')
    .order('last_seen', { ascending: false })
    .limit(10);
  bundle.recentErrors = recentErrors;

  console.log(JSON.stringify(bundle, null, 2));
  // Submit with your support ticket at https://supabase.com/dashboard/support
}

Example 3 — Automated slow query alert:

import { createClient } from '@supabase/supabase-js';

const supabase = createClient(url, serviceRoleKey, {
  auth: { autoRefreshToken: false, persistSession: false },
});

async function checkSlowQueries(thresholdMs = 1000) {
  const { data: slowQueries } = await supabase.rpc('get_slow_queries', {
    threshold_ms: thresholdMs,
  });

  if (slowQueries && slowQueries.length > 0) {
    console.warn(`Found ${slowQueries.length} queries averaging > ${thresholdMs}ms`);
    for (const q of slowQueries) {
      console.warn(`  [${q.avg_ms}ms avg, ${q.calls} calls] ${q.query_preview}`);
    }
  }
}

// Database function:
// CREATE OR REPLACE FUNCTION get_slow_queries(threshold_ms numeric DEFAULT 1000)
// RETURNS TABLE(queryid bigint, avg_ms numeric, calls bigint, query_preview text) AS $$
//   SELECT queryid, round(mean_exec_time::numeric, 2), calls, left(query, 150)
//   FROM pg_stat_statements
//   WHERE mean_exec_time > threshold_ms AND calls > 10
//   ORDER BY mean_exec_time DESC LIMIT 10;
// $$ LANGUAGE sql SECURITY DEFINER;

Resources

Next Steps

  • For load testing and scaling patterns, see supabase-load-scale
  • For incident respo

Content truncated.

When not to use it

  • When pg_stat_statements extension is not enabled
  • When using shared keys instead of service-role keys for diagnostics

Prerequisites

pg_stat_statements extension enabledDirect database accesssupabase-js v2+

Limitations

  • Requires direct database access or service-role key
  • Diagnostic queries must be run against project-scoped credentials

How it compares

This method uses deep database-level diagnostics rather than application-level logs to resolve complex performance issues.

Compared to similar skills

supabase-advanced-troubleshooting side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
supabase-advanced-troubleshooting (this skill)126dCautionAdvanced
plain-optimize12moNo flagsIntermediate
sql-optimization-patterns642moNo flagsAdvanced
supabase-postgres-best-practices46moNo flagsIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

More by jeremylongshore

View all by jeremylongshore

analyzing-logs

jeremylongshore

Analyze application logs to detect performance issues, identify error patterns, and improve stability by extracting key insights.

14123

ollama-setup

jeremylongshore

Configure auto-configure Ollama when user needs local LLM deployment, free AI alternatives, or wants to eliminate hosted API costs. Trigger phrases: "install ollama", "local AI", "free LLM", "self-hosted AI", "replace OpenAI", "no API costs". Use when appropriate context detected. Trigger with relevant phrases based on skill purpose.

1167

backtesting-trading-strategies

jeremylongshore

Backtest crypto and traditional trading strategies against historical data. Calculates performance metrics (Sharpe, Sortino, max drawdown), generates equity curves, and optimizes strategy parameters. Use when user wants to test a trading strategy, validate signals, or compare approaches. Trigger with phrases like "backtest strategy", "test trading strategy", "historical performance", "simulate trades", "optimize parameters", or "validate signals".

1071

generating-database-seed-data

jeremylongshore

Process this skill enables AI assistant to generate realistic test data and database seed scripts for development and testing environments. it uses faker libraries to create realistic data, maintains relational integrity, and allows configurable data volumes. u... Use when working with databases or data models. Trigger with phrases like 'database', 'query', or 'schema'.

1033

cursor-codebase-indexing

jeremylongshore

Execute set up and optimize Cursor codebase indexing. Triggers on "cursor index setup", "codebase indexing", "index codebase", "cursor semantic search". Use when working with cursor codebase indexing functionality. Trigger with phrases like "cursor codebase indexing", "cursor indexing", "cursor".

885

testing-mobile-apps

jeremylongshore

Execute mobile app testing on iOS and Android devices/simulators. Use when performing specialized testing. Trigger with phrases like "test mobile app", "run iOS tests", or "validate Android functionality".

810

You might also like

plain-optimize

dropseed

Captures and analyzes performance traces to identify slow queries and N+1 problems. Use when analyzing performance or optimizing database queries.

10

sql-optimization-patterns

wshobson

Master SQL query optimization, indexing strategies, and EXPLAIN analysis to dramatically improve database performance and eliminate slow queries. Use when debugging slow queries, designing database schemas, or optimizing application performance.

64220

supabase-postgres-best-practices

davila7

Postgres performance optimization and best practices from Supabase. Use this skill when writing, reviewing, or optimizing Postgres queries, schema designs, or database configurations.

439

supabase-performance-tuning

jeremylongshore

Optimize Supabase API performance with caching, batching, and connection pooling. Use when experiencing slow API responses, implementing caching strategies, or optimizing request throughput for Supabase integrations. Trigger with phrases like "supabase performance", "optimize supabase", "supabase latency", "supabase caching", "supabase slow", "supabase batch".

416

analyzing-query-performance

jeremylongshore

Execute use when you need to work with query optimization. This skill provides query performance analysis with comprehensive guidance and automation. Trigger with phrases like "optimize queries", "analyze performance", or "improve query speed".

18

find-hypertable-candidates

timescale

Use this skill to analyze an existing PostgreSQL database and identify which tables should be converted to Timescale/TimescaleDB hypertables. **Trigger when user asks to:** - Analyze database tables for hypertable conversion potential - Identify time-series or event tables in an existing schema - Evaluate if a table would benefit from Timescale/TimescaleDB - Audit PostgreSQL tables for migration to Timescale/TimescaleDB/TigerData - Score or rank tables for hypertable candidacy **Keywords:** hypertable candidate, table analysis, migration assessment, Timescale, TimescaleDB, time-series detection, insert-heavy tables, event logs, audit tables Provides SQL queries to analyze table statistics, index patterns, and query patterns. Includes scoring criteria (8+ points = good candidate) and pattern recognition for IoT, events, transactions, and sequential data.

18

Search skills

Search the agent skills registry