Cache
The cache configuration defines the datastores where tiles should be stored/retrieved. We recommended you use a `multi`-tiered cache with a smaller, faster "near" cache first followed by a larger, slower "far" cache.
Description
Some cache options include built-in mechanisms for applying a TTL and maximum size. Any cache can be wrapped in the ttl cache to stop serving old entries, however that doesn’t delete them, so some options require an external cleanup mechanism if desired. Be mindful of this as some options may incur their own costs if allowed to grow unchecked. To delete entries covering a specific area, use the seed command with --purge.
When specifying a cache ensure you include the name parameter.
Choosing a cache
| Goal | Cache | Notes |
|---|---|---|
Develop or test locally |
Lost on restart and not shared between instances. Not for production |
|
Keep tiles on a single server’s filesystem |
Survives restarts. No cleanup, so use an external job |
|
Share a fast cache between instances |
Needs a matching datastore. Entries expire on their own |
|
Store a large or long-lived cache cheaply |
Shared and durable, but slower and billed by usage. Expiration requires external lifecycle configuration. |
|
Combine a small fast cache with a large slow one |
Tried in order on reads, written to all tiers. Keep to 2 or 3 tiers |
|
Stop serving old entries from a cache with no native expiration |
Wraps another cache. Doesn’t delete anything |
|
Keep each tenant’s tiles separate |
Wraps another cache. Only useful with tenant IDs from authentication |
|
Never cache a layer |
No-op cache. The |
Feature Comparison
| Cache | Shared between instances | Survives restart | Built-in TTL | Size limit | Needs datastore |
|---|---|---|---|---|---|
Memory |
No |
No |
Yes |
Yes |
Optional |
Disk |
No |
Yes |
No |
No |
No |
Redis |
Yes |
Depends on server |
Yes |
Depends on server |
Yes |
Memcached |
Yes |
No |
Yes |
Depends on server |
Yes |
S3 |
Yes |
Yes |
No |
No |
No |
Multi |
N/A |
N/A |
N/A |
N/A |
No |
TTL |
N/A |
N/A |
Yes |
N/A |
No |
Tenant |
N/A |
N/A |
N/A |
N/A |
No |
None |
N/A |
N/A |
N/A |
N/A |
No |
Overridable caches
Layer configurations have the ability to specify a cache parameter that overrides the default cache configuration. The top-level cache definition can be an array for specifying multiple distinct caches. This is different from the multi cache mentioned above. The multi cache allows combining multiple physical caches into a single cache config, but specifying an array under cache directly specifies multiple distinct cache configs.
Cache configurations are referred to by their id parameter, which defaults to the cache’s name. If you have multiple caches of the same kind, then id is required.
The first cache in the list will be used as the default cache. Any layers you want to use a different cache config should include cache: SOME_ID inside the layer definition. Any cache configuration can be referred to by ID in this way, including a cache that’s defined within another cache. Said another way, if you have a multi cache containing a disk cache and a memcached cache, a layer can be configured to refer to just the memcached cache.
If you don’t want to use the first cache in the list as your default, you can specify a defaultcache parameter at the very top-level of your configuration. This parameter takes the ID of the cache to use as your default.
There is no deduplication of cache configurations. That means if you have two identical memory caches defined, each will be a totally separate cache with their own memory allocations and capacity. This goes for all other cache types. If you need to define a cache multiple times (for example to be used under different multi, ttl, or tenant setups) it’s recommended you utilize datastores.
|
Example
-
YAML
-
JSON
cache:
- id: tenanted
name: tenant
cache:
name: multi
tiers:
- name: memory
datastore: tiles
- name: s3
bucket: my-tile-cache
- name: none
defaultcache: multi (1)
layers:
- id: public (2)
provider:
name: proxy
url: https://example.com/{z}/{x}/{y}.png
- id: per-user
cache: tenanted (3)
provider:
name: proxy
url: https://example.com/private/{z}/{x}/{y}.png
- id: uncached
cache: none (4)
provider:
name: proxy
url: https://example.com/live/{z}/{x}/{y}.png
datastores: ...
| 1 | Every layer uses the multi cache unless it picks another. It caches in memory first and then falls back on an S3 bucket. |
| 2 | public doesn’t set a cache, so it uses the default. |
| 3 | per-user uses the tenanted cache. That’s the same multi cache underneath, but entries are segregated by tenant. |
| 4 | uncached uses the no-op none cache. Alternatively, the skipcache parameter avoids needing to define a none cache at the top level. |
{
"cache": [
{
"id": "tenanted",
"name": "tenant",
"cache": {
"name": "multi",
"tiers": [
{
"name": "memory",
"datastore": "tiles"
},
{
"name": "s3",
"bucket": "my-tile-cache"
}
]
}
},
{
"name": "none"
}
],
"defaultcache": "multi", (1)
"layers": [
{
"id": "public", (2)
"provider": {
"name": "proxy",
"url": "https://example.com/{z}/{x}/{y}.png"
}
},
{
"id": "per-user",
"cache": "tenanted", (3)
"provider": {
"name": "proxy",
"url": "https://example.com/private/{z}/{x}/{y}.png"
}
},
{
"id": "uncached",
"cache": "none", (4)
"provider": {
"name": "proxy",
"url": "https://example.com/live/{z}/{x}/{y}.png"
}
}
],
"datastores": [ ... ]
}
| 1 | Every layer uses the multi cache unless it picks another. It caches in memory first and then falls back on an S3 bucket. |
| 2 | public doesn’t set a cache, so it uses the default. |
| 3 | per-user uses the tenanted cache. That’s the same multi cache underneath, but entries are segregated by tenant. |
| 4 | uncached uses the no-op none cache. Alternatively, the skipcache parameter avoids needing to define a none cache at the top level. |