After finding that most docker images and manuals seem to use quite outdated 
software versions and methods to import OSM data and render tiles from it, I 
decided my own image: 
[FacilMap/openstreetmap-tile-server](https://github.com/FacilMap/openstreetmap-tile-server).
 One thing that I still need to improve is the expiration of tiles. I wasn’t 
able to find any real-world examples using the new expire table feature (Gemini 
even insisted that such a feature does not exist), so my work on this is 
entirely based on the osm2pgsql user manual and my own thoughts.

So far I have defined a single expire table for my map style. I run the 
following bash script to expire the tiles from this table:
```bash
EXPIRE_MAP=mymap
EXPIRE_TABLE=mymap_expire
EXPIRE_WAIT=60
EXPIRE_DELETE_FROM=13

while true; do
        date="$(date -u +'%Y-%m-%dT%H:%M:%SZ')"
        if psql -Aqtc "select zoom || '/' || x || '/' || y from 
\"${EXPIRE_TABLE}\" where last < '${date}';" | render_expired -m 
"${EXPIRE_MAP}" -c /etc/renderd.conf -d "${EXPIRE_DELETE_FROM}"; then
                if ! psql -Aqtc "delete from \"${EXPIRE_TABLE}\" where last < 
'${date}';"; then
                        echo "Cleaning up expiration table failed." >&2
                fi
        else
                echo "Expiring tiles failed." >&2
        fi

        sleep "$EXPIRE_WAIT"
done
```

So I generate a list of tiles whose `last` time is at least one second before 
the current time (because more tiles might become expired in the current second 
after reading out the list). Then I expire this list of tiles (which can take 
several minutes depending on the configuration). If expiring the tiles 
succeeds, I delete all rows from the expire table whose `last` time is still at 
least one second before the time when I queried the table the first time. Any 
tiles that were expired (again) while the tile expiration was running would 
have a later `last` date now, so this way they will be handled (again) during 
the next iteration.

Firstly, I would like some feedback on my script. Is this how expiration is 
commonly done? One thing that I know I could still improve there is calling the 
expiration each time right after `osm2pgsql-replication` instead of in a 
separate infinite loop.

-----

Now to my actual question. I have one map where I render a large variety of way 
types at different zoom levels. On the one end of the spectrum, all motorways 
globally are rendered starting at zoom level 6. On the other end of the 
spectrum, most footways globally are rendered starting at zoom level 14. This 
is equivalent to the OSM Carto style, but I only render a small subset of it, 
which mostly consists of motorways, footpaths and some other roads.

Since rendering tiles takes quite long for this map on my server, especially at 
low zoom levels, I prerendered all tiles up to zoom level 9 and configured the 
expiration script to rerender expired tiles up to zoom level 9 as well and 
delete expired tiles for zoom levels above. To my surprise, this caused my 
server to basically be busy rerendering expired tiles all the time, causing 
significant CPU and memory/swap usage on my server. At first I was confused, 
since at zoom level 9 I only render motorways and a few major roads and I 
didn’t expect those to change so often, but now I think I understand what’s 
going on. Since I have only a single expire table that does not distinguish 
between zoom levels, a simple change to a footpath anywhere causes tiles 
containing it to be expired, even if those tiles are at a zoom level so low 
that they don’t actually contain that footpath. And I imagine small things like 
footpaths change in many places all the time, which is why so many tiles at 
zoom levels <= 9 keep getting expired that my server can barely keep up with 
it. So what I need is a more sophisticated mechanism for tile expiration where 
the minimum zoom level of a feature is considered when determining what tiles 
to expire.

I found out that I can configure a 
[`minzoom`](https://osm2pgsql.org/doc/manual.html#defining-and-using-expire-outputs)
 option for an expire table. Because I can only define it for the whole table, 
it means that I basically need one expire table per minimum zoom level. As a 
consequence, I also need one feature table per minimum zoom level that is 
connected to the expire table. Right now I have a single table for ways with a 
`highway` column to determine the way type. Now I will need separate 
`ways_minzoom6`, `ways_minzoom8`, `ways_minzoom9`, … tables with corresponding 
expire tables where each way type is put into the table corresponding to the 
minimum zoom level where it is rendered. I have several questions about this:
* Is there a technical reason why I cannot define the expire minzoom in the 
`:insert()` call instead of defining a fixed minzoom for the expire table? That 
would make my setup much easier, since I would be able to keep using a single 
way table and a single expire table.
* Might splitting up my ways into about 10 different tables have a negative 
impact on the rendering of my tiles? I don’t know enough details about how 
geospatial indexes work in PostGIS, but I could imagine that querying features 
from 10 different tables to render a tile would be slower than querying them 
from a single table?
* Are there examples of how to query and clear multiple expire tables in my 
expiration script? I imagine I need to adapt my postgres query to query all 
expire tables at the same time, but still return the tiles uniquely, since the 
same tile might appear in multiple tables. After the expiration I need to clear 
the tiles separately for each table, since I assume postgres does not allow 
deleting from multiple tables in one query.

-- 
Reply to this email directly or view it on GitHub:
https://github.com/osm2pgsql-dev/osm2pgsql/discussions/2495
You are receiving this because you are subscribed to this thread.

Message ID: <osm2pgsql-dev/osm2pgsql/repo-discussions/[email protected]>
_______________________________________________
Tile-serving mailing list
[email protected]
https://lists.openstreetmap.org/listinfo/tile-serving

Reply via email to