sqlite: SQL code runs slower on each iteration in Chrome if ASYNCIFY and IDBFS are used

15 views
Skip to first unread message

leopatras

unread,
Feb 10, 2026, 11:05:14 AMFeb 10
to emscripten-discuss
Hi folks, we ran into an issue that so far all of our SQL tests with sqlite are running slower and slower over time in our ASYNCIFY'd environment on a IDBFS mount...only in Chrome.
FF and Safari are performing with roughly the same times each loop.
Even deleting the DB file in the IDBFS doesn't help, I can revert to the initial loop time only when deleting the indexed DB content.
Running on MEMFS I can't observe this behaviour. Also running without ASYNCIFY I can't observe this behavior..(unfortunately we need both IDBFS and ASYNCIFY)
Is this a known issue ?
Thanks in advance,
Leo

Env : latest sqlite amalgation 3.51.2, latest emscripten 5.0.0,latest Chrome 144.0.7559.133.

emcc flags:

emcc \

          -s MAIN_MODULE=1 \

          -O2 \

          -s EXPORT_ALL=1 \

          -s EXIT_RUNTIME=1 \

          -s ASSERTIONS=1 \

          -s FORCE_FILESYSTEM=1 \

          -s ALLOW_MEMORY_GROWTH=1 \

          -s ASYNCIFY \

          -lidbfs.js \

          -o main.html $(OBJS)

little sqlite demo creating a table, insert 100 rows, delete, drop and remove in each loop.

#include <stdio.h>

#include <stdlib.h>

#include <sys/time.h>

#include <emscripten.h>

#include "sqlite3.h"


EM_JS(char*,addPersistentDirsInt,(),{

  const dirname="/persist";

  try {

    FS.mkdir(dirname);

  } catch(err) {

    console.error("mkdir %o failed:%o",dirname,err);

    return;

  }

  try {

    FS.mount(IDBFS, { autoPersist: true }, dirname);

    console.log("did mount IDBFS to "+dirname);

  } catch (err) {

    console.error("mount(IDBFS,{ autoPersist: true },%o) error:%o",dirname,err);

  }

});



static int callback(void *NotUsed, int argc, char **argv, char **azColName)

{

    NotUsed = 0;

    /*

       int i;

       for (i = 0; i < argc; i++) {

       printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");

       }

       printf("\n");

     */

    return 0;

}


int main(int argc, char **argv)

{

    sqlite3 *db;

    char *err = 0;

    int rc,i,loop;

    struct timeval stop, start;

    addPersistentDirsInt();

    for (loop = 1; loop <= 20; loop++) {

        gettimeofday(&start, NULL);

        remove("/persist/test.db");

        rc = sqlite3_open("/persist/test.db", &db);

        if (rc == SQLITE_OK) {

            rc = sqlite3_exec(db,

                              "CREATE TABLE test (id INTEGER NOT NULL, text VARCHAR(100))",

                              callback, 0, &err);

            if (rc != SQLITE_OK) {

                fprintf(stderr, "SQL error CREATE: %s\n", err);

            }

            for (i = 1; i < 100; i++) {

                char buf[500];

                sprintf(buf, "INSERT INTO test VALUES (%d, 'text%d')", i,

                        i);

                rc = sqlite3_exec(db, buf, callback, 0, &err);

                if (rc != SQLITE_OK) {

                    fprintf(stderr, "SQL error INSERT: %s\n", err);

                }

            }

            rc = sqlite3_exec(db, "SELECT * FROM test", callback, 0, &err);

            if (rc != SQLITE_OK) {

                fprintf(stderr, "SQL error SELECT: %s\n", err);

            }

            rc = sqlite3_exec(db, "DELETE FROM  test", callback, 0, &err);

            if (rc != SQLITE_OK) {

                fprintf(stderr, "SQL error DELETE: %s\n", err);

            }

            rc = sqlite3_exec(db, "DROP TABLE test", callback, 0, &err);

            if (rc != SQLITE_OK) {

                fprintf(stderr, "SQL error DROP: %s\n", err);

            }

            sqlite3_close(db);

            gettimeofday(&stop, NULL);

            printf("loop:%d db ops took %lld msec\n",loop,

                   (stop.tv_sec - start.tv_sec) * 1000000 + stop.tv_usec -

                   start.tv_usec);

        } else {

            fprintf(stderr, "Can't open database: %s\n",

                    sqlite3_errmsg(db));

            sqlite3_close(db);

            return 1;

        }

    }

    return 0;

}


Sam Clegg

unread,
Feb 10, 2026, 2:08:53 PMFeb 10
to emscripte...@googlegroups.com
That does sound rather strange.

Can you also reproduce if you remove `-sMAIN_MODULE=1` and `-sALLOW_MEMORY_GROWTH`?

Is the IDBFS storage growing on each iteration?   Can you tell where the slowdown is happening exactly?   I can't see how it would be related to ASYNCIFY.   Can you also try wth `-sJSPI` instead of `-sASYNCIFY`?

cheers,
sam

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/emscripten-discuss/fb7330e6-399c-4db6-ad83-bbaeafe13c51n%40googlegroups.com.

Alon Zakai

unread,
Feb 10, 2026, 2:25:26 PMFeb 10
to emscripte...@googlegroups.com
On Tue, Feb 10, 2026 at 11:08 AM 'Sam Clegg' via emscripten-discuss <emscripte...@googlegroups.com> wrote:
That does sound rather strange.

Can you also reproduce if you remove `-sMAIN_MODULE=1` and `-sALLOW_MEMORY_GROWTH`?

Is the IDBFS storage growing on each iteration?   Can you tell where the slowdown is happening exactly?

To pinpoint the slowdown, the browser's profiler might help. It could show if it is doing more GC or more computation, and if it is more computation, exactly what code is running there.
 

Leo Schubert

unread,
Feb 10, 2026, 5:33:16 PMFeb 10
to emscripte...@googlegroups.com
Hi Sam,
> Can you also reproduce if you remove `-sMAIN_MODULE=1` and `-sALLOW_MEMORY_GROWTH`?
Same symptoms.
> Is the IDBFS storage growing on each iteration?
No, it stays constant at 8192 bytes.
> Can you also try wth `-sJSPI` instead of `-sASYNCIFY`?
Same symptoms
> Can you tell where the slowdown is happening exactly?
Well I did compile with --profiling and I did record a performance log...
It seems that operations take more time over time (I did focus on the close here), so one shot is some seconds taken before the other one and execution time did double from 0.1msec to 0.2msec
close01.png
close02.png

leopatras

unread,
Feb 23, 2026, 2:41:11 PMFeb 23
to emscripten-discuss
What puzzles me is that the performance recording of a run on IDBFS seems to show only spikes of activity with big pauses in-between.
A run on MEMFS doesn't show this behavior. 
See attached/
Removing ASYNCIFY with IDBFS also doesn't show this behavior.
The question is if this is a chrome bug or an emscripten bug. May I add an emscripten issue for that ?
Regards, Leo

(Spikes of activity with a lot of pauses)
idbfsWithAsyncify.png

(run on MEMFS doesn't show those spikes)
memfsWithAsyncify.png

Alon Zakai

unread,
Feb 23, 2026, 3:59:57 PMFeb 23
to emscripte...@googlegroups.com
> IDBFS seems to show only spikes of activity with big pauses in-between

IDBFS is async - that might explain some of the pauses. Such event callbacks have a minimum latency in milliseconds last I checked, so waiting for many of them can be noticeable. MEMFS, otoh, is sync (at least in the same thread).

Feel free to open an emscripten issue for more investigation if needed.

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages