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

3 views
Skip to first unread message

leopatras

unread,
Feb 10, 2026, 11:05:14 AM (15 hours ago) Feb 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 PM (12 hours ago) Feb 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 PM (12 hours ago) Feb 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 PM (9 hours ago) Feb 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
Reply all
Reply to author
Forward
0 new messages