WMS vs WMTS vs WFS: A Picture, Fast Tiles, or the Raw Data (and When to Use Each)

WMS, WMTS, and WFS are three OGC web services that answer the same question — how does map data get from a server into your browser — in three completely different ways. WMS renders a flat PNG picture on the fly (flexible, but just pixels). WMTS is that same picture pre-sliced into cacheable tiles (fast, but rigid). WFS sends the actual vector geometry plus attributes (clickable and queryable, but heavier). Here's the mental model, the trade-offs, and a clear rule for which to reach for.

Banner

Prefer to watch? ▶ WMS vs WMTS vs WFS in 90 seconds ✈ Telegram

Open any government geoportal, toggle a few layers, and you'll see three acronyms show up over and over: WMS, WMTS, and WFS. They're all OGC web services, they all serve map data, and they're all three letters apart — so it's easy to assume they're competing versions of the same thing.

They aren't. They answer three different questions about how map data gets from a server into your browser. Get the distinction and a whole class of "why is my map slow / why can't I click this / why does it look wrong at this zoom" problems disappears.

The one-line mental model:

  • WMS hands you a picture. You ask for an area, the server renders a flat PNG on the fly and sends the image.
  • WMTS is that same picture, pre-sliced into a fixed grid of ready-made tiles the browser just grabs.
  • WFS sends the actual data — the real vector geometry of each feature plus its attributes.

Or, the analogy that sticks: WMS is a photo of a spreadsheet, WMTS is that photo cut into a jigsaw so it loads fast, and WFS is the actual spreadsheet you can open and edit.


WMS — the Web Map Service: render me a picture

With WMS you send the server a bounding box, a size, a projection, and a list of layers, and it renders a flat raster image on the fly and hands it back. It's a GetMap request:

GET /geoserver/wms?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap
    &LAYERS=parcels
    &CRS=EPSG:3857
    &BBOX=828000,5931000,830000,5933000
    &WIDTH=1024&HEIGHT=1024
    &FORMAT=image/png HTTP/1.1

You get back a 1024×1024 PNG of exactly that area, styled however the server (or your STYLES/SLD) says.

The appeal is flexibility: any arbitrary area, any projection, any styling, composited server-side into one image. The catch is twofold. First, it's just pixels — there's no parcel #42 in there you can click, only colored dots. Second, because every request is a bespoke render, it re-renders on every pan and zoom, which puts load on the server and can feel sluggish.


WMTS — the Web Map Tile Service: the same picture, pre-sliced

WMTS serves the same kind of raster image, but instead of rendering an arbitrary box on demand, the whole map is pre-cut into a fixed pyramid of square tiles (typically 256×256) at set zoom levels. Your client just asks for tiles by z/x/y grid coordinates:

GET /geoserver/gwc/service/wmts?SERVICE=WMTS&REQUEST=GetTile
    &LAYER=parcels&TILEMATRIXSET=EPSG:3857
    &TILEMATRIX=14&TILEROW=5701&TILECOL=8642
    &FORMAT=image/png HTTP/1.1

Because the tiles are identical for everyone and align to a fixed grid, they're trivially cacheable — by the browser, a CDN, or a tile cache like GeoWebCache. That's why slippy web maps feel instant: you're grabbing pre-baked images, often from an edge cache, not waiting on a live render.

The trade-off is rigidity. You only get the zoom levels, projection, and styles that were baked ahead of time. Want a custom style or an in-between zoom? It isn't in the cache. WMTS trades WMS's on-the-fly flexibility for speed and scale.


WFS — the Web Feature Service: give me the raw data

WFS doesn't send a picture at all. It sends the actual features — the real vector geometry plus each feature's attributes — usually as GML or GeoJSON. A GetFeature request:

GET /geoserver/wfs?SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature
    &TYPENAMES=parcels&OUTPUTFORMAT=application/json
    &BBOX=828000,5931000,830000,5933000,EPSG:3857 HTTP/1.1
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": { "type": "Polygon", "coordinates": [[[828100, 5931200], "…"]] },
      "properties": { "id": 42, "area_m2": 613, "land_use": "residential" }
    }
  ]
}

Now you have real objects, not pixels. You can click a parcel, read its ID and area, run a query ("all parcels over 500 m²"), measure, edit, and restyle it entirely client-side. WFS-T even lets you write features back.

The cost is weight. Vector geometry with attributes is far heavier than a compressed image, and rendering thousands of features in the browser is more work than dropping a PNG. WFS buys you interactivity and query power at the price of bytes and CPU.


The real differences

WMSWMTSWFS
What you getRendered image (raster)Rendered image (raster)Vector features + attributes
RenderingOn the fly, per requestPre-rendered tilesClient-side (you render)
SpeedModerate (live render)Fast (cacheable tiles)Slower (heavier payload)
FlexibilityHigh (any area/style/CRS)Low (baked grid + styles)High (query/restyle/edit)
Clickable / queryableNo (pixels)No (pixels)Yes (real objects)
CachingHard (bespoke renders)Trivial (fixed tiles)Manual
Typical useCustom overlays, printFast basemapsFeature editing, analysis

The trade-off is bigger than maps

Strip the geospatial labels off and WMS / WMTS / WFS are three answers to a universal serving question: do I compute the result on demand, serve a pre-computed cached artifact, or ship the raw data and let the client assemble it?

That same triangle shows up almost everywhere you serve data at scale:

  • Compute on demand (WMS-like) — flexible, always current, but you pay CPU on every request. Think server-side rendering per request, or an LLM generating a fresh answer every time.
  • Pre-compute and cache (WMTS-like) — fast and cheap to scale because the work is done once and reused, but rigid and potentially stale. Think a CDN of pre-rendered pages, materialized views, or a semantic/response cache in front of an LLM so repeated questions hit a baked answer instead of a fresh (and costly) generation.
  • Ship the raw data (WFS-like) — maximum flexibility for the client, heaviest payload. Think a REST/GraphQL API returning raw records, or RAG returning raw retrieved chunks and letting the model do the assembly.

The lesson transfers cleanly: caching a rendered artifact is fast but rigid; shipping raw data is flexible but heavy; rendering on demand sits in between. Whether it's map tiles or model responses, you're choosing where the work happens and who pays for it.


Which should you reach for?

  • Reach for WMTS when you want a fast, scalable basemap and a fixed set of styles/zooms is fine. It's the right default for the background layer everyone loads.
  • Reach for WFS when users need to click, query, measure, or edit features, or you need the raw geometry for client-side analysis.
  • Reach for WMS when you need flexible on-the-fly rendering — arbitrary areas, custom server-side styling, odd projections, or print-quality composites — and caching isn't the priority.

And like most "vs" arguments, the honest answer is you often use all three: WMTS for the fast basemap, WMS for a custom-styled overlay, and WFS for the one layer users actually interact with. There's no winner — just the right delivery mechanism for each layer.

Want the 90-second visual version? Watch the reel.

WMS vs WMTS vs WFS: A Picture, Fast Tiles, or the Raw Data (and When to Use Each) | Vahid Aghajani