Replies: 2 comments 2 replies
-
|
I ran this discussion through a couple rounds of Fable and gpt-5.5 against targeted past tickets and issues. I sifted through the suggestions and I think these points hold. On the first open question. I'd go the other way and keep all pre-stream rejections out of this counter, including Pre-stream failures come up fairly often in support ( |
Beta Was this translation helpful? Give feedback.
-
|
I took another look at the connection lifecycle for the transports. The above did make sense, but the actual implementation does need a bit of work. For a minimal pass, I think we can get away with adding one additional value to Accepted stream success rate would be Here is the connection lifecycle outcome matrix, as I see it:
I think we defer auth and validation rejections, since it's more HTTP/request level concern, less sync-lifecycle concern + they fail before the code knows it's a sync attempt:
To count these as sync rejections we'd need route-aware hooks reaching into middleware/acceptor, which seems out of scope for a first pass. But I think this is where a separate counter would make more sense (something like: |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Background
The service already exposes sync API metrics through a Prometheus endpoint (internally via OpenTelemetry libs):
powersync_concurrent_connectionspowersync_data_synced_bytes_totalpowersync_data_sent_bytes_totalpowersync_operations_synced_totalThese metrics show current load and throughput, but they do not make it easy to answer:
The sync routes already compute a best-effort
close_reasonfor logs, so the main missing piece is a low-cardinality counter that records one final outcome per connection. Scanning the logs is a workaround sometimes used to get error rates, but it's not an efficient method for that, and requires custom work to generate alerts.Proposal
Add a monotonic counter:
Description:
Record exactly one increment when a sync stream finishes after it has been accepted as a sync connection. This should be paired with the existing
powersync_concurrent_connectionsdecrement sites so that each opened sync connection produces one final outcome.Recommended labels:
outcomesuccess,errorclose_reasonerror_codenone,other,PSYNC_*nonefor success, a PowerSync error code when available, andotherfor non-ServiceError failures.transporthttp_stream,rsocket/sync/streamHTTP from RSocket reactive streams.Example Prometheus output:
Close reason values
This should match what is produced in the logs, but we may need to reconsider the specific values for both.
Example values:
client_closedservice_closedprocess_shutdownstream_errorservice_unavailableno_sync_configunknownSuccess and error classification
Classify
outcomefrom the final stream state:successwhen the stream finishes without a thrown or reported error. This must specifically include cases like auth expiry, switching sync config, shutting down the process, or client disconnect.errorwhen the stream returns aServiceError, throws a non-service exception, or is rejected before streaming due to service state.Suggested
error_codehandling:ServiceError, useerror.errorData.code. This includesInternalServerError.other.none.Client disconnects should normally be
outcome="success"withclose_reason="client_closed"unless the server was already handling a stream error. This keeps normal mobile reconnect behavior from inflating error rates.For error codes, we may need to revisit some existing error handling. For example, I've seen
PSYNC_S2403errors wrapped in a genericPSYNC_S2001- we should remove that wrapping.Also consider:
PSYNC_S2403into separate errors for timeout while loading data vs timeout while computing checksums.Query examples
Success rate over five minutes:
Error rate by PowerSync error code:
Close reasons by transport:
Cardinality guidance
Do not add
client_id,user_id, sync config id, bucket name, request parameters, or raw exception messages as labels. Those values are high-cardinality and belong in logs or traces instead.The proposed label set should stay bounded:
outcome: 2 values.transport: 2 values initially.close_reason: small enum controlled by code.error_code: bounded by the PowerSync error-code enum plusnoneandunknown.Open questions
powersync_concurrent_connectionsincrements be counted by this metric? The recommendation is yes for sync-specific service-state rejections, such asPSYNC_S2003andPSYNC_S2302, because they are connection attempts from the user's perspective. Authentication and validation failures may be better represented by a separate API request metric.close_reason="service_closed"be split further for auth expiry vs sync config switch? This would be useful if the route can identify those causes reliably without parsing generic stream completion.AI Usage
This proposal was generated by Codex gpt-5.5, reviewed and edited manually.
Beta Was this translation helpful? Give feedback.
All reactions