Skip to main content

Timer Service Architecture

This architecture implements reliable time tracking with strong guarantees: no overlapping timers per user, resumable sessions, Pomodoro workflows, and analytics-ready aggregation. It is designed for a single database (Postgres preferred) and supports monitoring and management.

Goals

  • Single active timer per user (enforced by constraint + trigger).
  • Precise elapsed time via spans (pause/resume tracked).
  • Support types: manual, pomodoro, countdown, interval.
  • Operational visibility: health checks, daily totals, performance metrics.
  • Clean lifecycle and admin controls.

Core Entities

  • timers: One row per logical timer session with status and metadata.
  • timer_spans: Sub-intervals when a timer is running (start→end). Summed for accurate elapsed time.
  • pomodoro_settings: Per-user config for work/break durations.
  • pomodoro_cycles: Actual executed cycles tied to a timer.

See the full SQL in the Schema page.

Lifecycle

  • Start: create timers with status='running' and first timer_spans record.
  • Pause: close current span; status='paused'.
  • Resume: create new span; status='running'.
  • Stop/Complete: close last span and set ended_at; status='stopped'|'completed'.

Constraints prevent multiple active timers per user and optionally prevent overlapping time ranges.

Monitoring & Management

  • Daily totals materialized view for analytics and dashboards.
  • Admin controls to disable timers or correct data.
  • Background tasks (cron/worker) to auto-complete stale running timers.

Health Metrics

  • Count of active timers per minute.
  • Average session duration per type.
  • Pomodoro adherence (planned vs actual cycle durations).

Integration

  • REST/gRPC endpoints:
    • POST /timers/start (type, title, expected_end)
    • POST /timers/:id/pause
    • POST /timers/:id/resume
    • POST /timers/:id/stop
    • GET /timers?user_id=...&date=... (list with totals)

Optimization Notes

  • Store tstzrange (Postgres) for overlap checks (requires btree_gist).
  • Partial unique index to enforce one active timer per user.
  • GIN index on tags for flexible filtering.
  • Materialized views refreshed on schedule for reporting.

Continue to the Schema page for the full SQL including triggers and indexes.

This document describes the architecture of the Timer service.

Goals

  • Precise scheduling with low drift
  • Scalable timers for millions of users
  • Fault-tolerant execution

High-Level Diagram

Components

  • Scheduler: manages timer creation, updates, cancellations
  • Queue: durable timer events (e.g., RabbitMQ/Kafka)
  • Workers: consume due timers and execute callbacks/webhooks
  • DB: persistence, deduplication, idempotency keys
  • API: create/list/cancel timers, WebSocket for real-time status

Non-Functional

  • At-least-once execution with idempotent callbacks
  • Dead-letter queue for failures
  • Observability with metrics on due vs executed