Skip to main content

The BitDive Developer Workflow

BitDive provides deep runtime insights. To maximize their value, we recommend integrating BitDive into your daily development process. Here is the recommended workflow for developing features, fixing bugs, and optimizing performance.


πŸ— The 12-Step Change Cycle​

Follow these steps when making any code changes to a service monitored by BitDive.

1. Understand the Target​

Identify exactly what you are trying to change:

  • The target service and method.
  • The expected impactβ€”which methods, REST calls, or SQL queries will be affected.

2. Discover the Environment​

Go to your HeatMap Dashboard to see the system's overview over the last 30 minutes. Take note of the methods that currently exist, their average latency, error rates, and sub-call breakdown.

3. Run Tests BEFORE Change (Baseline)​

Before touching the code, capture the "green" baseline. Run your Maven or Gradle test suite:

mvn test

Check the results in BitDive:

  • Which tests passed?
  • Which tests already failed? (Pre-existing failures are not your fault, so take note not to incorrectly attribute them to your changes later.)

This is your absolute baseline measurement.

4. Study Traces​

Trigger the target method to capture a BEFORE trace. Navigate to the trace summary and review the execution tree, timing, and SQL queries. BitDive shows you what your code actually does, not just what it says it does.

5. Make the Code Change​

Proceed with your bug fix or feature development.

6. Build & Deploy​

Deploy the modified service locally or in your dev environment (like Docker).

7. Get the AFTER Trace​

Call the modified endpoint, wait a few seconds, and locate your new trace.

8. Compare BEFORE vs AFTER Traces​

Use BitDive's trace comparison tool to diff the two traces. Confirm that the actual runtime difference matches your intended change:

  • Are there new or removed SQL queries?
  • Were old errors fixed?
  • Are there any N+1 alerts?

9. Run Tests AFTER Change​

This is the critical step to find out what broke:

mvn test

10. Analyze Test Results​

Compare your BEFORE baseline with your AFTER results. Categorize every failure:

  1. Already failed BEFORE: A pre-existing failure. Skip it.
  2. Was βœ…, now ❌, in the changed method: This is an expected deviation. Your change caused it. Update your test baseline.
  3. Was βœ…, now ❌, NOT in the changed method: This is an unexpected regression. You accidentally broke a downstream dependency. Investigate.

11. Update Expected Deviations​

If the failure was expected (Option #2), you need to update your testing baseline in BitDive:

  • You can regenerate the tests just for the specific method (surgical).
  • Or, if many methods changed, update your entire test group with the newly captured traces.

Never update tests for unexpected regressions. Fix the code.

12. Final Verification​

Run mvn test one last time. Your tests should pass, and the pass/fail count should be identical to your Step 3 baseline.


⚑ Performance Optimization​

BitDive can also be used specifically to fix performance bottlenecks like N+1 queries and sequential logic execution.

Phase 1: Detection​

Look at the HeatMap Dashboard and search for:

  • Very high average response times (ms) on a single method.
  • A high SQL count relative to the call count, indicating an N+1 query pattern.
  • Persistent 5xx errors.
  • Queue imbalancesβ€”when the system produces messages significantly faster than it consumes them.

Phase 2: Diagnosis​

Drill into a trace for the sluggish method.

  • N+1 Queries: If you see the exact same SQL query repeated 20 times in a loop with different parameters, this is a classic N+1 problem.
  • Sequential Bottlenecks: Are multiple independent database or REST calls running one after the other instead of in parallel?
  • Slow Query: A single SQL query is taking most of the latency block. You probably need an index.

Phase 3: Compare Fixes​

Make the performance optimization and compare the old and new traces:

  1. Fixing Parallelization: Instead of sequentially awaiting IO:

    long c1 = repo1.count();
    long c2 = repo2.count();

    Consider running independent calls asynchronously via CompletableFuture.

  2. Fixing N+1 Queries: Instead of fetching loops:

    students.forEach(s -> s.setCourses(courseRepo.findByStudentId(s.getId())));

    Consider batch querying:

    Map<Long, List<Course>> coursesMap = courseRepo.findByStudentIds(studentIds);
    students.forEach(s -> s.setCourses(coursesMap.get(s.getId())));

After deploying the fix, place the two Trace IDs side-by-side in BitDive and verify the timing difference!