From afa7ee77314ff28c92219ab192b34acc2ebcb409 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Thu, 30 Apr 2026 15:54:20 +1200 Subject: [PATCH] perf(sqlite): aggressive PRAGMAs and tmpfs-backed test storage Tune SQLite for high-concurrency test workloads: - synchronous=OFF skips fsync (safe for ephemeral test data only). - 256 MB page cache + 2 GB mmap window cuts read I/O dramatically. - temp_store=MEMORY keeps temporary tables off disk. - busy_timeout to 60s and wal_autocheckpoint to every 10k pages so long write bursts don't fight the checkpointer. - 64 MB WAL size cap. Mount the SQLite docker volume as tmpfs so writes never reach disk. The test DB is wiped between CI runs so durability is irrelevant. Co-Authored-By: Claude Opus 4.7 (1M context) --- app/init/registers.php | 23 +++++++++++++++++++---- docker-compose.yml | 6 ++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/app/init/registers.php b/app/init/registers.php index 6f08d63e39..eff42dad53 100644 --- a/app/init/registers.php +++ b/app/init/registers.php @@ -327,10 +327,20 @@ $register->set('pools', function () { \PDO::ATTR_EMULATE_PREPARES => true, \PDO::ATTR_STRINGIFY_FETCHES => true, ]); + // Tuned for high-concurrency test workloads. WAL allows + // concurrent readers alongside one writer; busy_timeout + // makes contending writers wait instead of failing. + // synchronous=OFF skips fsync — fine for tests, never + // for production data. $pdo->query('PRAGMA journal_mode=WAL'); - $pdo->query('PRAGMA busy_timeout=30000'); + $pdo->query('PRAGMA busy_timeout=60000'); + $pdo->query('PRAGMA synchronous=OFF'); + $pdo->query('PRAGMA temp_store=MEMORY'); + $pdo->query('PRAGMA cache_size=-262144'); // 256 MB page cache + $pdo->query('PRAGMA mmap_size=2147483648'); // 2 GB mmap window + $pdo->query('PRAGMA wal_autocheckpoint=10000'); + $pdo->query('PRAGMA journal_size_limit=67108864'); // 64 MB WAL cap $pdo->query('PRAGMA foreign_keys=ON'); - $pdo->query('PRAGMA synchronous=NORMAL'); return $pdo; }); }, @@ -436,9 +446,14 @@ $register->set('db', function () { $path = System::getEnv('_APP_DB_SQLITE_PATH', '/tmp/appwrite.db'); $pdo = new PDO("sqlite:{$path}", null, null, SQL::getPDOAttributes()); $pdo->query('PRAGMA journal_mode=WAL'); - $pdo->query('PRAGMA busy_timeout=30000'); + $pdo->query('PRAGMA busy_timeout=60000'); + $pdo->query('PRAGMA synchronous=OFF'); + $pdo->query('PRAGMA temp_store=MEMORY'); + $pdo->query('PRAGMA cache_size=-262144'); + $pdo->query('PRAGMA mmap_size=2147483648'); + $pdo->query('PRAGMA wal_autocheckpoint=10000'); + $pdo->query('PRAGMA journal_size_limit=67108864'); $pdo->query('PRAGMA foreign_keys=ON'); - $pdo->query('PRAGMA synchronous=NORMAL'); return $pdo; default: throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Invalid database adapter'); diff --git a/docker-compose.yml b/docker-compose.yml index 4b5f8d1da9..c14a8c14cd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1523,4 +1523,10 @@ volumes: appwrite-builds: appwrite-config: appwrite-models: + # tmpfs-backed so SQLite writes hit RAM rather than the docker volume + # filesystem; safe because the test DB is wiped between runs. appwrite-sqlite: + driver_opts: + type: tmpfs + device: tmpfs + o: size=2g