Guides
Fix Retool Table Column Order with a Dynamic Query

If you're building a pivot table or any report with a dynamic number of columns in Retool, you've likely hit this wall: your query returns data in the correct column order, but the Table component displays columns in the wrong sequence. This is the Retool table column order dynamic query problem, and it catches a lot of developers off guard. The short answer is that Retool's table component persists column positions internally — and that memory overrides whatever order your query actually returns.
Why Retool Tables Ignore Your Query's Column Order
Retool's Table component is designed to let users drag and reorder columns manually. To preserve those preferences across query runs, Retool stores each column's position internally. This is useful for static schemas, but it becomes a real problem when your schema is dynamic — for example, when columns are dates generated at query time.
Here's the specific scenario: your first query run returns 2021-01-01, 2021-02-01, 2021-03-01. Retool registers these columns and remembers their order. When your next query run introduces 2021-01-10 — a date that logically falls between existing columns — Retool appends it to the end of the table instead of inserting it in the correct position. The JSON coming back from your query is in the right order. The table just doesn't care.
This is a known limitation confirmed by the Retool team. There is currently no built-in property or configuration toggle that lets you force the table to re-read and respect column order from the query on every run.
What Doesn't Work (So You Can Stop Trying)
- Setting column order via
Dynamic column settings— useful for renaming or styling columns, but it does not control position. - Reordering keys in your query's returned JSON — Retool ignores the key order once column positions are cached.
- Using a JS transformer to reorder the data object — the transformer output affects data values, not the table's internal column ordering state.
The Best Workaround: A Synthetic Header Row
The most practical workaround — and the one recommended by Retool staff in the community — is to decouple your column headers from the actual table column names. Instead of relying on Retool to render your dynamic column labels correctly, you inject a fake "header" as the first data row and give your real columns neutral, static names like numeric indices (col_1, col_2, col_3, etc.).
Here's how to implement it step by step:
- Step 1: In your query or a JS transformer, determine the correct ordered list of dynamic column names (e.g., sorted dates).
- Step 2: Rename your actual data columns to static keys —
col_0,col_1,col_2, and so on — mapped in the correct order. - Step 3: Prepend a synthetic first row to your dataset where each
col_Nvalue is the intended human-readable column label (e.g.,"2021-01-10"). - Step 4: In your
Tablecomponent, useDynamic column settingsto style this first row differently — a background color or bold font — so it visually reads as a header. - Step 5: Set the actual Retool column header labels to something neutral or hide them, since your synthetic row is now acting as the visible header.
This approach works because the static column keys (col_0, col_1, etc.) never change — so Retool's column memory is never triggered. The order of displayed data is entirely controlled by your query logic.
Alternative: Build a Custom Component
If you're on a Retool plan that includes Custom Components, you can build a fully controlled table using a library like AG Grid or Tanstack Table embedded in an iframe. This gives you 100% programmatic control over column order, rendering, and state. It's the most powerful solution but also the most engineering-heavy. For most internal tools, the synthetic header row approach will get you unblocked faster.
Is Retool Going to Fix This?
This thread was converted to a feature request on the Retool community forum, and it has accumulated multiple +1 votes from users with identical use cases — particularly teams building date-pivoted reports and dashboards. As of now, Retool has not shipped a native fix. If this is a blocker for your team, upvoting the original community thread is the best way to push it up the priority list.
Key Takeaways
- Retool's
Tablecomponent persists column positions and will not reorder them based on query output alone. Dynamic column settingscan rename and style columns but cannot set their order.- The recommended workaround is to use static column keys and inject a synthetic header row with the correct dynamic labels.
- For full control, a
Custom Componentwith a third-party table library is the nuclear option. - If this is a pain point, vote for the feature on the Retool community forum to help prioritize a proper fix.
Dynamic column ordering is one of those gaps that only surfaces when you're building something slightly beyond a standard CRUD app — exactly the kind of thing internal tool builders run into. The synthetic header workaround isn't pretty, but it ships, and that's what matters at 11pm.
Ready to build?
We scope, design, and ship your Retool app — fast.