From 3c41dea48ff86fe76f4a59099764caaa38c91f42 Mon Sep 17 00:00:00 2001 From: YueGuobin Date: Mon, 15 Jun 2026 23:43:41 +0800 Subject: [PATCH] Replace SELECT 1 warmup with full database file read to warm OS page cache Reading the entire DB file into OS page cache eliminates the 8-14s cold-start penalty on the first ORM query (users/templates/api_keys). Previous SELECT 1 only warmed the connection pool, not the file cache. --- gns3server/db/tasks.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/gns3server/db/tasks.py b/gns3server/db/tasks.py index 06816d584..c7855fc3d 100644 --- a/gns3server/db/tasks.py +++ b/gns3server/db/tasks.py @@ -99,14 +99,17 @@ async def connect_to_db(app: FastAPI) -> None: return row[0] if row else "unknown" wal_mode = await _verify_conn.run_sync(_check_wal) log.info(f"SQLite journal mode: {wal_mode} {'✅' if wal_mode and wal_mode.upper() == 'WAL' else '❌ will cause database contention'}") - # Warm up the connection pool and ORM cache so the first API request - # doesn't pay the cold-start penalty (observed: 6-8s first DB query) - async with engine.connect() as _warmup: - def _warmup_query(conn): - from sqlalchemy import text - conn.execute(text("SELECT 1")) - await _warmup.run_sync(_warmup_query) - log.info("Database connection pool warmed up") + # Warm up the OS page cache by reading the entire database file. + # The first API query suffers 8-14s cold-start penalty when the file + # isn't in cache (SQLite + OS page cache combined). + try: + db_file_size = os.path.getsize(db_path) + with open(db_path, "rb") as f: + while f.read(1024 * 1024): # 1MB chunks + pass + log.info(f"Database warmed up ({db_file_size / 1024:.0f} KB)") + except OSError as e: + log.warning(f"Could not warm up database file: {e}") alembic_cfg = config.Config() alembic_cfg.set_main_option("script_location", "gns3server:db_migrations") #alembic_cfg.set_main_option('sqlalchemy.url', db_url)