Skip to content

perf: reduce memory footprint of GTFS data and cache metrics exposition - #82

Merged
aaronbrethorst merged 10 commits into
OneBusAway:mainfrom
0xaboomar:refactor/minimal-gtfs-models
Aug 23, 2025
Merged

aaronbrethorst merged 10 commits into
OneBusAway:mainfrom
0xaboomar:refactor/minimal-gtfs-models

Conversation

@0xaboomar

@0xaboomar 0xaboomar commented Aug 17, 2025 •

Copy link
Copy Markdown
Member

Performance Improvements

Here are the measured performance improvements after applying the optimizations:

  • Before optimization: in-use memory ranged between 70–90 MB.
  • After optimization: in-use memory now ranges between 5–9 MB.

During load testing with 10K total requests and 1K concurrent requests:

  • Time per request: reduced from 495 ms to 209 ms.
  • Max in-use memory: reduced from 100+ MB to 16 MB.

During lower load with 1K total requests and 50 concurrent requests:

  • Time per request: reduced from 25 ms to 8 ms.

Before

Before

After
After

Note:

  • These benchmarks were conducted with Watchdog monitoring two OBA servers.
  • Peak points are the points where I performed load testing using Apache Bench.
  • The reserved memory here is the larger virtual address space that Go pre-allocates from the OS to reduce fragmentation and minimize allocation latency.

What Changed

  • Added lightweight StaticData and RealtimeData models containing only required GTFS fields.

  • Updated StaticStore and RealtimeStore to store these minimal models instead of full bundles, reducing memory usage.

  • Introduced CachedPromHandler that precomputes metrics at fixed intervals and serves cached responses.

    • Avoids expensive serialization for every scrape.

Why

  • Full GTFS static/realtime bundles kept in memory were unnecessarily large.
  • Prometheus scrapes were triggering full metrics serialization on every request, wasting CPU and increasing latency.

- Store only required GTFS fields (stops, agencies, services, vehicles)
- Copy slices to avoid retaining full GTFS bundles in memory
- Provide constructors NewStaticData and NewRealtimeData
…imeStore

- Replace direct usage of remoteGtfs.Static and remoteGtfs.Realtime with models.StaticData and models.RealtimeData
- Update Set/Get methods to work with new wrapper types
- Ensures stores only retain required GTFS fields
@0xaboomar 0xaboomar changed the title refactor: introduce minimal GTFS models and optimize memory usage perf: reduce memory footprint of GTFS data and cache metrics exposition Aug 18, 2025
@aaronbrethorst
aaronbrethorst requested a review from Copilot August 23, 2025 21:44

@aaronbrethorst aaronbrethorst left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm! 👍

@aaronbrethorst
aaronbrethorst merged commit 0072b95 into OneBusAway:main Aug 23, 2025
@0xaboomar
0xaboomar removed the request for review from Copilot March 23, 2026 22:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants