Skip to content

Short bike hold in Redis, not a trip

Field Value
status proposed
date 2026-08-04
decision-makers CityCycle engineering
consulted support, product

RFC 0002 asks to keep a bike for a rider who is walking to the station. ADR 0002 only locks a bike for 15 seconds during unlock. Where does the longer hold live, and does it create a trip?

  • The hold must expire even if the app is killed
  • PostgreSQL remains the ledger of trips and payments, not of intentions
  • The map must hide the held bike within the same 30 second freshness goal
  • One rider must not be able to freeze several bikes
  • Redis key with a 90 second TTL, no PostgreSQL row
  • A holds table in PostgreSQL
  • Lengthen the existing 15 second unlock lock

Chosen option: “Redis key with a 90 second TTL, no PostgreSQL row”, because the hold is a temporary claim, not a trip, and Redis already owns the hot availability path.

This ADR is proposed. It is not accepted, and section 6 still describes the current unlock. The map changes only after this decision is accepted.

  • Good, because an abandoned hold disappears with the TTL
  • Good, because a failed hold writes nothing to the trip ledger
  • Bad, because a Redis flush drops every live hold; riders retry
  • Bad, because 90 seconds is a guess until support confirms the walk time
  • Good, because it matches the availability cache already in production
  • Bad, because the hold is gone if Redis is down; unlock falls back to the 15 second lock
  • Good, because the claim survives a Redis restart
  • Bad, because expiry needs a job, and the map read we tried to keep off PostgreSQL comes back
  • Good, because no new route
  • Bad, because it reserves the dock for someone who is not there yet

Review is on RFC 0002. Do not add POST /holds to section 5 until this status is accepted.