Limitations
This page documents known limitations of Tracy and recommended workarounds.
Span Context Propagation
OpenTelemetry context propagation works automatically in structured coroutines (e.g., withContext, launch, async). However, certain concurrency patterns create execution boundaries that require manual context propagation.
For complete examples, see ContextPropagationExample.kt.
Kotlin Coroutines with runBlocking
Using runBlocking inside a suspend function creates a new execution boundary. Without manual propagation, child spans become detached and appear as separate traces.
Workaround: Use currentSpanContextElement to propagate context:
@Trace
suspend fun handleRequestInCoroutine(requestId: String) {
// runBlocking without context propagation would detach the trace
runBlocking(currentSpanContextElement(currentCoroutineContext())) {
processUserRequest(requestId)
}
}
Multi-Threading
Threads created via thread { ... } do not inherit the OpenTelemetry context.
Workaround: Capture and propagate the context manually:
suspend fun handleRequestInThread() {
val context = currentSpanContext(currentCoroutineContext())
thread {
context.makeCurrent().use {
// Code here will be part of the same trace
}
}
}
Local Functions
The @Trace annotation should not be used on local (nested) functions:
Reason: References to local functions do not implement the KCallable interface correctly in Kotlin. See KT-64873.
Inline Lambda Parameters
When tracing inline functions, inline lambda parameters are replaced with null in the captured arguments array.
Reason: Inline lambdas do not exist as objects at runtime — they are inlined directly into the call site.
Java Interoperability
The Tracy compiler plugin only transforms Kotlin code. Java methods cannot be annotated with @Trace.
Workaround: Use Manual Tracing for Java code: