Separately worth checking your preStop hook and how the app handles SIGTERM, because the same symptom has a second common cause. If the entrypoint is sh -c "myapp", PID 1 is the shell and it does not forward SIGTERM, so the container waits out the full grace period and gets SIGKILLed every time. That gives you a consistent 30 second delay rather than 20 minutes though, so it is not your case here.
Marcus Oyelaran
@tabula_rasa_dev
Six months into learning Python after a decade in warehouse logistics. I ask a lot of beginner questions and I write down every answer.
This is the underrated one. I have had reports go from 20 seconds to instant purely by collapsing the default state of one hierarchy.
Row count is almost never the problem at that size. Two things to check before anything else.
First, run Performance Analyzer, expand the slow visual, copy the DAX query out, and run it in DAX Studio with server timings on. If most of the time is formula engine rather than storage engine, you have a measure doing row-by-row work.
Second, look for FILTER(BigTable, ...) inside your CALCULATE calls. That materialises the whole table. Nine times out of ten it can be written as a plain predicate — CALCULATE([Sales], Sales[Channel] = "Retail") — and the time falls off a cliff. The other common killer is a bidirectional or many-to-many relationship between two large tables.
Also confirm which container was killed. kubectl describe pod gives last state per container, and in a pod with sidecars people routinely assume it was the main application when it was actually a proxy or a log agent with a much smaller limit.
Also confirm the measure is filtering on the date table's column and not the fact table's date column. Half the time people mark a proper date table, then write the time intelligence against Orders[OrderDate] out of habit and get results that are almost right, which is the worst kind of wrong.
Longer term, retry logic in the applications matters here too. DNS is not a guaranteed-instant service and a client that gives up on one failed lookup during a scale event will keep finding ways to page you. Not an argument against fixing the cluster side, just the other half.
The SUMX pattern above is right, but choose your iterator table carefully. Iterate over the dimension column you are displaying, not over the fact table. SUMX(VALUES(Dim[Attribute]), [Measure]) does as many evaluations as there are visible rows. SUMX(Fact, ...) does twelve million. Same answer, wildly different render time.
kubectl describe pod on the Pending pod usually says this out loud in the events — something like "node(s) had volume node affinity conflict". It is one of the more helpful messages Kubernetes produces and it is easy to skip past when you are looking at the PVC instead of the pod.
Split the difference so you are not gone for a week. Pull out the three biggest text columns into dimensions first — usually customer, product, geography — measure the file size, and stop if that gets you enough headroom. Most of the win lives in a handful of columns.
Blue-green earns its keep when you are jumping several versions, changing something fundamental like the CNI, or you have stateless workloads and a proper GitOps setup that can rebuild the whole cluster from a repo. Two minor versions with StatefulSets is not that case. It is a good thing to build toward, but not a good thing to do for the first time under a deadline.