new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Supabase · all subjects

platform

492 notes in this subject, read out of this brain and free to use. This is page 2 of 9.

Regex escaping reserved characters

Use backslash to escape reserved regex characters. For example: \. is interpreted as a period . instead of as a wildcard. Example: match(event_message, 'hello world\.').

Example: Query Postgres logs with detailed attributes

Example query to retrieve Postgres logs with error severity and user name: ```sql select event_message, log_attributes['parsed.error_severity'] as error_severity, log_attributes['parsed.user_name'] as user_name from logs where source = 'postgres_logs' limit 100; ```

Example: Query edge logs by method, path, and status

Example query to retrieve request method, path, and status from edge logs: ```sql select log_attributes['request.method'] as method, log_attributes['request.path'] as path, log_attributes['response.status_code'] as status from logs where source = 'edge_logs' limit 100; ```

Timestamp is UTC and ISO-8601 formatted

The timestamp column is a DateTime64 value in UTC, formatted as an ISO-8601 string like 2026-06-22T09:34:06.215000. You can order and compare it directly without needing conversion functions. In the Logs Explorer the selected time range is applied automatically, so filtering on timestamp by hand is rarely needed.

ClickHouse logs table structure

The Logs Explorer runs on ClickHouse. Every log line from every source is one row in a single logs table. The table contains a source column to tag which service the log came from, a log_attributes map containing structured fields, and an event_message column containing the raw line. Filter by source to scope a query to one service.

Accessing log_attributes map fields

Structured fields live in the log_attributes map. Read a field using bracket access with the full dotted key. There are no unnesting joins required. The key keeps the full dotted path with the metadata root dropped. For example, metadata.request.cf.country in BigQuery is log_attributes['request.cf.country'] in ClickHouse. Keep the full prefix rather than shortening it.

Logs table columns and structure

The logs table contains the following columns: id (unique log identifier), timestamp (time the event was recorded, a DateTime64 value in UTC formatted as ISO-8601 string like 2026-06-22T09:34:06.215000), event_message (the log's message), severity_text (log level when the source sets one), source (the service the log came from), and log_attributes (structured per-source fields keyed by dotted path).

Discover log_attributes keys from recent rows

Do not guess keys in log_attributes. Discover the keys a source sets from recent rows using: select arrayJoin(mapKeys(log_attributes)) as key, count() as n from logs where source = 'postgres_logs' group by key order by n desc limit 100;

log_attributes map values are always strings

Map values in log_attributes are always strings. To compare or aggregate a numeric field, wrap it in toInt32OrZero, which returns 0 for a missing or non-numeric value.

Use narrow time range for log queries

Keep the time range tight when querying logs. Querying a very large range risks timeouts, especially for Enterprise customers with long retention, because of the extra data scanned.

W3C Trace Context standard support for tracing SDKs

Because the headers follow the W3C standard, any compliant tracing SDK such as OpenTelemetry, Sentry, Datadog, or Honeycomb can pick up the trace on the server side, including in self-hosted collectors.

JavaScript SDK trace header security domain restrictions

For security, trace headers are only attached to requests targeting Supabase domains (*.supabase.co, *.supabase.in, and localhost for local development). Third-party hosts called through a custom fetch are never tagged.

JavaScript SDK trace propagation troubleshooting checklist

If trace_id is missing from Supabase logs, check these in order: (1) The tracing runtime isn't loaded (version 2.112.0+) - tracePropagation is enabled but entry point never imports '@supabase/supabase-js/tracing', SDK logs a one-time console warning and sends requests without trace headers; (2) No active span at request time - SDK reads current context, if supabase.from() is called outside tracer.startActiveSpan() there's nothing to propagate; (3) @opentelemetry/api is not installed in the app making the request; (4) No TracerProvider registered - @opentelemetry/api defaults to a noop provider; (5) The upstream trace is not sampled - by default SDK respects sampling decisions, set respectSamplingDecision: false to propagate every request; (6) Calling a non-Supabase host through custom fetch - trace headers only attached to Supabase domains; (7) Using the CDN (UMD) build - trace propagation isn't available there.

Vendor tracing SDK compatibility with Supabase trace propagation

Many tracing SDKs are built on top of OpenTelemetry and work with Supabase trace propagation as long as a W3C-compliant propagator is registered. Some vendor SDKs inject only their proprietary headers by default and need extra configuration to also emit the standard traceparent header. Check the vendor's OTel integration docs for exact setup.

Correlating Supabase logs with external traces via trace_id

If Supabase logs are forwarded to a third-party backend via Log Drains, you can join Supabase logs to your own client and server traces using the shared trace_id. This is especially useful for self-hosted setups where you already operate your own OpenTelemetry collector — Supabase logs become first-class citizens in your existing tracing UI.

Supabase logs trace_id locations

After trace context is flowing through, the trace_id appears in API Gateway logs (every request to PostgREST, Auth, Storage, and Realtime) and Edge Function logs (invocations and any structured logs emitted from within the function).

Client-side tracing with W3C Trace Context headers

The Supabase JS, Swift, and Dart SDKs can attach W3C Trace Context headers (traceparent, tracestate, baggage) to outgoing requests. The resulting trace_id flows through Supabase services and appears in API Gateway and Edge Function logs, enabling correlation of client-side spans with server-side logs end-to-end across the network boundary.

Dart SDK trace header security domain restrictions

Headers are only injected on requests targeting Supabase hosts (*.supabase.co, *.supabase.in, project host, and loopback addresses for local development). Third-party hosts never receive trace headers.

Per-product debugging resources

Database — Debugging and monitoring; Auth — Error codes; Storage — Debugging; Edge Functions — Local debugging. Each Supabase product has its own debugging resources to use as a starting point when the error originates in a specific service.

Debugging completion criterion

Debugging is complete only once you have re-run the failing operation, confirmed it succeeds, and checked that the layer's logs show a clean result.

Reading logs strategy

Once you know the layer, query that layer's log source directly rather than scanning everything. Pick one source, bound the time window, and select only the fields you need. When a query comes up empty, widen along an anchor such as a timestamp, request ID, or error code to follow the same request into the adjacent source instead of broadening into an unfiltered scan. A wide, unfiltered query across every source buries the one line you need and costs more in scanned data on paid projects.

Debugging methodology: evidence-based approach

Debug by evidence, not by guessing. A Supabase error almost always surfaces at one layer but originates at another. The fastest path to a fix is finding where the problem is, not pattern-matching the symptom. Retrying a failed request rarely helps; isolating the layer does.

Five-step debugging process

1. Reproduce the issue and read the error precisely, capturing exact status code, error code, and full message. Remember that in supabase-js, errors are returned not thrown—check the error field in the {data, error} response object. 2. Locate the failing layer using the request stack and error codes. 3. Gather evidence for that layer by querying its logs, running security and performance advisors, and inspecting the schema. 4. Isolate the cause using the troubleshooting guide for that layer and confirm your hypothesis against evidence. 5. Apply the fix, re-run the exact operation that failed, and verify it succeeds and the log line is clean.

Request stack layers and log sources

Requests pass through multiple layers: Client (supabase-js/SSR) → Edge/API gateway (edge_logs) → one of four services in parallel: PostgREST (postgrest_logs), GoTrue Auth (auth_logs), Storage API (storage_logs), or Realtime (realtime_logs). PostgREST, GoTrue, and Storage each reach the database independently through Supavisor connection pooler (supavisor_logs) → Postgres (postgres_logs). Edge Functions sit outside this stack and log to function_edge_logs for HTTP requests and function_logs for console output. Errors propagate upward, so the layer that reports an error is often not the layer that caused it.

Storing credentials securely in Android development

Never commit local.properties to version control. Add it to .gitignore. Store SUPABASE_PUBLISHABLE_KEY, SUPABASE_URL, and other secrets in local.properties at the project root (same level as build.gradle). Load these values using Properties object in build.gradle and expose them through buildConfigField to BuildConfig.

Datadog Remapper for log level

Use a Remapper in Datadog to set the log level from the fields: `metadata.parsed.error_severity, metadata.level`

Loki log drain configuration

Logs are formatted and sent to the Loki HTTP push API. The log source and product name are used as stream labels. The `event_message` and `timestamp` fields are dropped from events to avoid duplicate data. Events are batched with a maximum of 250 events per request. Required configuration: URL (the Loki push endpoint, e.g., `https://my-logs.grafana.net/loki/api/v1/push`), Username (optional, required for Grafana Cloud and other authenticated Loki instances), Password (optional, required for Grafana Cloud and other authenticated Loki instances), and Headers (optional additional headers). Loki must be configured to accept structured metadata, with maximum structured metadata fields set to at least 500 to accommodate large log event payloads.

Sentry log drain configuration

Logs are sent to Sentry's Logging product. All log event fields are attached as Sentry log attributes, which can be used for filtering and grouping with no cardinality limits on the number of attributes. Required configuration: DSN (Sentry project DSN in the format `{PROTOCOL}://{PUBLIC_KEY}@{HOST}/{PROJECT_ID}`). Steps: get the DSN from Sentry project settings, create the drain in Project Settings > Log Drains, and watch incoming logs on the Sentry Logs page. Ingesting Supabase logs as Sentry errors is not supported. If self-hosting Sentry, Sentry Logs requires self-hosted version 25.9.0 or later.

Datadog Grok parser for JSON conversion

Use a Grok parser in Datadog to convert stringified JSON to structured JSON on the `json` field with the pattern: `%{data::json}`

HTTP destination batching

HTTP destinations receive logs as batched POST requests with a maximum of 250 events or 1-second intervals, whichever comes first.

Datadog log drain configuration

Datadog log drains send logs batched and with Gzip compression. Each event's log source is mapped to the `service` field, and the source is set to `Supabase`. The payload message is a JSON string of the raw log event, prefixed with the event timestamp. Required configuration: API Key (from Datadog Organization Settings) and Region (the Datadog site the account uses: US1, US3, US5, EU, AP1, AP2, or US1-FED). Steps: generate an API key in the Datadog dashboard, create the drain in Project Settings > Log Drains, and watch incoming events on the Datadog Logs page.

Axiom log drain configuration

Logs are sent to an Axiom dataset as JSON, with the timestamp adjusted for Axiom's ingestion format. Required configuration: Dataset Name (name of the target dataset in Axiom) and API Token (an Axiom API token with ingest permissions on the dataset). Steps: create a dataset in Axiom Console under Datasets, generate an API token with ingest access, create the drain in Project Settings > Log Drains, and watch incoming events in the Axiom Console Stream panel.

Datadog Grok parser for log timestamp extraction

Use a Grok parser in Datadog to extract the timestamp into a `date` field with the pattern: `%{date("yyyy-MM-dd'T'HH:mm:ss.SSSSSSZZ"):date}`

OpenTelemetry (OTLP) log drain configuration

OpenTelemetry logs are sent to any OTLP-compatible endpoint using the OpenTelemetry Protocol over HTTP with Protocol Buffers encoding, following the OpenTelemetry Logs specification. Required configuration: Endpoint (full URL of OTLP HTTP endpoint, typically ends in `/v1/logs`), Protocol (`http/protobuf` is the only supported protocol), Gzip (enable to reduce bandwidth, recommended), and Headers (optional authentication headers). The OTLP endpoint must accept logs at the `/v1/logs` path with `application/x-protobuf` content type. Compatible platforms include OpenTelemetry Collector, Grafana Cloud, New Relic, Honeycomb, Datadog (OTLP ingestion), Elastic, and any other OTLP-compatible observability tool.

OpenTelemetry Collector OTLP configuration example

Example OpenTelemetry Collector configuration with OTLP HTTP receiver: ```yaml receivers: otlp: protocols: http: endpoint: 0.0.0.0:4318 processors: batch: exporters: logging: loglevel: debug service: pipelines: logs: receivers: [otlp] processors: [batch] exporters: [logging] ``` Create a log drain in Project Settings > Log Drains with the endpoint set to `https://your-collector:4318/v1/logs`.

Log Drains availability and location

Log drains are only available for customers on Pro, Team, and Enterprise Plans. Log drains can be accessed in the dashboard under Project Settings > Log Drains.

Custom endpoint configuration for log drains

Custom endpoint log drains require: URL (http:// or https://), HTTP Version (HTTP/1 or HTTP/2), Gzip option (enable to compress the payload), and Headers (optional key/value pairs for authentication or routing). Both HTTP/1 and HTTP/2 are supported. Logs are delivered as a JSON array via HTTP POST. Custom headers can be added to every request. Requests to custom endpoints are currently unsigned; signed requests are coming in a future release.

Syslog log drain configuration

Logs are forwarded to a remote Syslog receiver using TCP or TLS, adhering to RFC 5424. Required configuration: Host (hostname or IP address of the Syslog receiver), Port (port of the Syslog receiver, 0–65535), and TLS (enable to connect via SSL/TLS instead of plain TCP). Optional configuration: Structured Data (static RFC 5424 structured data included in every log frame, e.g., `[exampleSDID@32473 iut="3"]`) and Cipher Key (base64-encoded 32-byte key for AES-256-GCM encryption of the log body). TLS-only options: CA Certificate (PEM-encoded CA certificate for server verification, falls back to system CA bundle if omitted), Client Certificate (PEM-encoded client certificate for mutual TLS/mTLS), and Client Key (PEM-encoded client private key, required when a client certificate is provided).

OTLP authentication methods

Different OTLP platforms use different authentication methods. Add the appropriate header to the drain configuration: API Key uses `X-API-Key: your-api-key`, Bearer Token uses `Authorization: Bearer your-token`, and Basic Auth uses `Authorization: Basic base64(username:password)`.

Log Drains capabilities

Log drains can route Supabase logs (Postgres, Auth, Storage, Edge Functions, and more) to any observability platform. They can combine Supabase logs with application-level traces, archive logs to S3 for long-term retention and compliance, and build alerts and dashboards on top of Supabase log data in preferred vendors.

Last9 log drain configuration

Logs are sent to Last9 using its OpenTelemetry-native ingestion endpoint. Required configuration: Region (Last9 cluster region: US West 1 or AP South 1), Username (from the Last9 OTEL integration panel), and Password (from the Last9 OTEL integration panel). Steps: in the Last9 dashboard, open the OTEL integration panel and note the region, username, and password, then create the drain in Project Settings > Log Drains.

Log field reference documentation structure

The Supabase logs field reference is organized by source type with tabs for each available source. Each source tab contains a table showing the Path and Type of each available field. Nested keys require unnesting joins to access.

Log sources available in Supabase

Supabase provides logs for multiple sources including edge_logs and other sources. The full list of available log sources is defined in logConstants.schemas with each source having a reference identifier and display name.

Accessing nested keys in Supabase logs

To access nested keys in Supabase logs, you need to perform unnesting joins as documented in the advanced log filtering guide.

Metrics API beta status and limitations

The Metrics API is currently in beta. Metric names and labels might evolve as the dataset expands. The feature is not available in self-hosted Supabase instances.

Metrics API use cases

The Metrics API enables streaming of database CPU, IO, WAL, connection, and query stats into Prometheus-compatible systems. It allows combining Supabase metrics with application signals in Grafana, Datadog, or other observability vendors. Users can reuse the supabase-grafana dashboard JSON to bootstrap over 200 ready-made charts and build custom alerting policies for right-sizing, saturation detection, index regression, and more.

Metrics API overview

Every Supabase project exposes a Prometheus-compatible Metrics API endpoint that surfaces approximately 200 Postgres performance and health series. This can be scraped into any observability stack to power custom dashboards, alerting rules, or long-term retention beyond what Supabase Studio provides.

Supabase Grafana dashboard repository

The supabase-grafana GitHub repository contains dashboard JSON and alert examples for monitoring Supabase metrics with Grafana.

ClickHouse log query field access syntax

Read fields in ClickHouse log queries with bracket access, keeping the full dotted key (e.g., log_attributes['request.path'] rather than path). Wrap numeric values in toInt32OrZero(...) which returns 0 for missing or non-numeric values. Use count() rather than count(*).

Logs Explorer uses ClickHouse engine

The Logs Explorer runs on ClickHouse. Every log line from every source is a single row in the logs table, tagged by a source column. Structured fields live in a log_attributes map as strings, and the raw line is in event_message. ClickHouse has been the default engine since June 2026; projects created before use BigQuery.

Query failing API requests example

To find failing API requests, use: select timestamp, toInt32OrZero(log_attributes['response.status_code']) as status, log_attributes['request.path'] as path from logs where source = 'edge_logs' and toInt32OrZero(log_attributes['response.status_code']) >= 400 order by timestamp desc limit 100;

Log retention based on pricing plan

Log retention in Supabase is based on your project's pricing plan. Refer to the Manage Logs usage documentation for details on how logs usage is billed.

Available log sources in Logs Explorer

The Logs Explorer exposes logs from the following sources: auth_logs (GoTrue authentication/authorization), edge_logs (edge network requests/responses), function_edge_logs (edge function network requests/responses), function_logs (edge function console logging), postgres_logs (database statements), realtime_logs (realtime client connections), storage_logs (object upload/retrieval).

Discover ClickHouse log_attributes keys

To discover real log_attributes keys, do not guess. A missing key returns an empty string rather than an error, making wrong keys produce empty results instead of failures. Use: select arrayJoin(mapKeys(log_attributes)) as key, count() as n from logs where source = 'postgres_logs' group by key order by n desc limit 100; Alternatively, read event_message which always holds the full line.

Best practice: avoid selecting large nested objects in logs

Avoid selecting large nested objects in log queries. Selecting individual values instead of whole objects improves query speed. Do not use: select timestamp, log_attributes from logs; Instead use: select timestamp, log_attributes['request.method'] as method from logs;

Best practice: query one log source at a time

Query one source at a time. Identify which service owns the problem from the error or status code first, then query only that source. Scanning every source at once buries the signal and scans far more data than necessary.

Best practice: follow requests across log sources with anchors

Once a query gives you an anchor such as a timestamp, request ID, or SQL state, filter the adjacent source by that anchor to correlate the request across layers (e.g., edge_logs to postgres_logs), instead of re-scanning each source from scratch.

Logs Explorer result row limitation

The Logs Explorer has a maximum of 1000 rows per run. Use LIMIT to optimize queries by reducing the number of rows returned.

Best practice: include timestamp filter in log queries

Include a filter over the timestamp when querying logs. For Enterprise customers with large retention ranges, querying entire log history runs the risk of timeouts due to the time required to scan the larger dataset.

Supabase Metrics API is vendor-agnostic and Prometheus-compatible

The Supabase Metrics API can be ingested by any collector that can scrape a Prometheus text endpoint over HTTPS. It works with AWS Managed Prometheus, Grafana Mimir, VictoriaMetrics, Thanos, and other Prometheus-compatible systems.

Give your agent this brain