✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
🐇 Announcing Dash VTK for 3d simulation graphics. Check out the March webinar.

Updating hundreds of buttons slow

Hi,

I’m creating a dashboard that has hundreds of buttons in it that I wish to have updated in real-time (every 5 seconds). However, once I get beyond a couple hundred buttons, the callback generation in the app becomes extremely slow and the actual running of the callbacks is even slower (causing the page to basically time out).

The callback function itself is not computationally heavy (just returning a value from a dictionary for each button) so it seems that the slowdown is coming from dash trying to update all of the buttons simultaneously.

I have tried creating the callbacks individually for each button as well as creating a “Refresh” button that outputs to all of the other buttons, but both scenarios result in extremely slow performance.

Is this expected behavior? Are there limits to how many callbacks you can effectively run within a dash app?

Edit: Here is a minimal example where trying to refresh the page results in a timeout and even launching the app takes several seconds. Once launched, it never becomes responsive.

import dash
import dash_bootstrap_components as dbc
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
from dash.exceptions import PreventUpdate

def button_callback(n, text):
    if n is None:
        raise PreventUpdate
    else:
        return [text + '1']

def create_buttons():
    rows = []
    for x in range(30):
        cols = []
        for y in range(30):
            cols.append(dbc.Col(dbc.Button(str(x) + ',' + str(y), id=str(x) + ',' + str(y))))
        rows.append(dbc.Row(cols))

    return rows

app = dash.Dash(external_stylesheets=[dbc.themes.BOOTSTRAP])

app.layout = dbc.Container([
    dcc.Interval(id='update', interval=5000, n_intervals=0),
    html.Div(create_buttons()),
])

for x in range(30):
    for y in range(30):
        app.callback(Output(str(x) + ',' + str(y), 'children'), [Input('update', 'n_intervals'), Input(str(x) + ',' + str(y), 'id')])(button_callback)

if __name__ == "__main__":
    app.run_server(port=8888)

Thanks