Based on your application, it was faster to add another observe and reset counter 1 using the global assignment operator <<- . I also changed the plot, so these are indexes with an index. Look at the similar problems that people have here . NB: In some of my applications, I also have a pause button, when the user presses the start button twice, you can achieve this by checking whether the index of the button is divisible by two or not, since each time the button is pressed, it increases by one .
I studied your application, make sure that you collect unnecessary observers, as you may have a shortage of memory (look at the memory profile through the task manager). Look at this example here , alternately you can configure the logout function to a session where the client will be disconnected after n number of minutes.
rm(list = ls()) library(shiny) ui <- (fluidPage( # Application title headerPanel("Cost Explorer"), sidebarPanel( actionButton("goButton", "Go!"), actionButton("reset", "Reset"), sliderInput("myvar", label=h6("Variability of cost"),min=0, max=50, value=10) ), mainPanel(plotOutput(outputId="tsplot")) )) server <- (function(input, output, session) { # initialize reactive values ts <- reactiveValues(cost=rep(NA,100), year=(2010:2109), counter=1) output$tsplot <- renderPlot({ plot(ts$year[1:ts$counter], ts$cost[1:ts$counter], xlim=c(2010,2110), ylim=c(-200,200), xlab="Year", ylab="Cost (US Dollars)", type="l", main="Forecasted Cost Time series") }) observe({ isolate({ if (ts$counter==1){ ts$cost[ts$counter]=50 #initial cost } if (ts$counter > 1){ ts$cost[ts$counter]=ts$cost[ts$counter-1]+rnorm(1,0,input$myvar) } ts$counter=ts$counter+1 }) if (((isolate(ts$counter) < 100)) & (input$goButton > 0)){ invalidateLater(200, session) } }) observe({ if (input$reset > 0){ ts$counter <<- 1 } }) }) runApp(list(ui = ui, server = server))