Question About Tile Requests Not Being Cancelled in Cesium for Unity

While using Cesium for Unity, I noticed a behavior that I would like to better understand. I’m wondering whether this is an intentional design choice or if there are recommended optimization approaches.

Scenario

The behavior occurs in both of the following situations.

Case 1: Zooming Out Quickly (Low Level → High Level)

  1. The camera starts at a detailed level (e.g., Zoom Level 15), triggering many high-resolution tile requests.
  2. Before those requests complete, the camera quickly zooms out to a much higher level (e.g., Zoom Level 5).
  3. The previously requested detailed tiles are no longer needed for rendering.
  4. However, the requests continue downloading until completion.

Case 2: Zooming In Quickly (High Level → Low Level)

  1. The camera starts at a coarse level (e.g., Zoom Level 5).
  2. The camera quickly zooms in to a detailed level (e.g., Zoom Level 15).
  3. The previously requested low-resolution tiles are no longer the optimal representation for the current view.
  4. Those requests also continue until completion.

Based on network captures and logs, once a request has been issued, it appears to continue downloading even if the corresponding tile is no longer needed by the current view.

Questions

  • Is it the default behavior in Cesium Native / Cesium for Unity that issued tile requests are not cancelled?
  • When a tile is later determined to be unnecessary during tile selection, is it simply excluded from rendering while the network request continues?
  • Once a request has entered the IAssetAccessor or UnityWebRequest stage, does Cesium provide any cancellation mechanism?
  • Is this design primarily motivated by:
    • Better cache reuse?
    • Avoiding the overhead of cancelling and recreating connections?
    • Simpler request scheduling?
    • Other architectural considerations?
  • For scenarios involving rapid zooming or camera flights, are there recommended ways to reduce requests that ultimately will never be used?

My Current Understanding (Possibly Incorrect)

After reading some of the source code, my impression is that tile selection and asset requests have relatively independent lifecycles.

When a tile is no longer required:

  • The tile’s state may be updated;
  • It is no longer selected for rendering;
  • However, any network request already submitted to the AssetAccessor continues running;
  • The result may later be cached or discarded after completion.

I’m not sure whether this interpretation is accurate, so I would appreciate any clarification from people familiar with Cesium Native’s implementation.

Thanks in advance.

Hi @Astral-Yang - welcome to the Cesium community! Great first post — this is a really thorough and well-researched question.

Your understanding is essentially correct. Let me confirm each of your points with references to the source:

1. Yes, issued tile requests are not cancelled. This is the current default (and only) behavior in Cesium Native. The AsyncSystem that underpins all async work — including network requests through IAssetAccessor — currently has no concept of cancellation or reprioritization. Once a task is dispatched, it will run to completion. This is explicitly called out as a known limitation in cesium-native issue #789:

“Once runInWorkerThread (or similarly, thenInWorkerThread) is called, the task will run eventually (process exit notwithstanding)… There is no possibility of canceling or reprioritizing a task that hasn’t started yet.”

2. Correct — tiles are simply excluded from rendering. The tile selection pass and the request lifecycle are independent. When a tile is no longer needed, it is removed from the render list. There is no Cancelled state in the TileLoadState enum — tiles transition through Unloaded → ContentLoading → ContentLoaded → Done.

Recommended mitigations for rapid camera movement:

  • Lower Maximum Simultaneous Tile Loads (default is 20) — reducing this to 8–12 limits how many requests can become stale during fast movement
  • Disable Preload Ancestors and/or Preload Siblings if not needed for your use case — these cause speculative loads that compound the waste during rapid movement
  • Tune Loading Descendant Limit — a lower value prevents deep tree traversal before parent tiles have loaded, reducing wasted leaf-tile requests when zooming out
  • Control camera flight speed — giving tile selection time to stabilize between frames reduces overshoot

Future plans:

Cancellation support is being tracked as an enhancement in issue #789 (part of a larger effort in #1375), but there’s no timeline for implementation yet.

Hope this helps clarify the architecture! Feel free to follow up if you’d like to discuss tuning for your specific scenario.