Personal engineering product · live in production

Swiss Parking
Intelligence

I turned a fragmented parking search into findparking.ch: a public product that combines live availability, historical context and short-term forecasts across several Swiss cities. I designed, built, deployed and continue to operate the complete system.

5cities live today
~90parking facilities
Since Sep 2025historical observations
< CHF 10/moVPS hosting

01 — Genesis

A real driving problem, not a startup narrative.

When I drove to Zurich, checking parking availability was unnecessarily fragmented. The information existed, but comparing several relevant facilities meant opening separate sources one by one.

The first product idea was deliberately simple: show multiple parking facilities together so a driver can compare current availability immediately.

A second question appeared early. If I leave in 30–60 minutes, the current number is not enough: is a facility likely to become fuller or emptier? Answering that required something the source sites did not provide—a usable history.

02 — Product evolution

Useful first, then progressively more capable.

  1. 01

    Late 2025 · table MVP

    The first public version was primarily a set of availability tables. It solved the comparison problem and started collecting observations without waiting for a sophisticated interface.

  2. 02

    History accumulates

    Scheduled snapshots turned temporary public values into time series. The current production history reaches back approximately to September 2025.

  3. 03

    Around June 2026 · forecasting experiments

    Zurich provided the first development and test case for short-term prediction, followed by systematic comparison of several approaches.

  4. 04

    Multi-city architecture

    Once the shared pipeline existed, new cities could reuse storage, evaluation and presentation while adding only a source-specific ingestion adapter.

  5. 05

    Current product

    The table MVP has evolved into a polished, responsive public interface with comparable cards and an interactive map.

The sequence matters: the product was already useful while the data asset and the more experimental capabilities were still developing.

03 — Architecture

Keep source-specific complexity at the boundary.

Swiss cities and operators expose parking data through heterogeneous formats and endpoints, including XML and JSON. There is no single standard Swiss parking API behind the product.

Each city therefore has its own retrieval and adaptation connector. After normalization into a common internal representation, the PostgreSQL storage, forecasting and evaluation logic, Flask application and user interface are shared.

Production architecture
Heterogeneous public sources
XML · JSON · other endpoints
City-specific adapters
Common representation & validation
Historical observations
PostgreSQL on the VPS
Forecast & evaluation
~8 approaches · MAE
Operational checks
freshness · failures · alerts
Python + Flask application
Responsive list + Leaflet / OpenStreetMap

04 — Data pipeline

From an ephemeral update to an evaluated forecast.

  1. 01

    Retrieve

    A city connector calls its public source and handles that source’s particular format.

  2. 02

    Adapt

    City-specific fields and statuses are translated into the shared internal shape.

  3. 03

    Validate & store

    Usable observations are persisted as timestamped PostgreSQL snapshots instead of overwriting the previous state.

  4. 04

    Generate forecasts

    Scheduled jobs produce short-term estimates from the accumulated history when enough fresh data is available.

  5. 05

    Evaluate

    Forecasts are compared with later observed availability and model error is tracked, including with MAE.

  6. 06

    Present & monitor

    Flask serves the public cards and map, while private health views expose freshness, job status and detected problems.

Conventional cron is sufficient at this scale: ingestion runs approximately every 5 minutes, prediction jobs every 15 minutes, and backups daily. The different cadences avoid recomputing forecasts every time a raw observation arrives.

05 — Product and engineering decisions

Control complexity deliberately.

Adapters before abstractions

Heterogeneous sources remain isolated in city connectors; the rest of the system works with one common representation.

History before prediction

Collecting snapshots early created the evidence needed for later forecasting instead of forcing a prediction feature onto insufficient data.

Cron before orchestration infrastructure

Different schedules are explicit and easy to operate on one modest server. More infrastructure would not yet create proportional value.

Detect before pretending to self-heal

Monitoring distinguishes application failures from stale, missing or changed upstream data. Repairs still require diagnosis and, when necessary, connector changes.

06 — Historical data

The missing dataset had to be created over time.

Production observations currently reach back approximately to September 2025. No row count, database size or query-performance claim is published because those values are not verified here.

Each retained update makes availability an observable time series rather than a disposable number. PostgreSQL on the VPS supports the live application, historical comparisons and the prediction/evaluation pipeline.

The value compounds gradually. A new city can join the common forecasting framework only after a compatible public source is ingested and enough history has accumulated; the architecture cannot compensate for data that an operator does not publish.

Why history changes the productSource at one moment

Current availability

findparking.ch over time

Current availability
+ One-hour comparison
+ Historical observations
+ Short-term estimates
+ Forecast evaluation

07 — Forecasting experiments

Compare approaches before selecting a winner.

The current system is in an experimentation and evaluation phase, not a finished machine-learning platform. Approximately eight forecasting approaches are being compared rather than presenting one model as definitively best.

Predictions are stored and later compared with the availability that was actually observed. The private operational dashboard tracks model performance using measures including Mean Absolute Error (MAE), making selection evidence-based.

The public interface currently exposes estimates one and three hours ahead when fresh data, capacity and a current model are available. It labels them as estimates—not guarantees—and withholds them when the inputs are insufficient.

08 — Current public product

A modern interface for a decision made on the move.

Users can scan responsive parking cards or switch to a geographic map. Cards show the current free spaces and known capacity, a colour-coded availability state, the change and availability around one hour earlier, data freshness and—when valid—short-term estimates.

The map uses Leaflet with OpenStreetMap and presents the same core availability context geographically. The current experience is a substantial evolution from the original table MVP, while remaining focused on the practical comparison task.

Free now + capacityAvailability stateOne-hour comparison+1h and +3h estimatesFreshness timestampResponsive cards + map
Live public productOpen findparking.ch

Browse current parking availability and short-term estimates across the supported Swiss cities.

Visit findparking.ch

09 — Production operations

Deployment was the beginning of the reliability work.

Linux VPSThe Python, Flask and PostgreSQL production system runs as a real public service on infrastructure costing under CHF 10 per month.
Cron automationSeparate ingestion and prediction schedules keep the operating model understandable and proportionate.
Daily backupsDatabase and system backups run every day as a routine operational safeguard.
SMTP alertsLightweight email notifications report failed scheduled work, stale city data and other detected ingestion problems.

A password-protected internal health dashboard covers ingestion status, data freshness, prediction jobs, detected issues and MAE-based model comparisons. Authentication protects this operational view; it is not a consumer account system.

Real scheduled-job failures and upstream data problems motivated the monitoring and alerting. Some incidents originate in the application; others occur when an operator stops publishing, serves stale or unusable data, or changes its source. The pragmatic response is to detect, diagnose and adapt—not to claim perfect uptime or automatic repair.

10 — Continuous improvement

Keep the product useful while learning in a realistic system.

Two parallel goals

Development continues both to polish the actual product and to create a realistic environment for technical experimentation.

Complexity earns its place

A full consumer account ecosystem, extensive notifications, payments and commercial infrastructure remain intentionally outside the current product.

Experiments stay separate from production claims

Azure and Snowflake are being explored and prototyped for practical learning; they are not presented as critical production dependencies.

Small-scale operations are still real operations

A modest VPS and cron jobs create enough operational responsibility to learn from failures without building infrastructure the product does not need.

11 — Current state

A public product with real data and a deliberately modest scope.

5Zurich, Basel, Bern, Winterthur and Luzern
~90facility cards currently exposed
3 layersingestion · shared data/forecasting · web product
Livecontinuously operated public service

The achievement is the lifecycle, not commercial traction: idea, table MVP, continuous data collection, forecasting experiments, responsive UI, production deployment, monitoring, maintenance and roadmap all belong to one coherent product.

The site is public, but user acquisition is not currently an objective. I am the primary regular user, with occasional use by friends and others who have received the link; no meaningful MAU, DAU or traffic claim is available.

12 — End-to-end ownership

I own the complete technical and product lifecycle.

I identified the problem, scoped and shipped the first useful version, designed the connector boundary and PostgreSQL history, built the Flask application and responsive interface, introduced forecasting evaluation, and deployed the product on a Linux VPS.

I also operate it: scheduling jobs, maintaining backups, monitoring freshness and model performance, responding to application and upstream-source failures, and deciding which improvement is valuable enough to add next.

Positioning: this is a personal engineering and product project built outside my employment. There is no client, corporate stakeholder process, team-leadership claim or commercial traction story behind it. Its value is direct evidence that I can take a technical product from a personal problem through production operation and continuous improvement.

13 — Long-term roadmap

Mobile is the natural next product direction—not current functionality.

Parking availability is a mobile, real-time use case. A native application is a future direction rather than a committed delivery or a feature already under development.

Personalised live view

Accounts and favourite facilities could support persistent views centred on the parkings a person actually uses.

Richer notifications

Selected-facility monitoring could make changes more actionable without turning every update into noise.

Native mobile experience

A phone-first application could make the comparison faster before and during a journey.

Optional future business layer

Payments or other commercial capabilities would be considered only if the product genuinely evolves in that direction.