Automatic Map Caching Not Working - Verified with "onResourceRequest" API
Environment
- Xcode version: 16.4
- iOS version: 18.4/18.5
- Devices affected: N/A
- Maps SDK Version: ~> 11.10
Observed behavior and steps to reproduce
We are loading custom vector tiles from MapTiler using tile URLs in the format https://api.maptiler.com/tiles/
We are also observing all tile requests using:
mapView.mapboxMap.onResourceRequest.observe { event in ... }
Despite successful tile fetches, every request appears to bypass the local cache and fetch from the network—even on repeated tile requests for the same {z}/{x}/{y} coordinates. The event.source consistently reports .network, with no observed .database or .fileSystem hits.
Additionally:
event.response?.etag is consistently nil
event.response?.expires is usually nil, occasionally provides a value
event.response?.notModified is always false
These indicators suggest that no server caching headers are being used, and no client-side caching is occurring, even though the documentation suggests that automatic caching should apply to all tile requests, including third-party sources like MapTiler.
Expected behavior
All successfully fetched tiles should be stored in the local cache and reused when the same tile coordinates are requested again. This includes vector tiles from third-party providers like MapTiler, assuming they return appropriate HTTP cache headers.
According to Mapbox documentation, the SDK maintains an automatic on-disk tile cache. While manual control over caching behavior is limited (besides disk size), the expectation is that standard tile fetches, even from external tile providers, leverage this caching layer, provided response headers allow it.
Notes / preliminary analysis
- No ETag, Expires, or Cache-Control headers are returned from MapTiler responses. This prevents Mapbox from caching the tiles.
- Without these headers, Mapbox treats each request as a fresh network fetch.
- This might be an issue with how MapTiler serves tile resources, not necessarily a Mapbox SDK bug.
- Mapbox documentation does not clearly state how third-party caching works when required headers are missing.
- Using onResourceRequest, we confirmed each tile load is a new network request with zero cache reuse.
Additional links and references
MapTiler tile example:
https://api.maptiler.com/tiles/
Basic output using onResourceRequest vector_logs.txt
Related SDK documentation: onResourceRequest Offline