Skip to content

fix: [Capacitor] use HTTP NDJSON streaming as default#940

Merged
stevensJourney merged 8 commits into
mainfrom
capacitor-ios-stream
May 5, 2026
Merged

fix: [Capacitor] use HTTP NDJSON streaming as default#940
stevensJourney merged 8 commits into
mainfrom
capacitor-ios-stream

Conversation

@stevensJourney

@stevensJourney stevensJourney commented May 3, 2026

Copy link
Copy Markdown
Collaborator

closes: #904.

The Capacitor SDK currently extends the Web SDK - where we provide some additional functionality tailored to Capacitor ecosystem, such as a SQLite driver based of Capacitor Community SQLite.

Currently: In the Web SDK, and by extension Capacitor SDK, we default to connecting to the PowerSync service via WebSockets which provide binary data payloads. These payloads are passed to our Rust Core via a SQLite query parameter.

The Capacitor Community SQLite library has quite poor performance for handling binary query parameters. See the comment below for a basic benchmark comparison.

The results from benchmarking indicate that connecting to the PowerSync service via an NDJSON HTTP stream provides much better performance. The benefit is that we pass string JSON values to SQLite via Capacitor Community SQLite instead of binary Buffers.

This PR updates the defaults for Capacitor to use NDJSON based HTTP connections by default when using Capacitor Community SQLite. Capacitor apps are also web apps: in order to keep things consistent with the Web SDK, we default to Web Sockets on web. This may bring more confusion than it's worth - the change is currently focussed to only affect the use-case with poor performance issues.

@changeset-bot

changeset-bot Bot commented May 3, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 8818366

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@powersync/capacitor Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

simolus3
simolus3 previously approved these changes May 4, 2026
Comment thread packages/capacitor/src/sync/CapacitorRemote.ts Outdated
@stevensJourney

stevensJourney commented May 5, 2026

Copy link
Copy Markdown
Collaborator Author

In order to get some more context. I did a small benchmark which compared the various connection options' sync time on iOS and Android. The test setup involved measuring the time taken to do an initial sync of 10_000 basic rows.

[Update] The initial test result posted in this comment was incorrect. This comment has been updated with valid values.

The general sync performance for Capacitor on iOS is terrible when using Buffers. Android also has a substantial performance hit when using Buffers - however the impact in iOS is orders of magnitude worse than in Android.

Legend:

HTTP Default refferes to the new default of NDJSON over HTTP

Capacitor benchmark results

The differences between Android and IOS are too large to display in the same graph.

Android
image

iOS
image

OPFS seems to have issues on iOS due to opauge origins and security concerns.

Note that the HTTP binary indexed object test uses the method from #905 to pass binary payloads to SQLite.

Kotlin SDK

For a comparison, the same data was synced using the Kotlin SDK. The time observed is in the realm of the NDJSON HTTP results seen above.

image

Summary

While there clearly are general issues when using Buffers, I think for now - using HTTP is the better option.

@stevensJourney stevensJourney changed the title temp: Capacitor: use text streaming on iOS fix: [Capacitor] use HTTP NDJSON streaming as default May 5, 2026
@stevensJourney stevensJourney marked this pull request as ready for review May 5, 2026 12:29
@stevensJourney stevensJourney requested a review from simolus3 May 5, 2026 12:29

@simolus3 simolus3 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy with these changes. There's nothing we can do about binary parameters being so expensive, so switching to text makes sense.

Comment thread packages/capacitor/src/adapter/CapacitorSQLiteAdapter.ts
Comment thread packages/capacitor/src/adapter/CapacitorSQLiteAdapter.ts
@stevensJourney stevensJourney merged commit a656afa into main May 5, 2026
11 of 12 checks passed
@stevensJourney stevensJourney deleted the capacitor-ios-stream branch May 5, 2026 13:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Capacitor iOS crashes on line_binary payloads with Error in reading buffer

3 participants