Alerts
Every alert Sourcegull's Prometheus rules can fire, with what to do about it. The rules are generated from crates/monitoring into deploy/docker/prometheus/sourcegull-alerts.yml (in the Compose bundle, to load into your Prometheus) and the Helm chart's PrometheusRule (metrics.prometheusRule.enabled=true); README.md shows how to set them up. See dashboards.md for the panels they watch.
Each alert is named sourcegull_<service>_<observable> and carries the labels severity (warning: needs a look soon; critical: users are affected or will be shortly), service, owner and sourcegull_alert (the anchor below). A warning and a critical rule share a name; inhibit the warning while the critical one fires. Alertmanager routing is up to your Prometheus setup.
web_http_5xx_ratio
web: share of requests answered with 5xx
Descriptions
- warning: web: share of requests answered with 5xx above 2% for 5m
- critical: web: share of requests answered with 5xx above 10% for 10m
Next steps
- Find the failing routes: in Grafana, run
sum by (route, status) (rate(sourcegull_http_requests_total{role=~"web|all",status=~"5.."}[5m])). - Read the web logs for
errorentries around that time (docker compose logs web,kubectl logs -l app.kubernetes.io/component=web). Failed responses carry anx-request-idthat appears in the log lines. - Many 502/503 from GraphQL or search often mean Postgres or the repo nodes are unreachable: check the Postgres and repo dashboards.
- Panel: share of requests answered with 5xx on the Sourcegull: web dashboard.
Query
(sum(rate(sourcegull_http_requests_total{role=~"web|all",route!~"/metrics|/healthz|/readyz",status=~"5.."}[5m])) or 0 * sum(rate(sourcegull_http_requests_total{role=~"web|all",route!~"/metrics|/healthz|/readyz"}[5m])))
/ sum(rate(sourcegull_http_requests_total{role=~"web|all",route!~"/metrics|/healthz|/readyz"}[5m]))
Owner: platform
web_http_p90_latency
web: 90th percentile request duration by route
Descriptions
- warning: web: 90th percentile request duration by route above 5s for 15m
Next steps
- Check which routes are slow on this panel; GraphQL (
/.api/graphql) has its own panel below. - Slow GraphQL requests and searches are logged above
observability.logSlowGraphQLRequests/observability.logSlowSearchesand listed under Site admin > Slow requests. - Check Postgres (connection saturation, long transactions) and CPU usage of the web instances; add web replicas if they are CPU-bound.
- Panel: 90th percentile request duration by route on the Sourcegull: web dashboard.
Query
histogram_quantile(0.9, sum by (le, route) (rate(sourcegull_http_request_duration_seconds_bucket{role=~"web|all",route!~"/metrics|/healthz|/readyz|/.api/search/stream|/.api/compute/stream|/.api/blame/.*|/.api/scip/upload|/.api/files/.*|/.executors/.*"}[5m])))
Owner: platform
web_search_stream_p90_duration
web: 90th percentile streaming search duration
Descriptions
- warning: web: 90th percentile streaming search duration above 20s for 15m
Time from the request until the search stream ends, as users see it. Histogram buckets end at 60 s.
Next steps
- Check the repo dashboard: index queue length and index errors (unindexed repositories are searched without the index, which is slower), and the repo node instances.
- Look for expensive queries under Site admin > Slow requests (
observability.logSlowSearches). - Check CPU and memory of the repo nodes; the index's hot set should fit in RAM (see the Helm sizing guide).
- Panel: 90th percentile streaming search duration on the Sourcegull: web dashboard.
Query
histogram_quantile(0.9, sum by (le) (rate(sourcegull_http_request_duration_seconds_bucket{role=~"web|all",route="/.api/search/stream"}[5m])))
Owner: search
web_graphql_p90_duration
web: 90th percentile GraphQL request duration
Descriptions
- warning: web: 90th percentile GraphQL request duration above 5s for 15m
Next steps
- Find the slow operations under Site admin > Slow requests (enable
observability.logSlowGraphQLRequests). - Check the Postgres dashboard for connection saturation and long transactions.
- Panel: 90th percentile GraphQL request duration on the Sourcegull: web dashboard.
Query
histogram_quantile(0.9, sum by (le) (rate(sourcegull_http_request_duration_seconds_bucket{role=~"web|all",route="/.api/graphql"}[5m])))
Owner: platform
web_webhook_rejection_ratio
web: share of code host webhooks rejected
Descriptions
- warning: web: share of code host webhooks rejected above 50% for 30m
Next steps
- 401/403: the secret token in GitLab does not match the webhook's secret. Compare them on the code host connection page (Site admin > Code host connections > Webhooks) and in GitLab (project or group > Settings > Webhooks).
- 404: the webhook was deleted in Sourcegull but GitLab still sends to it; remove it in GitLab.
- Recent deliveries and their errors are listed under Site admin > Webhook logs.
- Panel: share of code host webhooks rejected on the Sourcegull: web dashboard.
Query
(sum(rate(sourcegull_http_requests_total{role=~"web|all",route=~"/.api/gitlab-webhooks|/.api/webhooks/.*",status!~"2.."}[30m])) or 0 * sum(rate(sourcegull_http_requests_total{role=~"web|all",route=~"/.api/gitlab-webhooks|/.api/webhooks/.*"}[30m])))
/ sum(rate(sourcegull_http_requests_total{role=~"web|all",route=~"/.api/gitlab-webhooks|/.api/webhooks/.*"}[30m]))
Owner: source
web_instance_up
web: instances answering Prometheus scrapes
Descriptions
- critical: web: instances answering Prometheus scrapes below 1 for 5m
1 while Prometheus can scrape the instance's internal listener (:6060), 0 when it cannot.
Next steps
- Check the web containers or pods (
docker compose ps web,kubectl get pods -l app.kubernetes.io/component=web) and their logs for a crash or failed start. - A web instance refuses to start while database migrations are pending: run
sourcegull migrate up(the Helm chart's migrate job does this on upgrade). - If the instance runs but cannot be scraped, check that Prometheus reaches port 6060 (NetworkPolicy, Compose network).
- Panel: instances answering Prometheus scrapes on the Sourcegull: web dashboard.
Query
up{role=~"web|all"}
Owner: platform
repo_disk_free_ratio
repo: free disk space on the data volume
Descriptions
- warning: repo: free disk space on the data volume below 15% for 10m
- critical: repo: free disk space on the data volume below 5% for 5m
Measured by the repo node janitor (2 minutes after start, then hourly). The node pauses clones when free space is below both SOURCEGULL_REPO_PAUSE_CLONES_FREE_PERCENT (default 10%) of the volume and SOURCEGULL_REPO_PAUSE_CLONES_FREE_GIB (default 20 GiB); Site admin > Repo nodes shows the threshold.
Next steps
- Grow the node's volume (Helm:
repo.persistence.sizeon a storage class that allows expansion; Compose: therepo-0-datavolume's disk). - Or add a repo node so repositories spread over more disks (Helm:
repo.replicaCount). - Check Site admin > Repo nodes and Repositories for unexpectedly large repositories; excluding them in the code host connection frees their space after the next sync.
- The repo node janitor removes repositories deleted from Sourcegull and maintains the object stores; its errors appear in the repo node's logs.
- Panel: free disk space on the data volume on the Sourcegull: repo dashboard.
Query
min by (instance) (sourcegull_repo_disk_free_bytes{role=~"repo|all"} / sourcegull_repo_disk_total_bytes{role=~"repo|all"})
Owner: source
repo_repo_update_error_ratio
repo: share of clones and fetches failing
Descriptions
- warning: repo: share of clones and fetches failing above 20% for 30m
- critical: repo: share of clones and fetches failing above 80% for 30m
Next steps
- Site admin > Repositories lists the failing repositories with their last error (filter: Failed fetch).
- If most updates fail, the code host is probably unreachable or the connection's token expired or lost access: test the connection under Site admin > Code host connections.
- Check the repo node logs for
repo update failedentries; corrupt clones are re-cloned from Site admin > Repositories. - Panel: share of clones and fetches failing on the Sourcegull: repo dashboard.
Query
(sum by (kind) (rate(sourcegull_repo_updates_total{role=~"repo|all",outcome="error"}[30m])) or 0 * sum by (kind) (rate(sourcegull_repo_updates_total{role=~"repo|all"}[30m])))
/ sum by (kind) (rate(sourcegull_repo_updates_total{role=~"repo|all"}[30m]))
Owner: source
repo_update_queue_oldest
repo: age of the oldest queued clone or fetch
Descriptions
- warning: repo: age of the oldest queued clone or fetch above 2h for 30m
Next steps
- Check that every repo node is up (instances panel) and processing:
sourcegull_repo_updates_totalshould grow. - A large backlog after adding a code host connection drains by itself; to speed it up raise
gitMaxConcurrentClonesin the site config (read when a repo node starts) andSOURCEGULL_REPO_MAX_CONCURRENT_FETCHESon the repo nodes, or add repo nodes. - Queued and failed jobs are listed under Site admin > Background jobs (
repo_update_jobs). - Panel: age of the oldest queued clone or fetch on the Sourcegull: repo dashboard.
Query
max(sourcegull_queue_oldest_queued_seconds{queue="repo_update_jobs"})
Owner: source
repo_repos_corrupted
repo: repositories marked corrupt
Descriptions
- warning: repo: repositories marked corrupt above 0 for 5m
Next steps
- Re-clone the repositories from Site admin > Repositories (filter: Corrupted).
- Repeated corruption on one node points to its disk or file system: check the node's kernel and volume logs.
- Panel: repositories marked corrupt on the Sourcegull: repo dashboard.
Query
max(sourcegull_repos_corrupted)
Owner: source
repo_index_queue_length
repo: repositories waiting to be indexed
Descriptions
- warning: repo: repositories waiting to be indexed above 500 for 1h
Next steps
- After a large import the queue drains by itself; check the build rate on the index updates panel.
- If it does not shrink, check the repo node logs for
indexing failedand its CPU usage; raise the node's CPU or add repo nodes. - Searches over unindexed repositories still work but are slower.
- Panel: repositories waiting to be indexed on the Sourcegull: repo dashboard.
Query
max by (instance) (sourcegull_index_queue_length{role=~"repo|all"})
Owner: search
repo_index_error_ratio
repo: share of index builds failing
Descriptions
- warning: repo: share of index builds failing above 20% for 30m
Next steps
- Site admin > Repositories shows the index status and error of each repository (filter: Not indexed).
- Check the repo node logs for
indexing failed; disk full (see the disk panels) is a common cause. - Panel: share of index builds failing on the Sourcegull: repo dashboard.
Query
(sum(rate(sourcegull_index_updates_total{role=~"repo|all",outcome="error"}[30m])) or 0 * sum(rate(sourcegull_index_updates_total{role=~"repo|all"}[30m])))
/ sum(rate(sourcegull_index_updates_total{role=~"repo|all"}[30m]))
Owner: search
repo_repo_moves_failed
repo: repository moves that gave up
Descriptions
- warning: repo: repository moves that gave up above 0 for 30m
Next steps
- Site admin > Repo nodes lists the failed moves with their errors; the repositories stay on their old node and keep working.
- Common causes: the old node is unreachable from the new one (gRPC port 3178), or the new node's disk is full.
- Fix the cause, then use Retry failed moves on that page.
- Panel: repository moves that gave up on the Sourcegull: repo dashboard.
Query
max(sourcegull_repo_moves{state="failed"})
Owner: source
repo_instance_up
repo: instances answering Prometheus scrapes
Descriptions
- critical: repo: instances answering Prometheus scrapes below 1 for 5m
1 while Prometheus can scrape the instance's internal listener (:6060), 0 when it cannot.
Next steps
- Check the repo pods or containers (
kubectl get pods -l app.kubernetes.io/component=repo,docker compose ps repo-0) and their logs. - A repo node refuses to start while migrations are pending, and when its data volume is not writable.
- While a node is down, searches skip its repositories (results say so) and its clones and fetches wait.
- Panel: instances answering Prometheus scrapes on the Sourcegull: repo dashboard.
Query
up{role=~"repo|all"}
Owner: platform
worker_queue_oldest_queued
worker: age of the oldest queued job by queue
Descriptions
- warning: worker: age of the oldest queued job by queue above 6h for 30m
Next steps
- Check that the workers are up (instances panel) and their logs for errors from the queue's handler.
- Site admin > Background jobs shows the queue's oldest jobs and recent failures; a single job type failing and retrying can hold up the rest.
- Queues that do much work per job (trend backfills, search jobs) can lag after large changes; add worker replicas or raise the feature's concurrency setting (e.g.
insights.query.worker.concurrency,batchChanges.reconcilerConcurrency). - Panel: age of the oldest queued job by queue on the Sourcegull: worker dashboard.
Query
max by (queue) (sourcegull_queue_oldest_queued_seconds{queue!~"codeintel_index_jobs|batch_spec_workspace_execution_jobs|repo_update_jobs"})
Owner: platform
worker_upload_processing_failure_ratio
worker: share of SCIP upload processing runs failing
Descriptions
- warning: worker: share of SCIP upload processing runs failing above 25% for 30m
Next steps
- The repository's Code graph > Uploads page shows each failed upload's error.
unknown commiterrors mean the repo node has not fetched the uploaded commit yet; they are retried. Check the repo dashboard if they persist.- Check the worker logs for
processing an upload failedand the blob store (blob dashboard) for errors reading upload files. - Panel: share of SCIP upload processing runs failing on the Sourcegull: worker dashboard.
Query
(sum(rate(sourcegull_codeintel_upload_processing_seconds_count{outcome!="completed"}[1h])) or 0 * sum(rate(sourcegull_codeintel_upload_processing_seconds_count[1h])))
/ sum(rate(sourcegull_codeintel_upload_processing_seconds_count[1h]))
Owner: code-intel
worker_codeintel_failing_repos_growth
worker: growth in repositories whose precise indexing fails, over 6 hours
Descriptions
- warning: worker: growth in repositories whose precise indexing fails, over 6 hours above 0 for 1h
Next steps
- Site admin > Index coverage, filtered to Failing, lists the repositories with the latest failure message; each links to the repository's Code graph page with the job's logs.
- Many repositories failing at once usually means the executors or an indexer image broke: check the executor dashboard and an index job's logs.
- Code navigation in a failing repository answers from its last completed index or from search, so results can be incomplete until indexing succeeds again.
- Panel: growth in repositories whose precise indexing fails, over 6 hours on the Sourcegull: worker dashboard.
Query
max(sourcegull_codeintel_coverage_repos{state="failing"}) - max(sourcegull_codeintel_coverage_repos{state="failing"} offset 6h)
Owner: code-intel
worker_reconciler_failure_ratio
worker: share of changeset reconciliations failing
Descriptions
- warning: worker: share of changeset reconciliations failing above 20% for 30m
Next steps
- The bulk change's page lists the failed changesets with the code host's error.
- Most failures are code host permissions: the bulk change's credential (user or site credential) needs
apiscope and Developer access to the project. - Check the code host's rate limits and status; the outbound requests log (Site admin > Outbound requests) shows recent calls when
outboundRequestLogLimitis set. - Panel: share of changeset reconciliations failing on the Sourcegull: worker dashboard.
Query
(sum(rate(sourcegull_batches_changesets_reconciled_total{outcome="failed"}[30m])) or 0 * sum(rate(sourcegull_batches_changesets_reconciled_total[30m])))
/ sum(rate(sourcegull_batches_changesets_reconciled_total[30m]))
Owner: batches
worker_changeset_sync_error_ratio
worker: share of changeset syncs failing
Descriptions
- warning: worker: share of changeset syncs failing above 50% for 1h
Next steps
- The syncer reads merge request state from GitLab; check the code host connection (Site admin > Code host connections > Test) and its token.
- Worker logs show the failing changesets and errors.
- Panel: share of changeset syncs failing on the Sourcegull: worker dashboard.
Query
(sum(rate(sourcegull_batches_changeset_syncs_total{outcome="error"}[1h])) or 0 * sum(rate(sourcegull_batches_changeset_syncs_total[1h])))
/ sum(rate(sourcegull_batches_changeset_syncs_total[1h]))
Owner: batches
worker_code_monitor_delivery_error_ratio
worker: share of watch notifications failing by kind
Descriptions
- warning: worker: share of watch notifications failing by kind above 50% for 30m
Next steps
- Email: check the SMTP settings (
email.smtpandemail.addressin the site config) and the worker logs for SMTP errors. - Slack, Mattermost and webhooks: the receiving URL rejects or does not answer; the watch's page shows the last errors. Fix or remove the action.
- Telegram: the Bot API refuses the message (wrong bot token, or the bot is not in the chat) or is unreachable from the worker; the watch's page shows the Bot API's answer.
- Panel: share of watch notifications failing by kind on the Sourcegull: worker dashboard.
Query
(sum by (kind) (rate(sourcegull_code_monitor_deliveries_total{outcome="error"}[1h])) or 0 * sum by (kind) (rate(sourcegull_code_monitor_deliveries_total[1h])))
/ sum by (kind) (rate(sourcegull_code_monitor_deliveries_total[1h]))
Owner: code-insights
worker_outbound_webhook_error_ratio
worker: share of outbound webhook deliveries failing
Descriptions
- warning: worker: share of outbound webhook deliveries failing above 50% for 30m
Next steps
- Site admin > Outbound webhooks shows each webhook's recent deliveries with status and error.
- Fix or remove the receiving endpoint; failed deliveries are retried with backoff.
- Panel: share of outbound webhook deliveries failing on the Sourcegull: worker dashboard.
Query
(sum(rate(sourcegull_outbound_webhook_deliveries_total{outcome="error"}[1h])) or 0 * sum(rate(sourcegull_outbound_webhook_deliveries_total[1h])))
/ sum(rate(sourcegull_outbound_webhook_deliveries_total[1h]))
Owner: platform
worker_oob_migration_errors
worker: out-of-band migration errors in the last hour
Descriptions
- warning: worker: out-of-band migration errors in the last hour above 0
Next steps
- Site admin > Migrations lists the migration's last errors.
- Re-encryption errors usually mean a key is missing from the key file (
SOURCEGULL_KEYS_FILE) orSOURCEGULL_KEYS: keep old keys there until the migration completes. - Upgrades refuse to pass a version whose out-of-band migrations are incomplete, so fix the cause before upgrading.
- Panel: out-of-band migration errors in the last hour on the Sourcegull: worker dashboard.
Query
sum by (id) (increase(sourcegull_oob_migration_errors_total[1h]))
Owner: platform
worker_instance_up
worker: instances answering Prometheus scrapes
Descriptions
- critical: worker: instances answering Prometheus scrapes below 1 for 5m
1 while Prometheus can scrape the instance's internal listener (:6060), 0 when it cannot.
Next steps
- Check the worker containers or pods (
docker compose ps worker,kubectl get pods -l app.kubernetes.io/component=worker) and their logs. - A worker refuses to start while migrations are pending.
- While no worker runs, queues grow and singleton jobs (syncs, janitors, schedulers) stop; they resume when a worker is back.
- Panel: instances answering Prometheus scrapes on the Sourcegull: worker dashboard.
Query
up{role=~"worker|all"}
Owner: platform
executor_jobs_without_executors
executor: queued executor jobs while no executor is active
Descriptions
- warning: executor: queued executor jobs while no executor is active above 0 for 15m
The number of queued executor jobs when no executor has sent a heartbeat for a minute, else 0.
Next steps
- Start executors: Compose
docker compose --profile executors up -d, Helmexecutor.enabled=true. - If executors run, check their logs: a wrong
SOURCEGULL_EXECUTOR_TOKEN(must equalexecutors.accessTokenin the site config) or an unreachableSOURCEGULL_EXECUTOR_FRONTEND_URLstops heartbeats. - Without executors, disable auto-indexing (Site admin > Code graph policies) and server-side bulk changes so jobs stop piling up.
- Panel: queued executor jobs while no executor is active on the Sourcegull: executor dashboard.
Query
sum(max by (queue) (sourcegull_queue_jobs{queue=~"codeintel_index_jobs|batch_spec_workspace_execution_jobs",state="queued"}))
* on() (max(sourcegull_executors_active) == bool 0)
Owner: platform
executor_queue_oldest_queued
executor: age of the oldest queued executor job by queue
Descriptions
- warning: executor: age of the oldest queued executor job by queue above 1h for 30m
Next steps
- Executors are busy or missing: compare running jobs with the executors' capacity (
SOURCEGULL_EXECUTOR_MAX_JOBS/ Helmexecutor.maxConcurrentJobsper executor). - Add executors (Helm
executor.replicaCount) or raise their concurrency if the nodes have room. - Executors only take queues listed in
SOURCEGULL_EXECUTOR_QUEUES(Helmexecutor.queues); check the queue is in the list. - Panel: age of the oldest queued executor job by queue on the Sourcegull: executor dashboard.
Query
max by (queue) (sourcegull_queue_oldest_queued_seconds{queue=~"codeintel_index_jobs|batch_spec_workspace_execution_jobs"})
Owner: platform
executor_api_5xx_ratio
executor: share of executor API requests answered with 5xx
Descriptions
- warning: executor: share of executor API requests answered with 5xx above 5% for 15m
Next steps
- Read the web logs for errors on
/.executors/routes; git requests are served from the repo nodes, so check the repo dashboard too. - Upload failures of batch step results can come from the blob store: check the blob dashboard.
- Panel: share of executor API requests answered with 5xx on the Sourcegull: executor dashboard.
Query
(sum(rate(sourcegull_http_requests_total{role=~"web|all",route=~"/.executors/.*",status=~"5.."}[15m])) or 0 * sum(rate(sourcegull_http_requests_total{role=~"web|all",route=~"/.executors/.*"}[15m])))
/ sum(rate(sourcegull_http_requests_total{role=~"web|all",route=~"/.executors/.*"}[15m]))
Owner: platform
blob_error_ratio
blob: share of blob requests answered with 5xx
Descriptions
- warning: blob: share of blob requests answered with 5xx above 1% for 10m
- critical: blob: share of blob requests answered with 5xx above 10% for 10m
Next steps
- Read the blob role's logs for
blob store request failed. - A full or read-only volume is the usual cause: check the free space of the blob volume (Helm
blobstore.persistence.size). - Panel: share of blob requests answered with 5xx on the Sourcegull: blob dashboard.
Query
(sum(rate(sourcegull_blob_requests_total{role=~"blob|all",status=~"5.."}[10m])) or 0 * sum(rate(sourcegull_blob_requests_total{role=~"blob|all"}[10m])))
/ sum(rate(sourcegull_blob_requests_total{role=~"blob|all"}[10m]))
Owner: platform
blob_instance_up
blob: instances answering Prometheus scrapes
Descriptions
- critical: blob: instances answering Prometheus scrapes below 1 for 5m
1 while Prometheus can scrape the instance's internal listener (:6060), 0 when it cannot.
Next steps
- Check the blob pod or container (
kubectl get pods -l app.kubernetes.io/component=blob,docker compose ps blob) and its logs. - While it is down, SCIP uploads, bulk change file uploads and search job downloads fail.
- Panel: instances answering Prometheus scrapes on the Sourcegull: blob dashboard.
Query
up{role=~"blob|all"}
Owner: platform
postgres_postgres_up
postgres: workers reaching Postgres
Descriptions
- critical: postgres: workers reaching Postgres below 1 for 5m
1 when the last metrics collection by a worker (every 30 s) reached Postgres, else 0.
Next steps
- Check that Postgres runs and accepts connections (
pg_isready), and its logs (disk full, too many connections, crash recovery). - Check
SOURCEGULL_DATABASE_URLand the network path (Kubernetes NetworkPolicy, external database firewall). - All roles need Postgres: expect web, worker and repo alerts until it is back.
- Panel: workers reaching Postgres on the Sourcegull: postgres dashboard.
Query
max(sourcegull_postgres_up)
Owner: platform
postgres_connection_saturation
postgres: share of max_connections in use by Sourcegull's database
Descriptions
- warning: postgres: share of max_connections in use by Sourcegull's database above 80% for 5m
- critical: postgres: share of max_connections in use by Sourcegull's database above 95% for 5m
Next steps
- Each Sourcegull process opens a pool per role; scaling out web or worker replicas multiplies connections. Compare the pools panel below with
max_connections. - Raise
max_connectionsin Postgres (and its memory accordingly), or put PgBouncer in transaction mode in front of it. - Lower the pool sizes (
SOURCEGULL_DB_MAX_CONNECTIONS,SOURCEGULL_DB_WORKER_MAX_CONNECTIONS) of roles that hold many idle connections. - Panel: share of max_connections in use by Sourcegull's database on the Sourcegull: postgres dashboard.
Query
sum(max by (state) (sourcegull_postgres_connections))
/ max(sourcegull_postgres_max_connections)
Owner: platform
postgres_oldest_transaction
postgres: age of the oldest open transaction
Descriptions
- warning: postgres: age of the oldest open transaction above 30m for 5m
Next steps
- Find it:
SELECT pid, usename, application_name, state, xact_start, query FROM pg_stat_activity WHERE xact_start IS NOT NULL ORDER BY xact_start LIMIT 5;. Sourcegull's connections name their role inapplication_name. - Long transactions block vacuum and can hold locks other queries wait on. End it with
SELECT pg_terminate_backend(<pid>);if it is stuck. - Schema migrations run in a transaction and can legitimately take long during an upgrade.
- Panel: age of the oldest open transaction on the Sourcegull: postgres dashboard.
Query
max(sourcegull_postgres_oldest_transaction_seconds)
Owner: platform
postgres_pool_saturation
postgres: share of the connection pool in use by process
Descriptions
- warning: postgres: share of the connection pool in use by process above 90% for 15m
Next steps
- Requests wait for a connection when the pool is exhausted: raise the pool size (
SOURCEGULL_DB_MAX_CONNECTIONS, orSOURCEGULL_DB_WORKER_MAX_CONNECTIONSfor theworkerpool) if Postgres has spare connections (see connection saturation). - A pool that stays full while traffic is normal points to slow queries or long transactions: check the oldest transaction panel and the slow request logs.
- Panel: share of the connection pool in use by process on the Sourcegull: postgres dashboard.
Query
max by (role, instance, pool) (sourcegull_db_pool_connections{state="in_use"} / ignoring(state) sourcegull_db_pool_connections{state="max"})
Owner: platform