Skip to content

Add application warmup feature to run routing queries during startup#7509

Draft
vpaturet wants to merge 1 commit intoopentripplanner:dev-2.xfrom
entur:jvm-warmup-during-startup
Draft

Add application warmup feature to run routing queries during startup#7509
vpaturet wants to merge 1 commit intoopentripplanner:dev-2.xfrom
entur:jvm-warmup-during-startup

Conversation

@vpaturet
Copy link
Copy Markdown
Contributor

@vpaturet vpaturet commented Apr 9, 2026

Summary

Add a configurable application warmup feature that runs transit routing queries in a background
thread during OTP startup. This warms up the application — JIT compilation, GraphQL schema caches,
routing data structures, and other lazily initialized components — before production traffic arrives.

How it works

When the warmup section is present in router-config.json, a daemon thread sends sequential
GraphQL trip queries through the configured API (TransModel or GTFS), exercising the full request
stack: GraphQL parsing, data fetchers, Raptor + A* routing, itinerary filtering, and response
serialization. The thread starts after Raptor transit data is created and stops when all updaters
are primed (health endpoint returns UP) or after a maximum of 20 queries.

Queries alternate between depart-at/arrive-by and cycle through access/egress mode combinations
(walk, car-to-park). Query parameters are passed as GraphQL variables rather than string
interpolation, matching how production clients call the API.

Configuration example

"warmup": {
  "api": "transmodel",
  "from": { "lat": 59.9139, "lon": 10.7522 },
  "to": { "lat": 59.95, "lon": 10.76 }
}

Design

  • WarmupConfig — config parsing (final class, Api enum implements DocumentedEnum, version V2_10)
  • WarmupWorker — background thread that orchestrates warmup queries with max query limit, completion summary (count, failures, elapsed time), and top-level Throwable catch
  • WarmupQueryExecutor — strategy interface returning success/failure boolean
  • TransmodelWarmupQueryExecutor / GtfsWarmupQueryExecutor — cache schema, context, and (for GTFS) the GraphQL instance at construction time; use GraphQL variables for query parameters; both use immutable Map.of/Map.ofEntries for variables
  • Package: standalone.configure.warmup (startup lifecycle, not HTTP infrastructure)

Safety

  • Null guard for @Nullable GraphQL schema (warns if API feature is disabled)
  • Top-level catch (Throwable) ensures the warmup thread never dies silently
  • GraphQL errors logged at WARN for operator visibility
  • Exception stack traces logged at DEBUG
  • Warmup thread launch and skip both logged at INFO
  • Daemon thread — killed on JVM shutdown

Unit tests

  • WarmupConfigTest — tests config parsing (absent section, coordinate parsing, API enum parsing)
  • WarmupQueryValidationTest — validates both static query constants against the actual GraphQL schemas at build time

Documentation

  • RouterConfiguration.md regenerated with the new warmup section
  • package.md documents the warmup subpackage lifecycle and design

@vpaturet vpaturet changed the title Jvm warmup during startup Add application warmup feature to run routing queries during startup Apr 9, 2026
@vpaturet vpaturet added !Optimization The feature is to improve performance. Entur Test This is currently being tested at Entur labels Apr 9, 2026
@codecov
Copy link
Copy Markdown

codecov bot commented Apr 9, 2026

Codecov Report

❌ Patch coverage is 22.28261% with 143 lines in your changes missing coverage. Please review.
✅ Project coverage is 71.19%. Comparing base (96ca627) to head (c989cf2).

Files with missing lines Patch % Lines
...nner/standalone/configure/warmup/WarmupWorker.java 0.00% 70 Missing ⚠️
...onfigure/warmup/TransmodelWarmupQueryExecutor.java 0.00% 35 Missing ⚠️
...lone/configure/warmup/GtfsWarmupQueryExecutor.java 0.00% 32 Missing ⚠️
...ner/standalone/configure/ConstructApplication.java 0.00% 4 Missing ⚠️
...pentripplanner/standalone/config/RouterConfig.java 50.00% 1 Missing ⚠️
...r/standalone/config/routerconfig/WarmupConfig.java 97.56% 1 Missing ⚠️
Additional details and impacted files
@@              Coverage Diff              @@
##             dev-2.x    #7509      +/-   ##
=============================================
- Coverage      71.29%   71.19%   -0.11%     
- Complexity     21217    21222       +5     
=============================================
  Files           2365     2369       +4     
  Lines          87770    87954     +184     
  Branches        8686     8698      +12     
=============================================
+ Hits           62574    62615      +41     
- Misses         22183    22327     +144     
+ Partials        3013     3012       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@vpaturet
Copy link
Copy Markdown
Contributor Author

vpaturet commented Apr 9, 2026

@flaktack have you put in place a similar feature for your OTP deployments?

@vpaturet vpaturet force-pushed the jvm-warmup-during-startup branch from 074225a to a0004e8 Compare April 9, 2026 14:20
@vpaturet vpaturet added Entur Test This is currently being tested at Entur and removed Entur Test This is currently being tested at Entur labels Apr 9, 2026
@vpaturet vpaturet force-pushed the jvm-warmup-during-startup branch 2 times, most recently from 9f29324 to cfe420d Compare April 10, 2026 09:14
@vpaturet vpaturet removed the Entur Test This is currently being tested at Entur label Apr 14, 2026
Add a configurable warmup feature that runs transit routing queries in a
background thread during OTP startup, warming up JIT compilation, GraphQL
schema caches, routing data structures, and other lazily initialized
components before production traffic arrives.

When the `warmup` section is present in router-config.json, a daemon thread
sends sequential GraphQL trip queries through the configured API (TransModel
or GTFS). Queries start after Raptor transit data is created and stop when
all updaters are primed or after a maximum of 20 queries.
@vpaturet vpaturet force-pushed the jvm-warmup-during-startup branch from cfe420d to c989cf2 Compare April 14, 2026 15:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

!Optimization The feature is to improve performance.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant