6 min read

How to Track JQL Queries in Mixpanel

If you're running JQL queries against your Jira instance, you need visibility into execution patterns and performance. Mixpanel lets you track when queries run, how long they take, and who's executing them so you can optimize database load and understand user workflows.

Capture Query Execution Events

Start by firing an event every time a JQL query executes. Include metadata about the query, execution time, and outcome.

Initialize Mixpanel and Track Query Events

Load the Mixpanel SDK and call mixpanel.track() whenever a query runs. Include the project key, query category, and execution time as properties.

javascript
import mixpanel from 'mixpanel-browser';

mixpanel.init('YOUR_PROJECT_TOKEN');

const trackJQLExecution = async (queryString, projectKey) => {
  const startTime = performance.now();
  
  try {
    const results = await jiraClient.runJql(queryString);
    const executionTime = performance.now() - startTime;
    
    mixpanel.track('JQL Query Executed', {
      project_key: projectKey,
      query_category: categorizeQuery(queryString),
      execution_time_ms: executionTime,
      result_count: results.length,
      success: true
    });
  } catch (error) {
    const executionTime = performance.now() - startTime;
    mixpanel.track('JQL Query Executed', {
      project_key: projectKey,
      query_category: categorizeQuery(queryString),
      execution_time_ms: executionTime,
      success: false,
      error_code: error.code
    });
  }
};

function categorizeQuery(jql) {
  if (jql.includes('assignee')) return 'assignee_filter';
  if (jql.includes('status')) return 'status_filter';
  if (jql.includes('created') || jql.includes('updated')) return 'date_filter';
  return 'complex';
}
Track query execution with timing and categorization

Identify Users and Set User Properties

Call mixpanel.identify() before tracking queries so Mixpanel knows which user ran each query. Set user properties like role and query frequency for later segmentation.

javascript
const trackUserQuery = (userId, userRole, queryCount) => {
  mixpanel.identify(userId);
  
  mixpanel.people.set({
    'user_role': userRole,
    'queries_this_session': queryCount,
    'is_power_user': queryCount > 10,
    'last_query_at': new Date()
  });
  
  mixpanel.track('JQL Query Executed', {
    user_id: userId,
    user_role: userRole
  });
};
Link queries to specific users and track user behavior
Tip: Always capture execution_time_ms from the start. You'll need this later to identify performance problems. Don't store full JQL strings—categorize them instead to keep your event data clean.

Analyze Query Patterns and Performance

Once events are flowing, use Mixpanel's analysis tools to find trends, slow queries, and heavy users.

Build a Query Performance Report in Segmentation

Go to Events > Segmentation, select JQL Query Executed, and create a breakdown by query_category. Add a formula card to calculate average execution_time_ms per category. This shows which query types are slowest.

javascript
// Example: detecting and flagging slow queries in real-time
const SLOW_QUERY_THRESHOLD = 2000; // 2 seconds

const trackQueryWithSlowFlag = async (queryString, projectKey) => {
  const startTime = performance.now();
  const results = await runQuery(queryString);
  const executionTime = performance.now() - startTime;
  
  mixpanel.track('JQL Query Executed', {
    project_key: projectKey,
    execution_time_ms: executionTime,
    is_slow: executionTime > SLOW_QUERY_THRESHOLD
  });
  
  // Separately track slow queries for alerting
  if (executionTime > SLOW_QUERY_THRESHOLD) {
    mixpanel.track('Slow Query Detected', {
      project_key: projectKey,
      execution_time_ms: executionTime,
      query_type: categorizeQuery(queryString)
    });
  }
};
Separate slow queries for easier monitoring

Create a Cohort for Power Users

In Data Management > Cohorts, create a cohort where queries_this_session > 5 to identify users who run many queries in one session. Use this cohort to segment other metrics and understand high-engagement users.

javascript
// Track cumulative query count per session
let sessionQueryCount = 0;

const trackQueryWithSessionCount = (queryString, projectKey) => {
  sessionQueryCount++;
  
  mixpanel.people.set({
    'queries_per_session': sessionQueryCount
  });
  
  mixpanel.track('JQL Query Executed', {
    query_number_in_session: sessionQueryCount,
    project_key: projectKey,
    query_category: categorizeQuery(queryString)
  });
  
  // Reset on session end
};

// In Mixpanel, use this cohort in Funnels:
// Step 1: JQL Query Executed (where queries_per_session >= 5)
// Step 2: Issue Created or Updated
Build session-level query counts for cohort creation
Watch out: If you track every unique JQL string, you'll create thousands of event properties. Always categorize queries (e.g., 'assignee_filter', 'complex') rather than storing raw JQL.

Set Up Alerts and Dashboards

Monitor query health continuously by building a dashboard and setting alerts for performance degradation.

Create a Custom Dashboard

Click Dashboards > Create Dashboard and add three cards: (1) Event Totals for JQL Query Executed, (2) Funnels to track query → action workflows, and (3) Formulas for average execution time by query_category.

javascript
// Track the full workflow: query → decision → action
const trackQueryWorkflow = (userId, queryType) => {
  mixpanel.identify(userId);
  
  // Step 1: User runs query
  mixpanel.track('JQL Query Executed', {
    query_type: queryType,
    workflow_stage: 'query'
  });
  
  // Later: User acts on results
  mixpanel.track('Issue Updated', {
    triggered_by_query: true,
    original_query_type: queryType,
    workflow_stage: 'action'
  });
};

// In Mixpanel, create a funnel:
// 1. JQL Query Executed
// 2. Issue Updated (where triggered_by_query = true)
Connect queries to downstream user actions

Monitor Query Success Rate

Add a Formulas card that calculates (success = true) / total to track your overall query success rate. Set an alert if it drops below 95%.

javascript
// Track failures separately for easier alerting
const trackQueryResult = async (queryString, projectKey) => {
  try {
    const results = await executeQuery(queryString);
    mixpanel.track('JQL Query Executed', {
      success: true,
      result_count: results.length,
      project_key: projectKey
    });
  } catch (error) {
    mixpanel.track('JQL Query Failed', {
      error_message: error.message,
      error_code: error.statusCode,
      project_key: projectKey
    });
    
    // This makes alerting clearer: spike in "JQL Query Failed" = problem
  }
};
Separate successes and failures for clearer alerting
Tip: Set your dashboard to a 7-day view so you can spot performance trends. If average execution time creeps up over a week, your query load or data is growing.

Common Pitfalls

  • Logging raw JQL strings creates too many unique event property values and makes Mixpanel slow. Always categorize queries (status_filter, assignee_filter, etc.) instead.
  • Forgetting to track execution_time_ms means you can't diagnose slow queries later. Capture timing from the start, even for quick queries.
  • Not calling mixpanel.identify() before tracking queries means you lose the user context and can't segment by user_id or user_role.
  • Setting the slow query threshold too low (e.g., 500ms) creates alert noise; too high (e.g., 30s) misses real problems. Calibrate based on your infrastructure's SLA.

Wrapping Up

By tracking JQL query executions, categorizing them, and monitoring execution time in Mixpanel, you gain visibility into which queries drive user engagement and which ones bottleneck your system. Use segmentation to spot slow queries, create cohorts for power users, and build dashboards to track trends. If you want to track this automatically across tools, Product Analyst can help.

Track these metrics automatically

Product Analyst connects to your stack and surfaces the insights that matter.

Try Product Analyst — Free