Skip to content

OpenTelemetry traces on server starting up #4381

Open

Description

@marcosnav

While testing the out-of-the-box features Shiny provides for OTel traces and logs in a few observability tools, I noticed that the very first span Shiny creates is session_start, and with a few more custom instrumentation I noticed there is a gap of time with unknown events between the call to shinyApp(ui, server) and the first session_start event.

There might be valuable information on the events happening while shiny starts up the server.

For example, similar code to the following snippet shows a span of ~12secs that happens just before session_start shows up.

.shiny_startup_span <- otel::start_span("shiny_framework_startup", attributes = list(app.instrumentation = "custom"))

server <- function(input, output) {
  otel::end_span(.shiny_startup_span)
  # ...
}

shinyApp(ui=ui, server=server)
Image

So there is a ~12s span of things happening in Shiny just after shinyApp is called and the server function is called.

Activity

  1. cpsievert commented on May 11, 2026

    @cpsievert
    Collaborator

    Hi @marcosnav, is this something you're noticing with a minimal Hello World Shiny app? Or is this something specific to a more complex app? If you are doing something like reading in lots of data at the top level of your server function, then that could explain the startup time here.

  2. marcosnav commented on May 13, 2026

    @marcosnav
    Author

    Hi @cpsievert, the shared example is a quite complex app. But the same can be seen in simple apps, like the one I'm sharing below.

    library(shiny)
    library(otel)
    library(otelsdk)
    
    ui <- fluidPage(
      titlePanel("Hello Shiny"),
      sidebarLayout(
        sidebarPanel(
          sliderInput("bins", "Number of bins:", min = 1, max = 50, value = 30)
        ),
        mainPanel(
          plotOutput("distPlot")
        )
      )
    )
    
    .shiny_startup_span <- otel::start_span(
      "shiny_framework_startup",
      attributes = list(app.instrumentation = "custom")
    )
    
    server <- function(input, output) {
      otel::end_span(.shiny_startup_span)
    
      output$distPlot <- renderPlot({
        x <- faithful$waiting
        bins <- seq(min(x), max(x), length.out = input$bins + 1)
        hist(x, breaks = bins, col = "steelblue", border = "white",
             main = "Old Faithful waiting times",
             xlab = "Waiting time (min)")
      })
    }
    
    shinyApp(ui = ui, server = server)
    Image
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Priority: LowLow-impact bug, docs polish, papercut, or unclear low-severity request.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions