Skip to content

Refresh issue in Local Models #21

Closed

Description

@mlonsk

I found that, even when I can connect to the local instance using the server name and the database name, the refresh command like refresh --type full is not reliable. The CLI shows that it refreshed successfully but the actual data on the Power BI model wasn't refreshed. I can see that the refresh completed very fast, indicating that it didn't refresh anything. The Refresh using the Power BI UI is more reliable that the model has been refreshed.

Originally posted by @uniznguyen in #4

Activity

  1. mlonsk commented on Jul 31, 2026

    @mlonsk
    CollaboratorAuthor

    @uniznguyen Thank you for reporting this in. I have created a new issue here to track this and have been looking into reproducing it, but have so far been unsucesful.

    I could verify the following

    The TMSL we generate for a full model refresh is correct:

    te refresh -s localhost:<port> -d <db> --type full --dry-run
    { "refresh": { "type": "full", "objects": [ { "database": "<db>" } ] } }
    

    Running that against an Import-mode model on a local Power BI Desktop instance (Desktop 2.156) does reach Desktop's Power Query engine and does report failures correctly. So the command isn't skipping execution outright.

    Could you tell us the following to help us confirm the behaviour:

    1. Storage mode of the tables. Import, DirectQuery, Direct Lake, mixed, or a live connection to a published model? If any table is DirectQuery-only or Direct Lake, that alone would explain an instant no-op.

    2. The trace log: te refresh --type full --trace refresh.log and attach refresh.log. If it's empty or shows no per-table progress events, the engine did no work — which confirms the diagnosis.

    3. Your Power BI Desktop version (Help > About).
      If you can also manage it:

    4. The exact command you ran, and the output of the same command with --dry-run added.

    5. How you confirmed the data was stale?

    6. Partition refresh timestamps immediately before and after the refresh:

      te query -s localhost:<port> -d <db> --no-validate "select [Name], [State], [RefreshedTime] from $SYSTEM.TMSCHEMA_PARTITIONS"
      

    Thank you

  2. uniznguyen commented on Aug 4, 2026

    @uniznguyen

    I use Claude to write this comment after 4 refreshes and logs.

    Repro details: refresh reports success, data never commits, visuals stay stale

    I'm hitting this exact issue on a local Power BI Desktop instance. Posting a
    concrete repro with 4 separate --trace captures of the same command against
    the same model.

    Environment

    • Tabular Editor CLI version: 0.6.0.12612
    • OS: Windows
    • Connection method: te connect localhost:61949 <database>
    • Model: local PBIP/TMDL project connected to a live Power BI Desktop session
    • Command run: te refresh --type full --trace refreshN.log

    What I'm seeing

    The CLI exits without any error and reports the refresh as successful. However,
    report visuals in the connected Power BI Desktop session do not reflect the
    new data afterward — values that are supposed to change stay exactly where
    they were pre-refresh.

    Trace evidence across 4 runs

    All 4 runs pulled identical row counts from source for every table
    (confirming the source read itself is fine and consistent):

    Table Rows (all 4 runs)
    FactSales 1,450,123
    FactInvoices 1,288,013
    FactTransfers 779,327
    FactPurchases 578,243
    DimInventorySupplier 289,568
    DimItem 645,435
    DimCustomer 39,200
    DimShipTo 54,827
    FactInventory 10,830–10,831

    Despite the data reading correctly every time, 3 of 4 runs never reached
    End TableProcess
    , and the one that did (refresh2, second capture) still
    stopped mid-TableCalculate without a closing Commit:

    Run ReadRows completes Reaches End TableProcess Reaches Commit Reaches End Commit
    refresh1 (baseline, ~4m12s) ✅ ✅ ❌ ❌
    refresh2 (attempt 1, ~43s) ❌ (cut off mid-index) ❌ ❌ ❌
    refresh2 (attempt 2, ~34s) ✅ ✅ ✅ (begins) ❌ (stops mid-TableCalculate)
    refresh3 (~39s) ✅ ❌ ❌ ❌
    refresh4 (~44s) ✅ ❌ ❌ ❌

    Notably, my baseline run (refresh1) — the one where everything actually
    appeared to work — also never shows a Commit section at all in the trace
    log
    , which makes me unsure whether the trace log itself reliably captures
    that phase, or whether commit genuinely isn't happening consistently.

    A specific stall pattern

    In runs 3 and 4, there's a consistent, unexplained gap of 15–21 seconds
    between the last fact table (FactSales/FactInvoices) finishing ReadRows
    and DimItem finishing its ReadRows — with nothing else logged in between:
    refresh3.log:
    00:24.510 End ReadRows FactSales 1,450,123
    ...(15s gap, nothing logged)...
    00:39.212 End ReadRows DimItem-... 645,435

    refresh4.log:
    00:23.328 End ReadRows FactSales 1,450,123
    ...(21s gap, nothing logged)...
    00:44.332 End ReadRows DimItem-... 645,435

    After that stall, both runs go straight into ColumnProcess/DictEncoding
    for DimItem and the trace log simply stops there — no TableProcess end,
    no error, no exception.

    Question for the maintainers

    1. Is it expected that Commit/End Commit doesn't reliably show up in
      --trace output, or should a successful refresh always show a closing
      Commit block?
    2. Is there a known issue with the commit/finalize phase not completing
      against a local Power BI Desktop connection specifically (vs. a
      deployed workspace)?
    3. Happy to share the full log files if useful — trimmed excerpts are above,
      but I have all 4 complete traces available.

    Let me know what else would help narrow this down — happy to run more
    captures with additional flags (--debug, etc.) if that'd help.

  3. uniznguyen commented on Aug 10, 2026

    @uniznguyen

    refresh.log.

    This is the refresh.log where CLI fails to refresh the FactSales table.

    Image

    There is no way it can fetch at the speed of 1.1 mil rows per second

  4. added
    in-progressCurrently being worked on
    and removed on Aug 11, 2026
  5. mlonsk commented on Aug 11, 2026

    @mlonsk
    CollaboratorAuthor

    Hi @uniznguyen
    Thank you for the detailed reports and the extra log. I have the past week on and off been trying to reproduce the lack of refresh of local Power BI models on my end, but have not been able to.

    Your report has, however, let us identify 2 bugs around how the trace is handled, which matters to the conclusions we can draw so far, so let me go through them.

    1. Your "1.1 million rows per second" observation is correct, and it's a bug in our trace.

    You're right that the number is impossible. It's an artifact of how we timestamp trace events.

    The timestamps in the log are taken from a client-side stopwatch at the moment our event handler runs, not from the trace event's own CurrentTime. This also means the per-table Query / Read / Total / Rows-s columns in the refresh summary table, the progress block in --output-format json, and the diagnostic hints are all derived from the wrong clock. In the worst case the CLI will print "Throughput: 1,100,000 rows/s -- excellent" off a fabricated number, which is actively misleading. We'll fix all of that together.

    1. The missing Commit / End TableProcess is also our bug

    We stop and drop the server-side trace the instant the TMSL command returns, without waiting for the server to flush what it has already buffered. Given the flush interval we can measure in your own log (~0.7s), the tail of every refresh gets systematically cut off.

    Your attached log ends at five consecutive Begin IndexSegment with no matching End, no End ColumnProcess, no End TableProcess, and no Commit. That is exactly the shape this bug produces.

    These two bugs do not, however, mean that the refresh commit is not happening for the following reasons.

    1. A server-side trace is a passive observer. Starting, stopping or dropping it cannot abort or otherwise affect a refresh that is already running.
    2. Execute() is synchronous. It only returns once the TMSL command, including its commit, has completed on the server. If it returned and the XMLA result carried no errors, the commit happened. Our trace simply stopped recording before it observed it.

    To be clear about what this does and does not settle: it explains away the evidence, but it does not prove your refresh worked. A truncated log on a broken clock can't tell us either way, and why we'd like a few measurements that don't come from our trace at all.

    Further debugging steps

    The most useful thing is to investigate the truth from outside the CLI's trace output. Here are several ways of doing this. We would appreciate it if you could try to investigate this on your end.

    1. Partition timestamps immediately before and immediately after a refresh.
    te query --no-validate "select [Name], [State], [RefreshedTime] from $SYSTEM.TMSCHEMA_PARTITIONS"
    
    1. A DAX aggregate before and after, so we can see whether the data actually moved:
    EVALUATE ROW("n", COUNTROWS(FactSales), "latest", MAX(FactSales[<your date column>]))
    
    1. Could you clarify what "stale" means in your case — the report visuals in the connected Power BI Desktop session, or the model data itself? Desktop serves visuals from a cached result set and is not notified when an external tool refreshes the model over the XMLA port. Visuals staying put after a successful external refresh is expected Desktop behavior rather than a CLI fault, so we would like to rule that out first. Checks 1 and 2 answer this directly, since they query the engine rather than the report.

    2. Storage mode per table, and whether any table has an incremental refresh policy. If a policy exists, te refresh --type full sends applyRefreshPolicy: true by default, which refreshes only the policy window — that can look indistinguishable from "nothing happened". Worth retrying with:

    te refresh --type full --apply-refresh-policy false
    
    1. An independent trace, if you are able: DAX Studio's All Queries or SQL Server Profiler attached to the same local port, with the CLI's --trace switched off. That removes our logging entirely from the evidence chain.

    Until we have fixed the timestamp and truncation issues, our own --trace output isn't reliable enough to diagnose from, so items 1–3 are where we would focus first.

    Thanks again for the detail and for helping us out in this way.
    Best regards
    Morten

  6. uniznguyen commented on Aug 11, 2026

    @uniznguyen

    Let me give you a quick response on how I know the model was not refreshed: I changed the unit cost in the FactSales table (line_item) in the ERP system. Then I refreshed the Power BI using the CLI. But I don't see the change happening in my visual table. So I used the Table View in Power BI to look at the raw FactTales, and confirmed that the unit_cost in the line item wasn't changed. I tried to use the CLI to refresh a few more times, but the model wasn't changed. I ended up using the Refresh function in Power BI desktop to refresh, then it changed.

    So your DAX EVALUATE ROW("n", COUNTROWS(FactSales), "latest", MAX(FactSales[]) might not be useful as the changes I'm looking for is an update of existing data.

    Regarding the 1 mil rows per second, although your trace is a bug, what matters is: the refresh process is taking so quick for the FactSales table. Even if I run the SQL directly (not through Power Query/Power BI), it takes me 33 seconds to run.

    My model doesn't implement incremental refresh. And every table is in Import mode

    Thanks for your response.

  7. mlonsk commented on Sep 25, 2026

    @mlonsk
    CollaboratorAuthor

    Hi @uniznguyen
    In the newest versions of the TE CLI this issue should be fixed. Feel free to give it a test and let us know.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    in-progressCurrently being worked on

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions