Common issues

SqliteException: Could not load extension or similar

This client-side error or similar typically occurs when PowerSync is used in conjunction with either another SQLite library or the standard system SQLite library. PowerSync is generally not compatible with multiple SQLite sources. If another SQLite library exists in your project dependencies, remove it if it is not required. In some cases, there might be other workarounds. For example, in Flutter projects, we’ve seen this issue with sqflite 2.2.6, but sqflite 2.3.3+1 does not throw the same exception.

Tools

Troubleshooting techniques depend on the type of issue:

  1. Connection issues between client and server: See the tools below.
  2. Expected data not appearing on device: See the tools below.
  3. Data lagging behind on PowerSync Service: Data on the PowerSync Service instance cannot currently directly be inspected. This is something we are investigating.
  4. Writes to the backend database are failing: PowerSync is not actively involved: use normal debugging techniques (server-side logging; client and server-side error tracking).
  5. Updates are slow to sync, or queries run slow: See Performance

Diagnostics app

Access the diagnostics app here: https://diagnostics-app.powersync.com

This is a standalone web app that presents data from the perspective of a specific user. It can be used to:

  • See stats about the user’s local database.
  • Inspect tables, rows and sync buckets on the device.
  • Query the local SQL database.
  • Identify common issues. E.g. too many sync buckets.

See the Readme for further details.

Instance Logs

See Monitoring and Alerting.

Diagnostics API

We also provide diagnostics via an API on the client. Examples include the connection status, last completed sync time, and local upload queue size.

If for example, a change appears to be missing on the client, you can check if the last completed sync time is greater than the time the change occurred.

The JavaScript SDKs (React Native, web) also log the contents of sync bucket changes to console.debug if verbose logging is enabled. This should log which PUT/PATCH/DELETE operations have been applied from the server.

Inspect local SQLite Database

Another useful debugging tool as a developer is to open the SQLite file and inspect the contents. We share an example of how to do this on iOS from macOS in this video:

Essentially, run the following to grab the SQLite file:

find ~/Library/Developer/CoreSimulator/Devices -name "mydb.sqlite"

The diagnostics app and several of our demo apps also contain a SQL console view to inspect the local database contents. Consider implementing similar functionality in your app.

See an example here.

Client-side Logging

Our client SDKs support logging to troubleshoot issues. Logging is enabled by default in our Flutter SDK. See the following usage examples for enabling logging in our SDKs:

Performance

When running into issues with data sync performance, first review our expected Performance and Limits.

These are some common pointers when it comes to diagnosing and understanding performance issues:

  1. You will notice differences in performance based on the row size (think 100 byte rows vs 8KB rows)
  2. The initial sync on a client can take a while in cases where the operations history is large. See Compacting Buckets to optimizes sync performance.
  3. You can get big performance gains by using transactions & batching as explained in this blog post.

JavaScript Web: Logging queries on the performance timeline

Enabling the debugMode flag in the JavaScript Web SDK logs all SQL queries on the Performance timeline in Chrome’s Developer Tools (after recording). This can help identify slow-running queries.

This includes:

  • PowerSync queries from client code.
  • Internal statements from PowerSync, including queries saving sync data, and begin/commit statements.

This excludes:

  • The time waiting for the global transaction lock, but includes all overhead in worker communication. This means you won’t see concurrent queries in most cases.
  • Internal statements from powersync-sqlite-core.

Enable this mode when instantiating PowerSyncDatabse:

export const db = new PowerSyncDatabase({
  schema: AppSchema,
  database: {
    dbFilename: 'powersync.db',
    debugMode: true // Defaults to false. To enable in development builds, use
      // debugMode: process.env.NODE_ENV !== 'production'
  }
});