Skip to content

Deploying OpenTripPlanner

Introduction

OpenTripPlanner (OTP) is an open-source platform for multimodal trip planning that combines public transit, walking, cycling, and driving into unified journey recommendations. Originally developed for TriMet (Portland’s transit agency), OTP has grown into a mature, widely-deployed solution used by transit agencies, cities, and transportation applications worldwide.

OTP processes transit schedules (GTFS data) and street networks (OpenStreetMap data) to build a routing graph that enables real-time trip planning. The platform provides both a web interface for end users and a powerful API for integration into mobile apps, websites, and other transportation services.

Key highlights of OpenTripPlanner:

  • Multimodal Routing: Combine transit, walking, cycling, and driving in single trips
  • Real-Time Updates: Support for GTFS-RT feeds for live arrival predictions
  • Accessibility: Route planning for users with mobility restrictions
  • Bike Share Integration: Include bike-sharing stations in trip options
  • Flexible API: RESTful and GraphQL APIs for application integration
  • Isochrone Maps: Visualize areas reachable within time limits
  • Multiple Languages: Internationalized interface and directions
  • Sandbox Extensions: Additional features like fare calculation and park-and-ride
  • Scalable Architecture: Handle high query volumes with appropriate resources
  • Open Data: Built on open standards (GTFS, GBFS, OpenStreetMap)

This guide walks through deploying OpenTripPlanner on Klutch.sh using Docker, importing transit data, and configuring the service for production use.

Why Deploy OpenTripPlanner on Klutch.sh

Deploying OpenTripPlanner on Klutch.sh provides several advantages:

Simplified Deployment: Klutch.sh automatically builds and deploys your trip planner. Push to GitHub, and your service deploys without complex orchestration.

Persistent Storage: Attach persistent volumes for your built graph and configuration. Avoid rebuilding the graph after container restarts.

HTTPS by Default: Klutch.sh provides automatic SSL certificates for secure API access and web interface.

Scalable Resources: Trip planning requires significant memory for large graphs. Allocate resources based on coverage area and expected query volume.

GitHub Integration: Store configuration in Git for version control. Update by pushing changes to your repository.

Custom Domains: Assign a professional domain for your trip planning service.

Always-On Availability: Your trip planner runs 24/7, providing consistent routing service for your applications.

Prerequisites

Before deploying OpenTripPlanner on Klutch.sh, ensure you have:

  • A Klutch.sh account
  • A GitHub account with a repository for your OTP configuration
  • Basic familiarity with Docker and containerization concepts
  • GTFS data for your transit agencies (publicly available from most agencies)
  • OpenStreetMap data for your region (PBF format)

Understanding OpenTripPlanner Architecture

OpenTripPlanner consists of several components:

Graph Builder: Processes GTFS and OSM data to create a routing graph. This is typically run once or periodically when data updates.

OTP Server: Loads the pre-built graph and handles routing requests. This is the main production service.

Web Interface: A built-in interface for testing and demonstration, or integrate with custom frontends.

APIs: RESTful API and GraphQL endpoint for programmatic access.

Data Requirements

GTFS (General Transit Feed Specification): Transit schedules including routes, stops, times, and calendar information. Available from transit agencies.

OpenStreetMap Data: Street network for walking, cycling, and driving. Download regional extracts from Geofabrik.

Preparing Your Repository

Create a GitHub repository containing your Dockerfile and configuration.

Repository Structure

otp-deploy/
├── Dockerfile
├── build-config.json
├── router-config.json
├── otp-config.json
├── .dockerignore
└── README.md

Creating the Dockerfile

Create a Dockerfile for OpenTripPlanner:

FROM opentripplanner/opentripplanner:latest
# Create directories
RUN mkdir -p /var/otp/graphs/default
# Copy configuration files
COPY build-config.json /var/otp/build-config.json
COPY router-config.json /var/otp/router-config.json
COPY otp-config.json /var/otp/otp-config.json
# Set environment variables
ENV JAVA_OPTS="-Xmx4G"
# Expose the OTP port
EXPOSE 8080
# The default entrypoint handles both building and serving

Configuration Files

Create build-config.json for graph building:

{
"areaVisibility": true,
"platformEntriesLinking": true,
"osmWayPropertySet": "default",
"transitServiceStart": "-P1Y",
"transitServiceEnd": "P2Y"
}

Create router-config.json for routing behavior:

{
"routingDefaults": {
"numItineraries": 5,
"transferSlack": 120,
"walkReluctance": 2.0,
"stairsReluctance": 1.65,
"bikeRentalPickupTime": 60,
"bikeRentalDropoffTime": 30
},
"updaters": []
}

Create otp-config.json for general settings:

{
"otpFeatures": {
"SandboxAPIMapboxVectorTilesApi": true,
"SandboxAPITravelTime": true
}
}

Environment Variables Reference

VariableDefaultDescription
JAVA_OPTS-Xmx2GJVM memory allocation
OTP_GRAPH_PATH/var/otp/graphsPath to graph files

Deploying OpenTripPlanner on Klutch.sh

Follow these steps to deploy OpenTripPlanner:

    Obtain Transit Data

    Download GTFS data from your transit agency. Many agencies publish feeds:

    • Check agency websites for GTFS downloads
    • Use TransitFeeds for aggregated feeds
    • Contact agencies directly for access

    Obtain Street Network Data

    Download OpenStreetMap data for your region:

    Terminal window
    # Example: Download data for a metro area
    wget https://download.geofabrik.de/north-america/us/oregon-latest.osm.pbf

    Build the Graph

    Before deploying, build the OTP graph locally or in a build container:

    Terminal window
    # Run OTP in build mode
    docker run -v /path/to/data:/var/otp/graphs/default \
    opentripplanner/opentripplanner:latest --build --save

    This creates a graph.obj file in your data directory.

    Push Your Repository to GitHub

    Initialize and push your repository:

    Terminal window
    git init
    git add Dockerfile *.json .dockerignore README.md
    git commit -m "Initial OpenTripPlanner configuration"
    git remote add origin https://github.com/yourusername/otp-deploy.git
    git push -u origin main

    Create a New Project on Klutch.sh

    Navigate to the Klutch.sh dashboard and create a new project named “otp” or “trip-planner”.

    Create a New App

    Within your project, create a new app. Connect your GitHub account and select the repository containing your OTP Dockerfile.

    Configure HTTP Traffic

    In the deployment settings:

    • Select HTTP as the traffic type
    • Set the internal port to 8080

    Set Environment Variables

    Configure memory allocation:

    VariableValue
    JAVA_OPTS-Xmx4G (adjust based on graph size)

    Attach Persistent Volumes

    Add persistent storage for the graph:

    Mount PathRecommended SizePurpose
    /var/otp/graphs20 GBBuilt graph files
    /var/otp/data10 GBGTFS and OSM source files

    Upload Graph Data

    Upload your pre-built graph.obj to the persistent volume at /var/otp/graphs/default/.

    Deploy Your Application

    Click Deploy to start the build process. OTP will load the graph and start the server.

    Access OpenTripPlanner

    Once deployment completes, access the web interface at:

    https://your-app-name.klutch.sh

Using OpenTripPlanner

Web Interface

The built-in interface provides:

  • Interactive map for selecting origin and destination
  • Date and time selection for trip planning
  • Mode selection (transit, walk, bike, etc.)
  • Accessibility options
  • Itinerary display with step-by-step directions

REST API

Query trips programmatically:

Terminal window
curl "https://your-app-name.klutch.sh/otp/routers/default/plan?fromPlace=45.5,-122.6&toPlace=45.4,-122.5&date=2024-03-15&time=08:00&mode=TRANSIT,WALK"

GraphQL API

Use the GraphQL endpoint for flexible queries:

{
plan(
from: {lat: 45.5, lon: -122.6}
to: {lat: 45.4, lon: -122.5}
date: "2024-03-15"
time: "08:00"
transportModes: [{mode: TRANSIT}, {mode: WALK}]
) {
itineraries {
duration
walkDistance
legs {
mode
from { name }
to { name }
}
}
}
}

Isochrone Analysis

Generate travel time maps:

Terminal window
curl "https://your-app-name.klutch.sh/otp/routers/default/isochrone?fromPlace=45.5,-122.6&date=2024-03-15&time=08:00&mode=TRANSIT,WALK&cutoffSec=1800&cutoffSec=3600"

Real-Time Updates

GTFS-RT Integration

Add real-time updates to router-config.json:

{
"updaters": [
{
"type": "real-time-alerts",
"frequencySec": 30,
"url": "https://transit-agency.com/gtfs-rt/alerts",
"feedId": "agency"
},
{
"type": "vehicle-positions",
"frequencySec": 30,
"url": "https://transit-agency.com/gtfs-rt/vehicle-positions",
"feedId": "agency"
},
{
"type": "stop-time-updater",
"frequencySec": 30,
"url": "https://transit-agency.com/gtfs-rt/trip-updates",
"feedId": "agency"
}
]
}

Bike Share Integration

Add GBFS feeds for bike sharing:

{
"updaters": [
{
"type": "bike-rental",
"frequencySec": 60,
"sourceType": "gbfs",
"url": "https://bikeshare.com/gbfs/gbfs.json"
}
]
}

Graph Updates

Updating Transit Data

When GTFS data changes:

  1. Download new GTFS files
  2. Rebuild the graph with new data
  3. Upload the new graph.obj to your volume
  4. Restart the OTP server to load the new graph

Automating Updates

Consider setting up scheduled graph rebuilds:

  1. Create a separate build container/job
  2. Schedule weekly or monthly rebuilds
  3. Upload new graphs during low-traffic periods
  4. Restart the server to load updated data

Performance Optimization

Memory Allocation

OTP requires significant memory for large graphs:

Coverage AreaRecommended Memory
City2-4 GB
Metro Area4-8 GB
State/Region8-16 GB
Country16-32 GB

Query Performance

  • Pre-compute common routes if possible
  • Use caching for repeated queries
  • Consider geographic sharding for very large areas
  • Monitor query latency and adjust resources

Troubleshooting Common Issues

Out of Memory Errors

Symptoms: OTP crashes during graph loading or routing.

Solutions:

  • Increase JAVA_OPTS memory allocation
  • Use a smaller geographic area
  • Reduce the number of GTFS feeds
  • Check for memory leaks in custom configurations

No Routes Found

Symptoms: API returns no itineraries.

Solutions:

  • Verify transit data covers the requested time
  • Check that origin/destination are within coverage area
  • Ensure street network connects to transit stops
  • Review GTFS calendar data for service dates

Graph Build Failures

Symptoms: Graph building crashes or hangs.

Solutions:

  • Verify GTFS files are valid
  • Ensure OSM data is not corrupted
  • Check for sufficient disk space
  • Review build logs for specific errors

Slow Query Performance

Symptoms: Routing requests take too long.

Solutions:

  • Increase memory allocation
  • Reduce graph complexity
  • Implement query caching
  • Scale horizontally for high traffic

Additional Resources

Conclusion

Deploying OpenTripPlanner on Klutch.sh provides a powerful multimodal trip planning service for your city or region. With support for transit, walking, cycling, and real-time updates, OTP enables sophisticated transportation applications.

The combination of persistent graph storage and scalable resources makes Klutch.sh well-suited for OTP deployment. Whether building a transit app, analyzing transportation accessibility, or providing journey planning for your organization, your self-hosted OpenTripPlanner instance delivers reliable routing services.

Start with a single city, expand to regional coverage, and integrate real-time feeds to provide up-to-the-minute trip planning for your users.