Storage & persistence¶
The gotime.services.query.persist_trip helper writes, per successful
provider call:
A row in
tripsnormalized to minutes/miles/UTC (always).A best-effort upsert of the source/destination in
locationskeyed on(user_id, nickname)(always).Opt-in — a row in
trip_api_logscontaining the raw provider JSON (JSONB on Postgres). Disabled by default because several providers’ Terms of Service restrict or forbid long-term storage of raw responses; seecompliance.mdfor the per-provider posture and theGOTIME_STORE_RAW_RESPONSES/store_raw=knobs that turn it on.
Choosing a backend¶
SQLite (default):
GOTIME_DATABASE_URL=sqlite:///./gotime.db. Good for local exploration and tests; the trip volume in this project easily fits.PostgreSQL (production): install the extras (
pip install gotime[postgres]) and setGOTIME_DATABASE_URL=postgresql+psycopg2://user:pass@host:5432/db.
The JSON blob column uses SQLAlchemy’s generic JSON type, which maps to
JSONB on Postgres and TEXT on SQLite. No code changes are needed when you
move between backends.
Retention & cost¶
Plan for two kinds of growth:
Row growth: one
tripsrow per API call, plus onetrip_api_logsrow only ifGOTIME_STORE_RAW_RESPONSES=true. A collector that polls every 5 minutes during weekday work hours produces roughly 6,000 normalized rows per year. Cheap.Blob growth (opt-in path only):
raw_jsonpayloads are 2–10 KB each for most providers. The heaviest are Google Directions responses, which can be a few hundred KB when step geometry is requested. Configure providers to return minimal responses (we already default to summary-only where the API supports it).
If you turn on raw-response persistence, pair it with a retention policy
consistent with your chosen providers’ ToS — e.g. 30 days for Google, no
long-term storage for Mapbox/Bing at all. See
compliance.md for the matrix.