How best to deploy an application for remote users

Hi all,

I’ve just discovered Bokeh, which I’m hoping to use to create an online application for manually labelling 3D data for my graduate students to use while they are isoloting from covid-19. The image data are large (the whole library is around 1TB), and contains sensitive (semi-anonymised) patient data, both of which limit my options for hosting it. This is currently a temporary fix to the covid-19 situation, but might be further developed if found to be useful and usable. I just need something that works well enough for the time being…

The main issue: The application runs very smoothly locally, but remote access seems to run considerably more slowly, even for what appear to be minor updates.

Currently it’s running on my Windows 10 Pro system, but I also have Ubuntu 18.04 running on another workstation that could be used.

The application currently:

  1. has three image widgets, each of which shows a slice from a 3D data set, sliced from a different orientation (e.g. x-y, z-y, etc; images are ~500x500 pixels);
  2. buttons to step through the image stack, in each orientation;
  3. two line plots on each image, showing the position of intersection planes with the other two images (i.e. just two simple line plots on each image);
  4. when images are double-clicked, points are added to a scatter plot, as part of the labelling process (this is more detailed, but beyond the scope of my question).

I think this is a fairly simple application, which I run with the ‘bokeh serve application.py’ command. When used on the local machine, it refreshes quickly and is very usable. However, I’ve tried a few approaches to deploying for remote users (in particular, using SSH tunneling, as described in the Bokeh documentation), but it runs painfully slowly… Currently it’s unusable, as each interaction taking around 6-10 seconds before seeing the relevent update in the application.

I’ve followed the Bokeh documentation for building the application: the document is generated once, when the page is first loaded, and updates to the plots and to the images (e.g. when the buttons are clicked) are coded within widget callbacks, and only the bare minimum is updated. I’m using a very basic directory structure, including an html template that simply embeds the application itself.

So - what would be my best option for hosting and running the server to get around the slow update time when used remotely? Is there an obvious approach or solution that I’m missing? Or is it simply that I’m limited by bandwidth?

Are all interaction slow or just the interactions that result in the 500x500 images updates? I would guess that it’s the latter because if you’re using image_rgba for 500x500 images, you end up transferring a few megabytes for each image. If the connection is slow, that’s what causing the issues.

In any case, what I would do is:

  • Open the problematic page
  • Open your browser’s developer tools on that page
  • Navigate to the Network tab
  • Filter for WebSocket connections (usually the WS filter button)
  • Refresh the page
  • There should be just one connection displayed - click on it
  • Click on the Messages tab and clear it
  • Make any interaction that results in a slow page update
  • Take note of all the WS messages that appear and about their timings

It should give you an idea about what the slowest things are.

Hard to say anything else without looking at the actual application.

Thanks, this was really useful, particularly the instructions for debugging loading times.

It turns out that because I was recreating the scatter plots that are overlaid on the images, whenever I added a new point, the whole figure (including the image) was being reloaded. Instead, I now just update the data source and it runs much faster as a result.

Glad I could help.

There’s a way to speed up image loading as well. You can expose some URL that generates images on demand, then then use image_url to get a JPEG or PNG or any other format that your browser supports that can create small files while preserving all the relevant details. But nothing like that is embedded in Bokeh itself at the moment.