Skip to main content

Performance Monitoring

The Tracker GraphQL API includes a built-in performance monitoring system that helps you identify bottlenecks and optimize your application. This guide explains how to use and configure the performance monitoring features.

Overview

The performance monitoring system tracks:

  • Resolver Execution Times: How long each GraphQL resolver takes to execute
  • Database Query Performance: Execution times for database queries
  • Cache Performance: Hit/miss rates and timing for the caching system

This data can help you identify slow queries, inefficient resolvers, and opportunities for optimization.

Accessing Performance Metrics

Performance metrics are available through the _performanceMetrics GraphQL query:

query {
_performanceMetrics {
resolvers {
name
count
avgTime
medianTime
minTime
maxTime
totalTime
lastExecutionTime
lastExecution
}
queries {
name
count
avgTime
medianTime
minTime
maxTime
totalTime
lastExecutionTime
lastExecution
}
cache {
hits
misses
hitRate
missRate
avgHitTime
avgMissTime
totalHitsTime
totalMissesTime
}
config {
enabled
includeInResponse
logAllMetrics
slowQueryThreshold
slowResolverThreshold
}
}
}

This query returns comprehensive metrics about your application's performance.

Understanding the Metrics

Resolver Metrics

Resolver metrics provide information about the performance of your GraphQL resolvers:

  • name: The name of the resolver function
  • count: Number of times the resolver has been called
  • avgTime: Average execution time in seconds
  • medianTime: Median execution time in seconds
  • minTime: Minimum execution time in seconds
  • maxTime: Maximum execution time in seconds
  • totalTime: Total execution time across all calls in seconds
  • lastExecutionTime: Execution time of the most recent call in seconds
  • lastExecution: Timestamp of the most recent call

Query Metrics

Query metrics provide information about database query performance:

  • name: The name of the query (derived from query type and table name)
  • count: Number of times the query has been executed
  • avgTime: Average execution time in seconds
  • medianTime: Median execution time in seconds
  • minTime: Minimum execution time in seconds
  • maxTime: Maximum execution time in seconds
  • totalTime: Total execution time across all executions in seconds
  • lastExecutionTime: Execution time of the most recent execution in seconds
  • lastExecution: Timestamp of the most recent execution

Cache Metrics

Cache metrics provide information about the performance of the caching system:

  • hits: Number of cache hits
  • misses: Number of cache misses
  • hitRate: Percentage of cache hits (0.0 to 1.0)
  • missRate: Percentage of cache misses (0.0 to 1.0)
  • avgHitTime: Average time to retrieve an item from cache in seconds
  • avgMissTime: Average time to determine a cache miss in seconds
  • totalHitsTime: Total time spent on cache hits in seconds
  • totalMissesTime: Total time spent on cache misses in seconds

Configuration

The configuration section shows the current performance monitoring settings:

  • enabled: Whether performance monitoring is enabled
  • includeInResponse: Whether to include performance data in GraphQL responses
  • logAllMetrics: Whether to log all metrics or only slow ones
  • slowQueryThreshold: Threshold in seconds for identifying slow queries
  • slowResolverThreshold: Threshold in seconds for identifying slow resolvers

Performance Data in Responses

When includeInResponse is enabled, each GraphQL response will include performance data for the specific resolver that handled the request. This appears as a _performance field in the response:

{
"data": {
"recentLocationHistory": [
// ... data ...
],
"_performance": {
"executionTime": 0.0339508056640625,
"resolverName": "resolve_recent_location_history_query"
}
}
}

This allows you to monitor performance on a per-request basis.

Logging

The performance monitoring system logs performance data to help you identify issues:

  • All metrics are logged when logAllMetrics is enabled
  • Only metrics that exceed the slow thresholds are logged when logAllMetrics is disabled
  • Slow queries and resolvers are logged at WARNING level
  • Normal metrics are logged at INFO level

Example log entries:

2025-05-04 16:51:50,674 - app.resolvers.location_history - INFO - PERFORMANCE: Resolver resolve_recent_location_history_query took 0.0005s
2025-05-04 16:51:50,674 - app.utils.performance - INFO - CACHE HIT: took 0.0003s

Implementation Details

The performance monitoring system is implemented using:

  1. Decorator Pattern: The @track_resolver decorator tracks resolver execution times
  2. Mixin Classes: The TimedSessionMixin adds performance tracking to SQLAlchemy sessions
  3. Middleware: Performance data is collected and stored in memory with configurable retention

Database Session Monitoring

Database queries are automatically monitored through a custom SQLAlchemy session class that combines resilient connections with performance monitoring:

class PerformanceSession(ResilientSession, TimedSessionMixin):
"""
Session class that combines resilient connections with performance monitoring.

This class inherits from both ResilientSession (for automatic retries on connection failures)
and TimedSessionMixin (for tracking query execution time).
"""
pass

This session class tracks execution times for all database operations.

Best Practices

Here are some best practices for using the performance monitoring system:

  1. Monitor Regularly: Check performance metrics regularly to identify trends and issues
  2. Focus on Slow Resolvers: Pay special attention to resolvers with high average or maximum execution times
  3. Optimize Cache Usage: Use the cache hit/miss rates to optimize your caching strategy
  4. Set Appropriate Thresholds: Adjust the slow query and resolver thresholds based on your application's requirements
  5. Use in Development: Enable detailed metrics in development to catch performance issues early
  6. Limit in Production: In production, consider disabling includeInResponse and logAllMetrics to reduce overhead

Configuring Performance Monitoring

The performance monitoring system can be configured programmatically:

from app.utils.performance import configure

# Enable or disable performance monitoring
configure(enabled=True)

# Configure logging
configure(log_all_metrics=False)

# Set thresholds
configure(slow_query_threshold=0.5, slow_resolver_threshold=1.0)

# Configure response inclusion
configure(include_in_response=True)

# Set retention period
from datetime import timedelta
configure(retention_period=timedelta(hours=1))

These settings can be adjusted based on your specific needs.