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 functioncount: Number of times the resolver has been calledavgTime: Average execution time in secondsmedianTime: Median execution time in secondsminTime: Minimum execution time in secondsmaxTime: Maximum execution time in secondstotalTime: Total execution time across all calls in secondslastExecutionTime: Execution time of the most recent call in secondslastExecution: 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 executedavgTime: Average execution time in secondsmedianTime: Median execution time in secondsminTime: Minimum execution time in secondsmaxTime: Maximum execution time in secondstotalTime: Total execution time across all executions in secondslastExecutionTime: Execution time of the most recent execution in secondslastExecution: Timestamp of the most recent execution
Cache Metrics
Cache metrics provide information about the performance of the caching system:
hits: Number of cache hitsmisses: Number of cache misseshitRate: 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 secondsavgMissTime: Average time to determine a cache miss in secondstotalHitsTime: Total time spent on cache hits in secondstotalMissesTime: Total time spent on cache misses in seconds
Configuration
The configuration section shows the current performance monitoring settings:
enabled: Whether performance monitoring is enabledincludeInResponse: Whether to include performance data in GraphQL responseslogAllMetrics: Whether to log all metrics or only slow onesslowQueryThreshold: Threshold in seconds for identifying slow queriesslowResolverThreshold: 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
logAllMetricsis enabled - Only metrics that exceed the slow thresholds are logged when
logAllMetricsis 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:
- Decorator Pattern: The
@track_resolverdecorator tracks resolver execution times - Mixin Classes: The
TimedSessionMixinadds performance tracking to SQLAlchemy sessions - 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:
- Monitor Regularly: Check performance metrics regularly to identify trends and issues
- Focus on Slow Resolvers: Pay special attention to resolvers with high average or maximum execution times
- Optimize Cache Usage: Use the cache hit/miss rates to optimize your caching strategy
- Set Appropriate Thresholds: Adjust the slow query and resolver thresholds based on your application's requirements
- Use in Development: Enable detailed metrics in development to catch performance issues early
- Limit in Production: In production, consider disabling
includeInResponseandlogAllMetricsto 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.