Documentation navigation

Wayfarer

Hardware and history performance

Use this guide to plan a host for personal location history. The backend in #924 provides three independent reads: chronology pages, a complete map overview of the selected scope, and complete selected-record detail. The map includes all matching records without waiting for chronology pages; detail remains accessible independently of the current filters. Exceptional unresolved time evidence is labelled incomplete, rather than silently discarded. These are backend capabilities; mobile presentation and deployed-client acceptance are separate responsibilities.

The sub-second query-plus-projection target remains unmet for complete multi-year overviews and combined searches. The measured limitations still require explicit maintainer acceptance under #918. The evaluation budget below does not waive that target or promise normal latency.

Representative measurements

These are local synthetic-data observations from 24 October 2026. Times in the table include bearer authentication, MVC routing, database reads, full response projection and buffered JSON through TestServer. They exclude real TCP, TLS and reverse-proxy costs. Query-plus-projection companions in the reports are separate executions and must not be added to, or subtracted from, routed times.

Evidence and read Owner records and selection Measured routed time
Latest correction: complete capture-date overview 2,628,000; worldwide, capture days 2001-01-01–2025-12-31, no text/activity/hour filter Median 6.88 → 4.98 s; three measured reads per configuration after warmup
Earlier: complete UTC overview 210,240 / 1,051,200; whole period, no additional filters Warm 0.248–0.253 / 0.973–1.017 s
Earlier: complete filtered overviews 2,628,000; capture-date range with Notes/address text and/or recurring local 11:00–15:00 Warm 4.21–8.70 s, depending on selection
Earlier: first chronology page 2,628,000; 100 items, full UTC period / recurring hours plus common phrase 0.938–0.988 / 5.146–5.363 s
Earlier: selected detail 2,628,000; one complete 2.3 KB response. Older 1,051,200-record fixture: approximately 1.2 MB long detail 35–49 ms; older long detail 43–51 ms
Earlier: ordinary reads during heavy history work 2,628,000 and 210,240-record history owners; activity catalog and ordinary date-existence reads 30–42 ms

The latest comparison changes only the UTC index’s covered status column. Capture selection uses Europe/Athens as viewer zone and the default worldwide grid of 16; it contains 2,627,999 definite matches and zero uncertain candidates. One early Honolulu event falls on the preceding capture-local date. Complete results agree before/after. The corrected range was 4.94–5.04 s; 27.6% lower median describes this small, fixed-order sample. A single full-period UTC control was slower, 2.59 → 2.87 s, so this is not a general speedup or nonregression guarantee. The latest independent review observed capture reads of 8.55 and 4.62 s at the unchanged implementation head, illustrating variability rather than a new paired estimate. See the committed correction report and latest independent review.

All rows marked earlier predate the status-coverage correction. Smaller broad overview timings come from the independently reviewed #923 implementation. The 2.628-million-record qualification uses distinct Notes and all eleven searchable fields; its text markers match about one record in seven and its common phrase cafe station about half. Notes/address selections use the same combined shipped predicate, not separate field-specific searches. Geography is mostly dense Athens with Tokyo, New York, London and sparse distant records. These distributions and repeated coordinates limit extrapolation to other histories.

In the earlier bounded mixed trial, three heavy overviews completed in 4.00–7.98 s, ten keyed ingestions persisted in 179–508 ms, and independent detail took 43 ms. Two excess attempts received controlled admission 503 responses; a deliberate disconnect cancelled work and released its resources. All 49 measured history reads completed successfully; no natural deadline failure occurred. An earlier independent replay observed an 8.76 s filtered overview and ingestion up to 678 ms. Those samples demonstrate modest mixed use, not sustained throughput or current corrected-index concurrency gains. Sources: earlier scale, detail and mixed-use report, smaller-scale provenance and earlier independent replay.

Measured environment and hardware planning

The test host ran Ubuntu 24.04.5 under Linux/WSL2 on an Intel i7-10700K with 16 logical CPUs and approximately 15.6 GiB RAM. It used Debug assemblies, .NET SDK 10.0.113/runtime 10.0.13 and PostgreSQL 18.6/PostGIS 3.6.4, with shared_buffers=128 MB, work_mem=4 MB, two parallel workers per gather and JIT enabled. Fixture loading and vacuuming preceded prepared reads; OS caches were warm, including first-use observations. No disk-cold or isolated storage-device performance was measured. This shared workstation is a test environment, not a minimum specification or a guarantee for another machine.

The following are planning projections, not measured alternative-host results:

There is no qualified minimum CPU/RAM/SSD specification, Raspberry Pi performance qualification or 25-simultaneous-user guarantee. ARM64 deployment support alone does not supply those results. Production hardware, cold caches, Release builds, network/proxy overhead, sustained writes, percentiles and arbitrary content remain unqualified. The fixture’s storage footprint is not a production sizing formula.

Evaluation budgets, admission and failures

Chronology and overview have a 15-second evaluation budget; selected detail has a separate 30-second budget. Evaluation covers token lookup, SQL, projection and complete buffered JSON before success. Remaining-time SQL timeout is transaction-local, and disconnect cancellation reaches the ongoing work. The budget does not bound network delivery time; bounded rollback and disposal may follow a failed evaluation.

Admission is nonwaiting and per application process: chronology/overview share two concurrent reads per owner and four globally; detail has an independent pool of four per owner and sixteen globally. Ingestion uses separate admission. These are protective limits, not user capacity or a cluster-wide bound across replicas.

Owner saturation returns 429 historyOwnerAdmissionExceeded; global saturation returns 503 historyAdmissionUnavailable, with global precedence when both apply. Both carry Retry-After: 5. Deadline exhaustion returns 503 historyBudgetExceeded, without partial successful items, cells or coverage. Pending required capture/text preparation returns 503 historyPreparationRequired; missing history environment qualification returns 503 historyQualificationRequired and requires a qualified profile before preparation can help; transient store failure returns 503 historyStoreUnavailable. Successes and errors are no-store. A cancelled client receives no success guarantee; resources are released. Clients should honor admission retry hints. See the API limits and error contract.

Upgrade planning

Follow the history preparation runbook and the installation’s supported update/recovery workflow. Existing histories require explicit resumable derivation preparation; ordinary startup and reads do not backfill them. Dependent capture/text operations remain gated until their required generation is ready.

Compatible qualified dependency servicing preserves prepared data, active/target state, checkpoints and continuations. R1 (#937/#938) has measured historical time and visible-text changes, so upgrade from the old generations requires explicit history-data rebuild both while old processes are quiesced; resume with history-data prepare both. Already-compatible qualified R1 rows are not rebuilt merely to rename their IDs. First inspect history-data status for actual loaded runtime/globalization provenance and Qualified; missing qualification is separate from pending preparation and rebuilding cannot cure it. No automatic repair or rolling-upgrade promise is introduced. Plan WAL, MVCC/index growth and maintenance using the retained measurements below and in the runbook, not a linear outage forecast. No new population/performance qualification accompanies this correction.

The status-coverage migration replaces the history UTC index in an ordinary transaction. Quiesce all application/read/import/enrichment traffic for this replacement, with a verified recovery set. Its lock blocks table access through commit. Allow the old and replacement indexes, build-sort temporary files, WAL and recovery reserve together. The local 4.61 s actual upgrade and approximately 32 MiB final index growth are observations, not downtime or peak-space bounds. If completion is ambiguous, inspect migration history and the physical index before retrying. See the index replacement requirements.

Actual restored-population headroom, downtime and recovery remain unqualified under #604. Backend acceptance does not accept a production deployment or mobile/native/deployed-client behavior. Those owners retain their separate responsibilities.

Self-hosting guide · Documentation home

Back to top