Type to search columns, filters, options, and extensions.

to navigate · Enter to open · Esc to close

Documentation

Web Profiler Panel

What the DataTables profiler collects and what the panel shows

The bundle ships a Symfony Web Profiler panel showing which tables a page rendered, how they were configured, and what each server-side Ajax query cost.

Enabling it

Nothing to configure: DataTablesBundle imports config/profiler.php when kernel.debug is true, so the panel is available in the dev environment as soon as symfony/web-profiler-bundle is installed.

composer require --dev symfony/profiler-pack

What is collected

Two services do the work. DataTableProfiler accumulates records during the request; DataTableCollector is the Symfony data collector that hands them to the profiler at the end of it. DataTableProfiler carries the kernel.reset tag, so its records are cleared between requests — required under a worker runtime such as FrankenPHP worker mode, where the service survives the request.

Rendered tables

collectRenderedTable() is called by the render_datatable() Twig function, with the table’s id and class, the entity class, whether it is server-side, the column count, the enabled extensions (key, class, whether the extension is layout-aware, and its serialized options), the Ajax option, whether inline rows are present and how many, the data controller, the forwarded query parameters, every column’s serialized definition, the names of the columns static permission filtering removed, the declared filters, the resolved Mercure configuration, and the edit-modal template and adapter.

Ajax queries

collectAjaxQuery() is called by AbstractDataTable::getResponse(), whichever route reached it — the bundle’s own Ajax controller or a custom endpoint calling handleRequest() / getResponse() directly. Each record holds:

FieldDescription
classThe AbstractDataTable subclass that answered
tokenThe table query parameter identifying the table
requestThe parsed DataTableRequest, plus a flattened summary
recordsTotal / recordsFilteredRow counts read back from the JSON payload
durationMsTime spent building the response
providerClassThe resolved data provider’s class
entityClassThe entity behind the table, when it has one
rowCountRows in the returned payload
payloadBytesResponse body size
httpStatusResponse status code

What the panel shows

The toolbar entry shows the rendered-table count, the Ajax-query count, and the summed Ajax duration. The panel itself has two halves.

Rendered DataTables starts with a summary table — id, class, server side, columns, extensions, inline rows — then one detail block per table: class, entity, server-side flag, inline row count, data controller, Ajax options, forwarded query parameters, edit modal, Mercure, the resolved columns, the columns denied by permission filtering, the enabled extensions with their options, and the declared filters.

AJAX queries lists one block per query: the table class, token, data provider, entity, record counts, returned rows, payload size, HTTP status, duration, and draw counter, followed by the pagination, global search, ordering, per-column search and ColumnControl criteria the request carried, the submitted filter values, and the raw DataTableRequest behind a collapsible toggle.

Limitations

The panel is a no-op for a table built outside the container. DataTableInfrastructure::createDefault() supplies no profiler, and every consumer treats it as optional, so a hand-built AbstractDataTable renders and answers normally but records nothing. In practice this only affects tests and scripts — Symfony’s autoconfiguration injects the container’s infrastructure into every subclass it manages.

A client-side table performs no Ajax query, so it appears under Rendered DataTables only.

See Also