Repository navigation
Issue: memory leak when using rowTransaction #338
Copy link
Copy link
Closed
Labels
bugsomething brokensomething broken
Description
Description:
when using rowTransactions. Every time a transaction is performed, a memory leak occurs. This is due to new row references being created while old ones aren’t being removed, leading to an increase in Shallow Size and Retained Size.
Sample code:
import dash_ag_grid as dag
from dash import Dash, html, Input, Output, State, ctx, no_update, callback
app = Dash(__name__)
rowData = [
{"id": "Toyota_0", "make": "Toyota", "model": "Celica", "price": 35000},
{"id": "Ford_0", "make": "Ford", "model": "Mondeo", "price": 32000},
{"id": "Porsche_0", "make": "Porsche", "model": "Boxster", "price": 72000},
]
columnDefs = [
{"field": "id", "checkboxSelection": True, "headerCheckboxSelection": True},
{"field": "make"},
{"field": "model"},
{"field": "price", "cellRenderer": "agAnimateShowChangeCellRenderer", },
]
columnDefs_leet = [
{"field": "id", 'headerName': "DSFDS","checkboxSelection": True, "headerCheckboxSelection": True},
{"field": "make", 'headerName': "DFA VXC" ,},
{"field": "model", 'headerName': "DSS Z",},
{"field": "price", 'headerName': "SDEAW", "cellRenderer": "agAnimateShowChangeCellRenderer", },
]
app.layout = html.Div(
[
html.Button("Update column def", id="btn-header-names-toggle"),
html.Button("Add Rows", id="btn-client-side-transaction-add"),
html.Button("Add Rows at index 2", id="btn-client-side-transaction-add-index-2"),
html.Button("Update selected", id="btn-client-side-transaction-update"),
html.Button("Remove Selected", id="btn-client-side-transaction-remove"),
html.Button("Clear", id="btn-client-side-transaction-clear"),
html.Button("Start Over", id="btn-client-side-transaction-start"),
dag.AgGrid(
id="client-side-transaction",
rowData=rowData,
columnDefs=columnDefs,
columnSize="sizeToFit",
dashGridOptions={"rowSelection": "multiple"},
getRowId="params.data.id"
),
],
)
@callback(
Output("client-side-transaction", "columnDefs"),
Input("btn-header-names-toggle", "n_clicks"),
State("client-side-transaction", "columnDefs"),
prevent_initial_call=True
)
def toggle_cols(n, column_defs):
if n % 2 == 0:
return columnDefs
return columnDefs_leet
# print('Changing column def')
# for col in column_defs:
# col["valueFormatter"] = {"function": "'* ' + params.value + ' *'"}
# print(column_defs)
# return columnDefs
@callback(
Output("client-side-transaction", "rowData"),
Input("btn-client-side-transaction-clear", "n_clicks"),
Input("btn-client-side-transaction-start", "n_clicks"),
)
def update_rowdata(*_):
return [] if ctx.triggered_id == "btn-client-side-transaction-clear" else rowData
@callback(
Output("client-side-transaction", "rowTransaction"),
Input("btn-client-side-transaction-add", "n_clicks"),
Input("btn-client-side-transaction-add-index-2", "n_clicks"),
Input("btn-client-side-transaction-update", "n_clicks"),
Input("btn-client-side-transaction-remove", "n_clicks"),
State("client-side-transaction", "selectedRows"),
prevent_initial_call=True,
)
def update_transaction(n1, n2, n3, n4, selection):
if ctx.triggered_id in ["btn-client-side-transaction-add", "btn-client-side-transaction-add-index-2"]:
newRows = [
{
"id": row["make"] + '_' + str((n1 or 0) + (n2 or 0)),
"make": row["make"], "model": row["model"], "price": row["price"]
} for row in rowData
]
return (
{"add": newRows}
if ctx.triggered_id == "btn-client-side-transaction-add"
else {"add": newRows, 'addIndex': 2}
)
if selection:
if ctx.triggered_id == "btn-client-side-transaction-update":
for row in selection:
row["price"] = row["price"] + n3
return {"update": selection}
if ctx.triggered_id == "btn-client-side-transaction-remove":
return {"remove": selection}
# If no rows selected, no grid update
return no_update
if __name__ == "__main__":
app.run(debug=True)
Ref: https://dash.plotly.com/dash-ag-grid/client-side#transaction-updates
FYI: There is also an increase of memory use with rowData but it is smaller
Reactions are currently unavailable
Metadata
Metadata
Labels
bugsomething brokensomething broken

Activity
BSd3v commentedon Feb 3, 2025
Hello @andre996,
Is there another way to measure this rather than having to watch the network tab?
andre996 commentedon Feb 20, 2025
Hey @BSd3v, after some research, I found memlab to check for memory leaks. It's a tool developed by Facebook that is used to find memory leaks in JS code.
Memlab takes a snapshot of the app when it loads after it interacts, and when it returns to the main stage. In this case, the interaction was to add 12 rows in batches of 3. As you can see on the report the memory usage passed from 17MB to 18.4MB, this change was caused by two types of leaks, the first one I think is related to adding the 12 rows to the ag-grid, and the second is caused by the number of time the
add 3 rowsbutton was clickedSample app and code used to generate the report
data_leaking.zip
BSd3v commentedon Apr 27, 2026
@andre996
I ran memlab on the latest version of AG Grid, and it isnt finding any memory leaks, even in this scenario. Can you confirm?
andre996 commentedon Apr 30, 2026
@BSd3v yes, it looks like there is no leak