feat(core): Add Supabase Queues support
Resolves: https://github.com/getsentry/sentry-javascript/issues/14611
This PR adds Supabase Queues support to the Supabase
Sample Events: Link
Instrumented Operations
Producer operations (queue.publish):
-
send- Send a single message -
send_batch- Send multiple messages
Consumer operations (queue.process):
-
pop- Read and delete message -
read- Read message (with visibility timeout) -
receive- Alias forread
Span Attributes
Follows OTEL Messaging Semantic Conventions and Sentry Queue Developer Docs:
-
messaging.destination.name- Queue name -
messaging.message.id- Message ID (frommsg_id) -
messaging.message.retry.count- Retry count (from PGMQ'sread_ct) -
messaging.batch.message_count- Batch size forsend_batch
Distributed Tracing
Producer spans inject sentry-trace and baggage into the message payload under _sentry key. Consumer spans create span links to the producer trace context.
Notes
- Works with both
client.rpc()andclient.schema('pgmq_public').rpc()patterns - Queue operations are detected via RPC function names:
send,send_batch,pop,read,receive - Empty consumer responses (no messages in queue) still create breadcrumbs and spans with
messaging.batch.message_count: 0
size-limit report 📦
| Path | Size | % Change | Change |
|---|---|---|---|
| @sentry/browser | 24.8 kB | - | - |
| @sentry/browser - with treeshaking flags | 23.31 kB | - | - |
| @sentry/browser (incl. Tracing) | 41.54 kB | - | - |
| @sentry/browser (incl. Tracing, Profiling) | 46.13 kB | - | - |
| @sentry/browser (incl. Tracing, Replay) | 79.96 kB | - | - |
| @sentry/browser (incl. Tracing, Replay) - with treeshaking flags | 69.69 kB | - | - |
| @sentry/browser (incl. Tracing, Replay with Canvas) | 84.64 kB | - | - |
| @sentry/browser (incl. Tracing, Replay, Feedback) | 96.88 kB | - | - |
| @sentry/browser (incl. Feedback) | 41.48 kB | - | - |
| @sentry/browser (incl. sendFeedback) | 29.49 kB | - | - |
| @sentry/browser (incl. FeedbackAsync) | 34.47 kB | - | - |
| @sentry/react | 26.52 kB | - | - |
| @sentry/react (incl. Tracing) | 43.74 kB | - | - |
| @sentry/vue | 29.25 kB | - | - |
| @sentry/vue (incl. Tracing) | 43.34 kB | - | - |
| @sentry/svelte | 24.82 kB | - | - |
| CDN Bundle | 27.21 kB | - | - |
| CDN Bundle (incl. Tracing) | 42.21 kB | - | - |
| CDN Bundle (incl. Tracing, Replay) | 78.75 kB | - | - |
| CDN Bundle (incl. Tracing, Replay, Feedback) | 84.2 kB | - | - |
| CDN Bundle - uncompressed | 79.96 kB | - | - |
| CDN Bundle (incl. Tracing) - uncompressed | 125.34 kB | - | - |
| CDN Bundle (incl. Tracing, Replay) - uncompressed | 241.37 kB | - | - |
| CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed | 254.13 kB | - | - |
| @sentry/nextjs (client) | 45.96 kB | - | - |
| @sentry/sveltekit (client) | 41.9 kB | - | - |
| @sentry/node-core | 51.27 kB | -0.01% | -1 B 🔽 |
| @sentry/node | 159.53 kB | - | - |
| @sentry/node - without tracing | 92.85 kB | +0.01% | +1 B 🔺 |
| @sentry/aws-serverless | 108.14 kB | - | - |
@sentry review
On it! We are reviewing the PR and will provide feedback shortly.
PR Description
This pull request introduces instrumentation for Supabase queue operations using pgmq, enabling Sentry to capture spans and breadcrumbs for queue publishing and processing. This provides visibility into asynchronous task execution within Supabase applications.
Click to see more
Key Technical Changes
The key technical changes include: 1) Instrumenting the rpc method of the Supabase client to detect queue operations (send, send_batch, pop). 2) Creating spans for queue publish and process operations, capturing relevant metadata like queue name and message ID. 3) Adding breadcrumbs for queue operations to provide context in Sentry events. 4) Modifying queue messages to inject Sentry trace context for distributed tracing. 5) Adding e2e tests to verify the instrumentation in a Next.js application.
Architecture Decisions
The primary architectural decision involves using Proxy objects to intercept calls to the Supabase client's rpc method and the schema(...).rpc(...) method. This allows for non-intrusive instrumentation without modifying the Supabase client's core code. The trace context is injected directly into the message body to propagate tracing information across queue operations.
Dependencies and Interactions
This integration depends on the @supabase/supabase-js library and interacts with Sentry's tracing and breadcrumb APIs. It also relies on the pgmq extension being enabled in the Supabase database. The integration injects Sentry trace context into queue messages, which requires consumers to be instrumented to extract and continue the trace.
Risk Considerations
Potential risks include: 1) Performance overhead due to the instrumentation, although proxies are generally performant. 2) Incorrectly identifying queue operations, leading to spurious spans. 3) Failure to propagate trace context if consumers are not properly instrumented. 4) Security implications of modifying message bodies, although the injected data is limited to Sentry trace context. 5) The modification of the arguments list in place could lead to unexpected side effects.
Notable Implementation Details
Notable implementation details include: 1) The use of continueTrace to link consumer spans to producer spans. 2) The handling of both rpc and schema(...).rpc(...) calls. 3) The injection of Sentry trace context into the message body. 4) The vendoring of SQL code from the Supabase repository to enable queue access locally.
anybody got eyes on this anymore? 😅
node-overhead report 🧳
Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.
| Scenario | Requests/s | % of Baseline | Prev. Requests/s | Change % |
|---|---|---|---|---|
| GET Baseline | 11,113 | - | 9,276 | +20% |
| GET With Sentry | 2,034 | 18% | 1,699 | +20% |
| GET With Sentry (error only) | 7,848 | 71% | 6,110 | +28% |
| POST Baseline | 1,173 | - | 1,174 | -0% |
| POST With Sentry | 597 | 51% | 587 | +2% |
| POST With Sentry (error only) | 1,036 | 88% | 1,054 | -2% |
| MYSQL Baseline | 4,083 | - | 3,289 | +24% |
| MYSQL With Sentry | 568 | 14% | 421 | +35% |
| MYSQL With Sentry (error only) | 3,380 | 83% | 2,647 | +28% |