Global Bikeshare Reliability Monitor
Quantify station reliability across networks, highlight empties and fullness, surface rebalancing needs.
liveJump to panel
Networks
- Abu Dhabi Careem BIKEAbu Dhabi, AE
- Accès VéloSaguenay, CA
- Aksu阿克苏市 (Aksu City), CN
- AlbaAlba, IT
- AlbaBiciAlbacete, ES
- AlGiraAlmeirim, PT
- AlmatybikeAlmaty, KZ
- Alsa nextbike LeónLeón, ES
- alterVélo libre serviceSaint-Pierre, FR
- AmbiciBarcelona, ES
- AmbiciBadalona, ES
- AmbiciCastelldefels, ES
- AmbiciCornellà de Llobregat, ES
- AmbiciEl Prat de Llobregat, ES
- AmbiciEsplugues de Llobregat, ES
- AmbiciGavà, ES
- AmbiciHospitalet de Llobregat, ES
- AmbiciMolins de Rei, ES
- AmbiciSant Adrià de Besòs, ES
- AmbiciSant Boi de Llobregat, ES
Stations • santander-cycles
- 300073 - Prince of Wales Drive, Battersea Park11 bikes • 9 docks
- 003447 - Gloucester Road (North), Kensington4 bikes • 13 docks
- 200213 - Durant Street, Bethnal Green8 bikes • 15 docks
- 001229 - High Holborn , Covent Garden13 bikes • 4 docks
- 003488 - Charles II Street, West End16 bikes • 7 docks
- 001126 - North Audley Street, Mayfair11 bikes • 4 docks
- 300004 - Harris Academy, Bermondsey5 bikes • 12 docks
- 001209 - Empire Square, The Borough32 bikes • 14 docks
- 001189 - Long Lane , Bermondsey5 bikes • 14 docks
- 001068 - Norton Folgate, Liverpool Street13 bikes • 8 docks
- 001057 - Hardwick Street, Clerkenwell7 bikes • 22 docks
- 001204 - Queen's Gate (North), Kensington14 bikes • 26 docks
- 200052 - Exhibition Road Museums 2, South Kensington8 bikes • 6 docks
- 001158 - St. Martin's Street, West End12 bikes • 3 docks
- 001143 - Kensington Church Street, Kensington10 bikes • 5 docks
- 200072 - Houndsditch, Aldgate24 bikes • 4 docks
- 002701 - Columbia Road, Shoreditch23 bikes • 1 docks
- 001190 - Kennington Lane Rail Bridge, Vauxhall18 bikes • 11 docks
- 200249 - Queen Mary's, Mile End2 bikes • 38 docks
- 200050 - Naval Row, Blackwall14 bikes • 4 docks
- 001152 - Marylebone Lane, Marylebone12 bikes • 8 docks
- 300212 - Birkenhead Street, King's Cross14 bikes • 10 docks
- 001174 - Alderney Street, Pimlico5 bikes • 9 docks
- 001099 - Frampton Street, Paddington9 bikes • 23 docks
- 200127 - East India DLR, Blackwall31 bikes • 16 docks
- 200198 - Seymour Place, Marylebone15 bikes • 10 docks
- 001231 - Queen's Gate, Kensington Gardens13 bikes • 8 docks
- 200017 - Lancaster Gate , Bayswater11 bikes • 27 docks
- 200118 - Albert Street, Camden Town16 bikes • 10 docks
- 200091 - Wandsworth Town Station, Wandsworth17 bikes • 16 docks
- 001191 - Barbican Centre, Barbican15 bikes • 2 docks
- 010623 - Greycoat Street , Westminster9 bikes • 8 docks
- 200149 - Watney Street, Shadwell8 bikes • 18 docks
- 001019 - Ampton Street , Clerkenwell10 bikes • 11 docks
- 300058 - The Vale, Chelsea1 bikes • 22 docks
- 200073 - Cephas Street, Bethnal Green3 bikes • 20 docks
- 200180 - South Park, Sands End8 bikes • 18 docks
- 300081 - Haggerston Road, Haggerston19 bikes • 16 docks
- 200189 - Phene Street, Chelsea4 bikes • 20 docks
- 200209 - Shepherd's Bush Road North, Shepherd's Bush29 bikes • 2 docks
Build goals
Quantify station reliability across networks, highlight empties and fullness, surface rebalancing needs.
Stack
- Frontend: React 18, Mapbox GL or deck.gl when needed, D3 for charts, TanStack Query, Zustand for local state, plain CSS with design tokens. No runtime CSS frameworks.
- API: Python 3.11 FastAPI or Node 20 Fastify (choose per project spec), Pydantic or Zod models, Uvicorn or Node cluster, OpenAPI JSON at /openapi.json.
- Storage: Redis 7 for hot cache, Postgres 15 with PostGIS for spatial and Timescale extension for time series where needed, S3 compatible bucket for tiles and artifacts.
- Ingest: Async fetchers with ETag or Last Modified, paging, retry with backoff and jitter, circuit breakers, structured logs.
- Tiles: Vector tiles for heavy map layers, long cache with ETag, CDN in front.
- Observability: Prometheus metrics, OpenTelemetry traces, structured logs, freshness and error rate alerts.
- Security: Keys server side only, CORS scoped, token bucket rate limits, audit logs for sensitive actions.
Data sources
Source | Endpoint | Cadence | Access | Auth | Notes |
---|---|---|---|---|---|
CityBikes Aggregator | api.citybik.es/v2 | frequent | REST JSON | None | Unified status many cities |
MobilityData GBFS registry | github.com/MobilityData/gbfs, systems.csv | frequent | CSV, JSON | None | Directory of official feeds |
Architecture
Node Fastify or Python FastAPI, GBFS adapters to common schema, staggered polls, Redis hot status, Postgres daily aggregates, city heat tiles.
Models
Models are expressed in DB tables and mirrored as API schemas. All timestamps are UTC. All coordinates are WGS84. Stable IDs, soft deletes by valid_to when needed.
- city(id, name, bbox geom)
- station(id, city_id, lat, lon, capacity)
- status(station_id, ts, bikes, docks)
- reliability(station_id, day, pct_empty, pct_full, score)
Algorithms
- Sample counters for empty and full intervals
- Score = 1 minus max(pct_empty, pct_full), capacity weighted
- Playback generated from sampled status, not full history
API surface
- GET /cities?q=
- GET /stations?city_id=
- GET /reliability?city_id=&day=
- GET /tiles/city/{z}/{x}/{y}.pbf
UI and visualization
- Clustered station map colored by reliability
- Worst station leaderboard
- City KPIs and daily playback
- CSV export of daily metrics
Performance budgets
- City view p95 frame under 16 ms at 5k stations
- Freshness under 10 minutes with staggered polls
- FCP under 2 s on broadband mid tier laptop.
- API p95 under 300 ms for common list endpoints, p99 under 800 ms.
- Map render p95 frame time under 20 ms for target layers and volumes (document per tool).
- Frontend app code under 180 KB gzip excluding map library.
- API memory under 200 MB under normal load.
Accessibility
- WCAG 2.2 AA, automated axe checks clean, no critical issues.
- Keyboard navigable controls, focus rings visible, ARIA roles correct.
- Color contrast at or above 4.5 to 1, colorblind safe palettes.
- Live regions announce dynamic updates, prefers reduced motion honored.
Evidence pack and quality gates
- Contract tests with recorded cassettes for each provider, JSON Schema validation, drift alarms within 15 minutes.
- Load tests with k6, thresholds enforced in CI for p95 and p99.
- Lighthouse performance and a11y reports stored as CI artifacts.
- Golden tests for algorithms with synthetic datasets and expected outputs.
- Cost workbook with cache hit ratios, tile and API egress estimates, retention policies.
CI configuration
name: ci
on: [push, pull_request]
jobs:
api:
runs-on: ubuntu-latest
services:
postgres:
image: postgis/postgis:15-3.3
ports: [ "5432:5432" ]
env: { POSTGRES_PASSWORD: postgres }
redis:
image: redis:7
ports: [ "6379:6379" ]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: "20" }
- uses: actions/setup-python@v5
with: { python-version: "3.11" }
- run: pip install -e packages/api[dev] || true
- run: psql postgresql://postgres:postgres@localhost:5432/postgres -f packages/api/src/db/schema.sql || true
- run: pytest -q packages/api/src/tests || true
- run: cd packages/web && npm ci && npm run build && npm test --silent
Risks and mitigations
- Aggregator staleness, add direct GBFS for priority networks
- Sampling jitter, smooth with small rolling window
Acceptance checklist
- CI green on main, all quality gates met.
- Freshness SLOs met for hot regions or feeds.
- Performance budgets met or better.
- A11y audits pass with zero critical findings.
- Provenance and license panels render correct metadata.
- Runbook covers stale feed handling, provider errors, and key rotation.
Implementation sequence
- Build GBFS adapters and city registry integration
- Implement reliability job and aggregates
- Serve tiles and list endpoints
- Ship map, leaderboard, KPIs, playback
- Evidence pack with jitter and paging tests
Runbook
make up # docker compose up db, redis, api, web
make ingest # start ingest workers for this tool
make tiles # build vector tiles if applicable
make test # unit + contract + golden
make e2e # browser tests