Join the Shiny Community every month at Shiny Gatherings

Shiny Dashboard Scaling Thumbnail

Video: How to Scale Shiny Dashboards


This presentation was a part of a joint virtual webinar with Appsilon and RStudio entitled “Enabling Remote Data Science Teams”. Find a direct link to the presentation here

How to Scale a Shiny App to Hundreds of Users

In this video, Appsilon’s VP of the Board & Co-Founder Damian Rodziewicz explains best practices for scaling Shiny applications in production. Damian explains three of the areas that Appsilon focuses on to scale Shiny applications: Frontend LeveragingExtracting Computations, and creating a stable and scalable Architecture.

R Shiny applications are fast by default but can become extremely slow if they are not properly built, especially when there are tens or hundreds of people using them. Having best practices in mind from the beginning of the project can save you a lot of trouble down the line. 

Learn More: Why You Should Use R Shiny For Enterprise Application Development

Vertical and Horizontal Scaling

If you intend to scale your Shiny app, there are two concepts we need to explore: Vertical Scaling and Horizontal Scaling.

Horizontal and vertical scaling
It’s best to start with proper vertical scaling &#8211; you should make sure the application is fast and robust in the first place while running on a single machine, and then you can add as many machines as you want in an efficient way (horizontal scaling). With this in mind, let&#8217;s return to our three previously mentioned areas: Leveraging Frontend, Extracting Computations, and Setting the Architecture. </span></p> <p><div data-gatsby-image-wrapper="" style="position:relative;overflow:hidden;display:inline-block;vertical-align:top" class="gatsby-image-wrapper gatsby-image-wrapper-constrained aligncenter size-large wp-image-5608 inline-gatsby-image-wrapper" data-reactroot=""><div style="max-width:1024px;display:block"><img alt="" role="presentation" aria-hidden="true" src="data:image/svg+xml;charset=utf-8,%3Csvg height=&#x27;485&#x27; width=&#x27;1024&#x27; xmlns=&#x27;http://www.w3.org/2000/svg&#x27; version=&#x27;1.1&#x27;%3E%3C/svg%3E" style="max-width:100%;display:block;position:static"/></div><div aria-hidden="true" data-placeholder-image="" style="height:100%;left:0;position:absolute;top:0;width:100%"></div><picture><source type="image/avif" data-srcset="/_gatsby/image/f49f0d92e85bfb71f1cee0a5192af2c5/3f56187836aeb1f8f8aa2956b056d23f/002-1.avif?u=https%3A%2F%2Fwordpress.appsilon.com%2Fwp-content%2Fuploads%2F2020%2F10%2F002-1.png&amp;a=w%3D256%26h%3D121%26fm%3Davif%26q%3D90&amp;cd=2020-10-14T07%3A26%3A17 256w,/_gatsby/image/f49f0d92e85bfb71f1cee0a5192af2c5/6e396a524714d158274be0bede20c512/002-1.avif?u=https%3A%2F%2Fwordpress.appsilon.com%2Fwp-content%2Fuploads%2F2020%2F10%2F002-1.png&amp;a=w%3D512%26h%3D242%26fm%3Davif%26q%3D90&amp;cd=2020-10-14T07%3A26%3A17 512w,/_gatsby/image/f49f0d92e85bfb71f1cee0a5192af2c5/e5bae8640996dfd95f09e6a4ee795181/002-1.avif?u=https%3A%2F%2Fwordpress.appsilon.com%2Fwp-content%2Fuploads%2F2020%2F10%2F002-1.png&amp;a=w%3D1024%26h%3D485%26fm%3Davif%26q%3D90&amp;cd=2020-10-14T07%3A26%3A17 1024w" sizes="(min-width: 1024px) 1024px, 100vw"/><source type="image/webp" data-srcset="/_gatsby/image/f49f0d92e85bfb71f1cee0a5192af2c5/c674f3e1580676f55ec44be93925947b/002-1.webp?u=https%3A%2F%2Fwordpress.appsilon.com%2Fwp-content%2Fuploads%2F2020%2F10%2F002-1.png&amp;a=w%3D256%26h%3D121%26fm%3Dwebp%26q%3D90&amp;cd=2020-10-14T07%3A26%3A17 256w,/_gatsby/image/f49f0d92e85bfb71f1cee0a5192af2c5/19b2cf52d56c0aa48b9c87f2336fd150/002-1.webp?u=https%3A%2F%2Fwordpress.appsilon.com%2Fwp-content%2Fuploads%2F2020%2F10%2F002-1.png&amp;a=w%3D512%26h%3D242%26fm%3Dwebp%26q%3D90&amp;cd=2020-10-14T07%3A26%3A17 512w,/_gatsby/image/f49f0d92e85bfb71f1cee0a5192af2c5/e30d12f147b3332f2032b82e6a5cacf5/002-1.webp?u=https%3A%2F%2Fwordpress.appsilon.com%2Fwp-content%2Fuploads%2F2020%2F10%2F002-1.png&amp;a=w%3D1024%26h%3D485%26fm%3Dwebp%26q%3D90&amp;cd=2020-10-14T07%3A26%3A17 1024w" sizes="(min-width: 1024px) 1024px, 100vw"/><img data-gatsby-image-ssr="" data-wp-inline-image="2" data-main-image="" style="height:100%;left:0;position:absolute;top:0;transform:translateZ(0);transition:opacity 250ms linear;width:100%;will-change:opacity;opacity:0" sizes="(min-width: 1024px) 1024px, 100vw" decoding="async" loading="lazy" data-src="/_gatsby/image/f49f0d92e85bfb71f1cee0a5192af2c5/2e376bedc156f6e40d93fe0f94f85f17/002-1.png?u=https%3A%2F%2Fwordpress.appsilon.com%2Fwp-content%2Fuploads%2F2020%2F10%2F002-1.png&amp;a=w%3D256%26h%3D121%26fm%3Dpng%26q%3D90&amp;cd=2020-10-14T07%3A26%3A17" data-srcset="/_gatsby/image/f49f0d92e85bfb71f1cee0a5192af2c5/2e376bedc156f6e40d93fe0f94f85f17/002-1.png?u=https%3A%2F%2Fwordpress.appsilon.com%2Fwp-content%2Fuploads%2F2020%2F10%2F002-1.png&amp;a=w%3D256%26h%3D121%26fm%3Dpng%26q%3D90&amp;cd=2020-10-14T07%3A26%3A17 256w,/_gatsby/image/f49f0d92e85bfb71f1cee0a5192af2c5/85a85ce88d28ae199368d1412178d84d/002-1.png?u=https%3A%2F%2Fwordpress.appsilon.com%2Fwp-content%2Fuploads%2F2020%2F10%2F002-1.png&amp;a=w%3D512%26h%3D242%26fm%3Dpng%26q%3D90&amp;cd=2020-10-14T07%3A26%3A17 512w,/_gatsby/image/f49f0d92e85bfb71f1cee0a5192af2c5/faffd722693af2d10167037d685bd917/002-1.png?u=https%3A%2F%2Fwordpress.appsilon.com%2Fwp-content%2Fuploads%2F2020%2F10%2F002-1.png&amp;a=w%3D1024%26h%3D485%26fm%3Dpng%26q%3D90&amp;cd=2020-10-14T07%3A26%3A17 1024w" alt="Pillars of making Shiny apps faster"/></picture><noscript><picture><source type="image/avif" srcSet="/_gatsby/image/f49f0d92e85bfb71f1cee0a5192af2c5/3f56187836aeb1f8f8aa2956b056d23f/002-1.avif?u=https%3A%2F%2Fwordpress.appsilon.com%2Fwp-content%2Fuploads%2F2020%2F10%2F002-1.png&amp;a=w%3D256%26h%3D121%26fm%3Davif%26q%3D90&amp;cd=2020-10-14T07%3A26%3A17 256w,/_gatsby/image/f49f0d92e85bfb71f1cee0a5192af2c5/6e396a524714d158274be0bede20c512/002-1.avif?u=https%3A%2F%2Fwordpress.appsilon.com%2Fwp-content%2Fuploads%2F2020%2F10%2F002-1.png&amp;a=w%3D512%26h%3D242%26fm%3Davif%26q%3D90&amp;cd=2020-10-14T07%3A26%3A17 512w,/_gatsby/image/f49f0d92e85bfb71f1cee0a5192af2c5/e5bae8640996dfd95f09e6a4ee795181/002-1.avif?u=https%3A%2F%2Fwordpress.appsilon.com%2Fwp-content%2Fuploads%2F2020%2F10%2F002-1.png&amp;a=w%3D1024%26h%3D485%26fm%3Davif%26q%3D90&amp;cd=2020-10-14T07%3A26%3A17 1024w" sizes="(min-width: 1024px) 1024px, 100vw"/><source type="image/webp" srcSet="/_gatsby/image/f49f0d92e85bfb71f1cee0a5192af2c5/c674f3e1580676f55ec44be93925947b/002-1.webp?u=https%3A%2F%2Fwordpress.appsilon.com%2Fwp-content%2Fuploads%2F2020%2F10%2F002-1.png&amp;a=w%3D256%26h%3D121%26fm%3Dwebp%26q%3D90&amp;cd=2020-10-14T07%3A26%3A17 256w,/_gatsby/image/f49f0d92e85bfb71f1cee0a5192af2c5/19b2cf52d56c0aa48b9c87f2336fd150/002-1.webp?u=https%3A%2F%2Fwordpress.appsilon.com%2Fwp-content%2Fuploads%2F2020%2F10%2F002-1.png&amp;a=w%3D512%26h%3D242%26fm%3Dwebp%26q%3D90&amp;cd=2020-10-14T07%3A26%3A17 512w,/_gatsby/image/f49f0d92e85bfb71f1cee0a5192af2c5/e30d12f147b3332f2032b82e6a5cacf5/002-1.webp?u=https%3A%2F%2Fwordpress.appsilon.com%2Fwp-content%2Fuploads%2F2020%2F10%2F002-1.png&amp;a=w%3D1024%26h%3D485%26fm%3Dwebp%26q%3D90&amp;cd=2020-10-14T07%3A26%3A17 1024w" sizes="(min-width: 1024px) 1024px, 100vw"/><img data-gatsby-image-ssr="" data-wp-inline-image="2" data-main-image="" style="height:100%;left:0;position:absolute;top:0;transform:translateZ(0);transition:opacity 250ms linear;width:100%;will-change:opacity;opacity:0" sizes="(min-width: 1024px) 1024px, 100vw" decoding="async" loading="lazy" src="/_gatsby/image/f49f0d92e85bfb71f1cee0a5192af2c5/2e376bedc156f6e40d93fe0f94f85f17/002-1.png?u=https%3A%2F%2Fwordpress.appsilon.com%2Fwp-content%2Fuploads%2F2020%2F10%2F002-1.png&amp;a=w%3D256%26h%3D121%26fm%3Dpng%26q%3D90&amp;cd=2020-10-14T07%3A26%3A17" srcSet="/_gatsby/image/f49f0d92e85bfb71f1cee0a5192af2c5/2e376bedc156f6e40d93fe0f94f85f17/002-1.png?u=https%3A%2F%2Fwordpress.appsilon.com%2Fwp-content%2Fuploads%2F2020%2F10%2F002-1.png&amp;a=w%3D256%26h%3D121%26fm%3Dpng%26q%3D90&amp;cd=2020-10-14T07%3A26%3A17 256w,/_gatsby/image/f49f0d92e85bfb71f1cee0a5192af2c5/85a85ce88d28ae199368d1412178d84d/002-1.png?u=https%3A%2F%2Fwordpress.appsilon.com%2Fwp-content%2Fuploads%2F2020%2F10%2F002-1.png&amp;a=w%3D512%26h%3D242%26fm%3Dpng%26q%3D90&amp;cd=2020-10-14T07%3A26%3A17 512w,/_gatsby/image/f49f0d92e85bfb71f1cee0a5192af2c5/faffd722693af2d10167037d685bd917/002-1.png?u=https%3A%2F%2Fwordpress.appsilon.com%2Fwp-content%2Fuploads%2F2020%2F10%2F002-1.png&amp;a=w%3D1024%26h%3D485%26fm%3Dpng%26q%3D90&amp;cd=2020-10-14T07%3A26%3A17 1024w" alt="Pillars of making Shiny apps faster"/></picture></noscript><script type="module">const t="undefined"!=typeof HTMLImageElement&&"loading"in HTMLImageElement.prototype;if(t){const t=document.querySelectorAll("img[data-main-image]");for(let e of t){e.dataset.src&&(e.setAttribute("src",e.dataset.src),e.removeAttribute("data-src")),e.dataset.srcset&&(e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset"));const t=e.parentNode.querySelectorAll("source[data-srcset]");for(let e of t)e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset");e.complete&&(e.style.opacity=1)}}

Below is a quick rundown of each area, but please reference the video presentation for a full explanation. Above all, it’s important to Make the Shiny Layer Thin. This means that Shiny should only be doing the work that it’s best at – creating an interface between R and your browser.  The rest of the work (such as interactivity or long computations) should be offloaded to the browser or handled by the database, etc.

Leverage Frontend 

  • Render inputs in UI and update them in Server – failing to do so requires re-rendering entire widgets, which makes the application run slower.
  • Run inline JavaScript – the package shinyjs allows you to do this. It’s best used to make some quick toggles.
  • Set all actions in JavaScript – handle things like button clicks with JavaScript, not with Shiny.
  • Learn more about leveraging frontend in Shiny here.

Extract Computations 

  • Remote API – the Plumber library is excellent for doing this. You rarely need the entire dataset when using the application, so why not filter it down first and then load only what you need when you need it. This logic is easily wrapped into a simple API.
  • Use a database – loading large files in memory isn’t scalable for tens/hundreds/thousands of users. Using a database can dramatically improve the performance of Shiny apps. 
  • Are heavy calculations freezing your Shiny app? Appsilon is developing the shiny.worker package to address this problem. shiny.worker is currently still under development, but it can be made available to clients and non-profit organizations on request.

Architecture

  • RStudio Connect and Shiny Server Open Source allows you to deploy applications quickly.
  • We use Ansible – to provision the whole infrastructure, install requirements, RStudio Connect, and deploy the application.
  • Learn more about the options for deploying Shiny apps here.

Learn more

Appsilon is an RStudio Full Service Certified Partner. We are global leaders in Shiny and we specialize in advanced enterprise Shiny apps for Fortune 500 companies. Reach out to us at hello@wordpress.appsilon.com.