---
title: "WMS vs WMTS vs WFS: A Picture, Fast Tiles, or the Raw Data (and When to Use Each)"
description: "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."
keywords: "WMS vs WMTS vs WFS, Web Map Service, Web Map Tile Service, Web Feature Service, OGC web services, GIS, geospatial, map tiles, vector data, WMS WMTS difference, geoportal, raster vs vector maps, when to use WFS, web mapping, tile cache"
created_at: "2026-07-02T15:00:00"
post_type: "anonym_post"
content_type: "technical_article"
---

![Banner](./banner.webp)

<div style="display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: center; padding: 1rem 1.25rem; margin: 1.5rem 0 2rem; background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%); border: 1px solid #e2e8f0; border-radius: 12px;">
  <span style="font-size: 0.95rem; font-weight: 600; color: #475569; margin-right: 0.25rem;">Prefer to watch?</span>
  <a href="https://youtube.com/shorts/NHG3tJVTDmM" target="_blank" rel="noopener noreferrer" style="display: inline-flex; align-items: center; gap: 0.4rem; padding: 0.55rem 1rem; border-radius: 8px; background: #ff0000; color: #ffffff; font-size: 0.875rem; font-weight: 600; text-decoration: none;">▶ WMS vs WMTS vs WFS in 90 seconds</a>
  <a href="https://t.me/SoftwareEngineerBlog" target="_blank" rel="noopener noreferrer" style="display: inline-flex; align-items: center; gap: 0.4rem; padding: 0.55rem 1rem; border-radius: 8px; background: #229ed9; color: #ffffff; font-size: 0.875rem; font-weight: 600; text-decoration: none;">✈ Telegram</a>
</div>

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](https://www.ogc.org/) 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:

```http
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:

```http
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:

```http
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
```

```json
{
  "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

<table>
  <thead><tr><th></th><th>WMS</th><th>WMTS</th><th>WFS</th></tr></thead>
  <tbody>
    <tr><td>What you get</td><td>Rendered image (raster)</td><td>Rendered image (raster)</td><td>Vector features + attributes</td></tr>
    <tr><td>Rendering</td><td>On the fly, per request</td><td>Pre-rendered tiles</td><td>Client-side (you render)</td></tr>
    <tr><td>Speed</td><td>Moderate (live render)</td><td>Fast (cacheable tiles)</td><td>Slower (heavier payload)</td></tr>
    <tr><td>Flexibility</td><td>High (any area/style/CRS)</td><td>Low (baked grid + styles)</td><td>High (query/restyle/edit)</td></tr>
    <tr><td>Clickable / queryable</td><td>No (pixels)</td><td>No (pixels)</td><td>Yes (real objects)</td></tr>
    <tr><td>Caching</td><td>Hard (bespoke renders)</td><td>Trivial (fixed tiles)</td><td>Manual</td></tr>
    <tr><td>Typical use</td><td>Custom overlays, print</td><td>Fast basemaps</td><td>Feature editing, analysis</td></tr>
  </tbody>
</table>

---

## 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.](https://youtube.com/shorts/NHG3tJVTDmM)
