Migrating v2 SQLite to v3
The native v3 server recognizes a v2 SQLite database before opening the v3
store. The normal v2 launch command can keep --persistence db, --data-dir,
a file-backed --dsn sqlite://PATH?mode=rwc, and --update-channel staging.
Keep the existing GPROXY_MASTER_KEY if the source database is encrypted.
Do not combine this upgrade with a master-key rotation.
Before upgrading
Section titled “Before upgrading”- Keep a copy of the currently installed v2 executable and its launch settings. Existing v2 self-updaters replace that executable without retaining it. The v3 startup migration cannot recover an executable already removed by v2.
- Stop other processes or instances using the database. The native entrypoint reserves its listening port before touching the database, and migration requires an exclusive SQLite lock.
- Allow disk space for a complete source backup, a migrated working database, and its standalone cutover snapshot.
- PostgreSQL, MySQL, remote libSQL, v1 databases and nonstandard SQLite DSNs are not automatic-upgrade inputs. Export/migrate them explicitly first. For a complete v2 to v4 migration, use the unified offline migration bridge.
What startup does
Section titled “What startup does”- Lock migration so only one process can upgrade the database.
- Create a private
gproxy-v2-backup-TIMESTAMP-PIDdirectory beside the database. - Exclusively lock SQLite, checkpoint WAL, then copy the original database
to
gproxy-v2.dbin that directory. - Import supported configuration, recoverable secrets, raw usage and upstream/
downstream request logs into a new v3 database under
candidate/. - Verify import counts, SQLite integrity, references, runtime control state, usage row count and the exact total settled cost.
- Flush and atomically replace the configured database only after validation.
Preserve the backup and
report.txt; restarting v3 does not reimport it.
Universal (*) route grants are preserved for organizations, teams and users.
Historical usage migration preserves only the retained usages detail rows.
v3 rebuilds its hourly aggregates from those rows; v2 usage rollups, daily
credential statistics and historical quota cycles are not imported. History
whose details were already deleted by v2 retention therefore does not appear
in v3 statistics. These source tables remain in the complete v2 backup.
Credential health snapshots, tokenizer caches and Codex task bindings are also
not imported. report.txt lists each populated skipped table, its row count
and the reason it was excluded.
Unknown tables, including populated ones, and v2 rate-limit rules are skipped
and listed in the report. Unsupported route-specific grants, unknown permission
scopes and grants whose subjects no longer exist are also skipped; supported
universal grants are still imported. Skipped policies are not enforced in v3
and can be configured again after the upgrade.
downstream_requests and upstream_requests migrate to request_logs and
wire_logs. Request IDs, timestamps, methods, paths/URLs, status, request
headers and request/response bodies are preserved, including multiple upstream
attempts for one request. A v2 status of zero becomes an unknown response status.
Provider and credential references are remapped; deleted entities get disabled
historical placeholders. Logs are read and written in bounded batches.
v2-only log creation/update timestamps and per-attempt latency_ms have no
matching v3 log fields and remain in the backup; v3 derives request duration
from usage details. Audit logs are not imported. Browser and client login
sessions may need to be established again; recoverable API keys are preserved.
Failure and rollback
Section titled “Failure and rollback”Failures before replacement leave the v2 database in place. Inspect the reported
attempt directory and .gproxy-v2-upgrade-blocked beside the database.
The marker prevents a process supervisor from repeatedly copying a failing database and
filling the disk. Correct the cause, then remove only that marker to retry.
Never delete the backup as a retry mechanism.
To roll back, stop v3, retain the current v3 database for investigation, reinstall
your saved v2 executable (or the same official v2 release), and restore the
backup gproxy-v2.db to the configured database path. Move any current -wal
and -shm files aside with the current database before restoring the backup.
Restore the old launch settings and master key, then start v2. Do not run v2
against a migrated v3 database. Usage written after the cutover stays in the
saved v3 database and is not merged back automatically.