Ecosystem services with InVEST, part 1 of 8
Ecosystem service models: the ideas
What an ecosystem service model is, how InVEST turns a land use map and a few tables into maps of carbon, habitat, water, sediment, nutrients and pollination, how Terraflux runs InVEST's models, and a first run on four of them at once.
- Level
- Beginner
- Time
- 35 min
- 11. The ideas
- 22. Carbon
- 33. Habitat quality
- 44. Water yield
- 55. Sediment
- 66. Nutrients
- 77. Seasonal water
- 88. Pollination
A forest stores carbon, shelters species, takes water from the soil and holds the soil on the slope. Clear it for pasture and all four change at once: less carbon, less habitat, more water running off, more mud in the river. Ecosystem service models put numbers on those changes, map by map, so that a land use plan, a restoration project or a scenario of the future can be compared on more than its hectares. This series teaches the seven models of InVEST that Terraflux runs: carbon storage, habitat quality, annual water yield, sediment retention, nutrient retention, seasonal water yield and crop pollination. In this first part you will learn what these models have in common, what they need and what they can and cannot tell you, and you will run four of them on one landscape, for today and for a scenario of 2040.
The idea#
Ecosystem services are the benefits people obtain from ecosystems: food and timber, clean water, a stable climate, pollination, recreation. The phrase became widely known when Costanza et al. (1997) put a (much debated) price on the services of the whole biosphere. What changed the practice of conservation was less the global price than a local question: if we change the land here, what do we gain and what do we lose, and where? To answer it you need models that start from the thing decision makers actually change, the map of land use, and end at something people care about.
Tallis and Polasky (2009) called these models production functions: functions that take the state of an ecosystem (here, mostly its land cover) and give the amount of a service it provides. The Natural Capital Project, a partnership led from Stanford University, built a free set of them, InVEST (Integrated Valuation of Ecosystem Services and Tradeoffs; Natural Capital Alliance, 2026), and showed with them how a river basin's land use plans trade carbon, species and commodities against each other (Nelson et al., 2009). Guerry et al. (2015) review how such models have since moved from research into the decisions of governments and companies.
Key idea: a land use map plus a table by class
Every InVEST model in this series has the same skeleton:
- a land use map (a raster, a grid of square cells, each holding an integer code: 1 forest, 2 pasture...);
- a table by class, one row per code, with the numbers the model needs for that class: tons of carbon per hectare, how sensitive the class is to roads, how deep its roots go, how much it protects the soil;
- for the hydrological models, maps of the physical setting: rain, evaporation, soils, elevation;
- a model that combines them cell by cell (and, for water and sediment, along the paths water takes downhill), giving maps of the service and totals for the landscape or for each watershed.
Change the land use map (a scenario) and run again: the difference between the two runs is the change in the service.

Because the land use map is at the centre, these models fit naturally after a model of land change: simulate where farming will expand (see the land change tutorials), then ask what that costs in carbon, habitat, water and soil.
Supply, service and value#
Three words are easy to mix up, and InVEST keeps them apart:
- the supply is what the ecosystem does, in physical units: tons of carbon stored, millimetres of water yielded, tons of soil kept on the slope;
- the service is the part of that supply someone uses or benefits from: the water a town or a power plant actually takes, the sediment that would otherwise fill a reservoir;
- the value is that service in money or another common unit: a price per ton of carbon, the electricity a dam produces from the water.
Every model of this series gives the supply. Some also take the step to the service or the value: the carbon model can value a change of storage with a price and a discount rate, the water model can subtract what people consume and value the rest as hydropower. The habitat quality model is different: it does not measure a service to people at all but the state of biodiversity, which is why it is so often run beside the others.
InVEST in Terraflux#
Terraflux's seven operators (in the library's subject Ecosystem services) are InVEST 3.20's models as landschaft, the library behind Terraflux, reimplements them in C++: the same inputs, the same equations, and the same arithmetic (the same 32-bit floating point numbers, the same order of the sums), so that the maps are InVEST's bit for bit. You can check it: the table below compares Terraflux with InVEST 3.20.2 on InVEST's own runs (the reference cases landschaft is tested against), cell by cell. The seasonal water yield model is the one exception: landschaft corrects four errors of InVEST 3.20.2 in it, so only part of its maps are InVEST's to the bit (part 7 says which).
| Operator | Map | Cells with a value | Identical to InVEST | Largest difference |
|---|---|---|---|---|
| services.carbon | carbon storage | 4,569 | 4,569 | 0 |
| services.carbon | sequestration | 4,516 | 4,516 | 0 |
| services.carbon | net present value | 4,516 | 4,516 | 0 |
| services.habitat_quality | degradation | 4,776 | 4,776 | 0 |
| services.habitat_quality | quality | 4,776 | 4,776 | 0 |
| services.habitat_quality | quality, future | 4,776 | 4,776 | 0 |
| services.habitat_quality | rarity | 4,776 | 4,776 | 0 |
| services.water_yield | AET / P | 3,462 | 3,462 | 0 |
| services.water_yield | actual evapotranspiration | 3,462 | 3,462 | 0 |
| services.water_yield | water yield | 3,462 | 3,462 | 0 |
| services.sdr | soil loss (USLE) | 4,498 | 4,498 | 0 |
| services.sdr | index of connectivity | 4,406 | 4,406 | 0 |
| services.sdr | sediment delivery ratio | 4,646 | 4,646 | 0 |
| services.sdr | sediment export | 4,406 | 4,406 | 0 |
| services.sdr | sediment deposition | 4,646 | 4,646 | 0 |
Why this matters for you: a study made with Terraflux can say it used InVEST 3.20's models, cite InVEST's papers and user's guide, and compare its numbers with any published InVEST study. What Terraflux adds is the rest of the workflow in one graph: preparing the maps (reprojecting, aligning, reclassifying), simulating the land use scenarios, running the models many times for sensitivity or uncertainty, and drawing the results.
When to use it#
Use ecosystem service models when the question is about where and how much a change of land use changes the services a landscape provides:
- Comparing scenarios: business as usual against a land use plan, or a road against no road. Nelson et al. (2009) compared scenarios of land use drawn up by stakeholders of the Willamette Basin (Oregon) for several services, biodiversity and the value of commodities: the scenarios with more development produced more commodities but fewer services and less biodiversity, a trade-off that payments for carbon eased.
- Targeting restoration or protection: the cells where reforestation would keep the most sediment out of a reservoir, the forests that store the most carbon.
- Payments for ecosystem services and water funds: who upstream provides the service, who downstream benefits.
- Several objectives at once: maps of carbon and of habitat quality are inputs to a spatial prioritization (see the spatial prioritization tutorials) or to a restoration plan with several benefits (several benefits).
What these models are not:
- They are not precise local predictions. They are deliberately simple, built on annual averages and tables of values by class, and they are best at comparing maps (scenario A against B, place X against Y). Their absolute numbers can be far from measured ones unless you check them. Redhead et al. (2016) compared the water yield model with the river flows measured in 22 catchments of the United Kingdom: with global input data the fit was moderate and varied widely between catchments, with national data most catchments came within about 10% of the measured flow. The data you give matter as much as the model.
- They are not process models. A daily hydrological model such as SWAT+ (
swat.run) simulates floods, low flows and nutrient loads through the year; the water yield model gives one number per cell for an average year. - Habitat quality is not a species distribution: it is a generic index of how intact the habitat is around threats. For one species, use a species distribution model or a connectivity analysis.
What you need#
A land use map in a projected coordinate system, in metres (a CRS, coordinate reference system, says how the numbers of the map relate to places on Earth; a projected one, such as UTM, measures in metres). These four operators refuse a map in longitude and latitude, as InVEST does, because they need the area of a cell in hectares and distances in metres. The codes must be whole numbers; cells with no value (outside the study area) are left out. See Coordinate systems if your map is not projected yet.
Every other map on the same grid: same number of rows and columns, same cells. Terraflux checks it and stops with a message naming the map that differs; One grid for all your maps shows how to bring them onto one grid.
A table for each model, by class. InVEST's tables are CSV files with a lucode column (the land use code) and
one column per parameter. In Terraflux a table is a node of its own:
table.readreads a CSV file (or a TSV, or a file Excel wrote with;and decimal commas: the separator and the decimal mark are found by themselves). The columns of text are left out, because a table in Terraflux holds numbers: InVEST's optionalnameordescriptioncolumn does no harm, it is simply not read. The column names are not case-sensitive (LUCODEandlucodeare the same).table.ofwrites a small table in the node's settings, without a file: handy for a first try.
Every class of the map must be in the table, or the operator stops and lists the missing codes ("the land use map has class(es) [7] that the table lacks"). Classes in the table that the map lacks do no harm.
Watershed polygons for the water and sediment models: a vector file (GeoPackage, Shapefile...) read by
vector.read, with an integer ws_id attribute.
The landscape of this series#
The tutorials of this series use Ribeirão Claro, an imaginary landscape made for them (the numbers are invented, the methods are real): 7.2 by 5.4 km of hills between 530 and 1,100 m in cells of 30 m, in SIRGAS 2000 / UTM zone 23S (EPSG:31983). Two valleys drain south; native forest covers the steep slopes, pasture and cropland the gentler ground, with four eucalyptus plantations and a town near the outlets. Download it to follow along: ribeirao-claro.zip (0.6 MB). It holds:
| Files | What they are |
|---|---|
lulc_1985.tif, lulc_2020.tif, lulc_2040.tif |
land use: 1 forest, 2 pasture, 3 cropland, 4 eucalyptus, 5 urban, 6 water |
dem.tif |
elevation, m |
precipitation.tif, eto.tif, depth.tif, pawc.tif |
annual rain and reference evapotranspiration (mm), soil depth (mm), plant available water (0 to 1) |
erosivity.tif, erodibility.tif |
the RUSLE's R and K factors |
crops_*.tif, roads_*.tif, urban_*.tif |
the threats to habitat in 2020 and 2040 (1 where the threat is) |
watersheds.gpkg, subwatersheds.gpkg, access.gpkg |
two watersheds, four sub-watersheds, a park and its buffer zone |
carbon_pools.csv, sensitivity.csv, threats.csv, biophysical_wy.csv, demand.csv, valuation.csv, biophysical_sdr.csv |
the models' tables |

The scenario of 2040 clears forest edges on the gentler ground for pasture, turns gentle pasture into cropland, doubles the town, adds a plantation and, as a compensation, restores forest along the rivers. The map of 1985 had more forest, no plantations and a village instead of a town.




Build the model#
Start with the simplest of the four: carbon storage needs only the land use map and a table.
- In the application, open the library (the left pane, or Operators in the toolbar) at the subject
Getting data and click
raster.read; in the Node pane set itspathtolulc_2020.tif. - Add a
table.readnode and set itspathtocarbon_pools.csv. - In the subject Ecosystem services, click
services.carbon. - Drag from the output
rasterof the first node to the inputlulcof the carbon node, and from the outputtableof the table node to its inputpools. - Select the carbon node and press Ctrl+Enter: it runs with everything it needs. Its
storageoutput is the map of carbon, itstotalsthe table of the landscape's tons.
Model file (TOML)
format = "terraflux/1"
[[nodes]]
id = "lulc"
op = "raster.read"
params = { path = "lulc_2020.tif" }
note = "Land use of 2020, codes 1 to 6, UTM metres."
[[nodes]]
id = "pools"
op = "table.read"
params = { path = "carbon_pools.csv" }
note = "lucode, c_above, c_below, c_soil, c_dead (t C / ha)."
[[nodes]]
id = "carbon"
op = "services.carbon"
inputs = { lulc = "lulc.raster", pools = "pools.table" }
The same model with the table written in the settings, so it runs without the CSV file. The table has the columns' names and one row of numbers per class:
Model file (TOML)
format = "terraflux/1"
[[nodes]]
id = "lulc"
op = "raster.read"
params = { path = "lulc_2020.tif" }
[[nodes]]
id = "pools"
op = "table.of"
params = { columns = ["lucode", "c_above", "c_below", "c_soil", "c_dead"], rows = [[1, 140, 35, 95, 12], [2, 3, 6, 60, 0.5], [3, 4, 1, 45, 0.5], [4, 75, 18, 70, 6], [5, 5, 1, 30, 0], [6, 0, 0, 0, 0]] }
[[nodes]]
id = "carbon"
op = "services.carbon"
inputs = { lulc = "lulc.raster", pools = "pools.table" }
From the command line, save the model as carbon.toml in the folder of the data and run it:
terraflux run carbon.toml --out results
The other three models follow the same pattern with more inputs: habitat quality adds the maps of the threats and a sensitivity table, water yield adds four rasters of climate and soil and the watersheds, sediment adds the elevation, two soil loss factors and the watersheds. Each has its own tutorial in this series. Run once with the land use of 2020, they give these four maps:




In the application
Click any node to see its map (or its table) in the Viewer, and keep the view with the model with
Plots › Save as a new plot: it is shown again after every run. A loop over scenarios
(control.repeat, see Loops) runs the same models on many land use maps.
Read the results#
Run the four models again with the land use of 2040 and compare the totals:
| Service | 2020 | 2040 | change |
|---|---|---|---|
| Carbon stored (t C) | 583,480 | 471,459 | -19.2% |
| Habitat quality, mean of the forest | 0.757 | 0.674 | -10.9% |
| Water yield of the two watersheds (million m³ / year) | 21.35 | 22.23 | +4.1% |
| Sediment exported to the rivers (t / year) | 1,921 | 2,686 | +39.8% |
This is the typical shape of a land use change: no scenario wins on every service. The scenario of 2040 loses a fifth of the landscape's carbon and a tenth of its forest's habitat quality, and sends 40% more sediment to the rivers, but it yields 4% more water, because pasture and crops evaporate less than forest. Whether more water is good depends on who uses it and when: a reservoir for hydropower gains, but the model says nothing about whether the extra water arrives as floods in the rainy season or as flow in the dry one. Reading these numbers well means knowing what each model includes, which is the subject of the next four tutorials.
When you report a study, give for each model: the version of the model (InVEST 3.20, through Terraflux), the maps and their resolution, the tables (in a supplement), the settings, and the totals for each scenario; show the maps of the difference between scenarios, not only the maps of each.
Settings that change the answer#
Three choices change every model of this series:
- The tables. The numbers by class are the model. A carbon density, a sensitivity to roads or a cover factor from a global table may be far from your landscape's; use local measurements when you have them, and test how much the answer moves when a value moves (each tutorial shows how). The values of Ribeirão Claro are illustrative, chosen to be plausible, not measured.
- The classes. A class is assumed to be the same everywhere: every hectare of "forest" holds the same carbon and the same roots. Splitting a class (old-growth and secondary forest, degraded and managed pasture) is often the cheapest way to make a model more realistic.
- The resolution. Water and sediment follow the flow of water over the elevation model: their results depend on the size of the cells far more than carbon does.
Common pitfalls#
- A map in longitude and latitude. The operators stop with "...is in longitude / latitude: give it
projected, in metres". Reproject with
raster.reprojectfirst. - Grids that differ by a row. Two maps from different sources rarely share their grid. Match them first
(
raster.match). - Missing classes. A code in the map that the table lacks stops the model; a class with code 0 used as "no data" must be a missing value of the raster, not a class.
- Units. Carbon in t C per hectare (InVEST's Mg C / ha: the same thing), water in millimetres, sediment in tons per hectare and year, distances in metres. A table in t CO₂ instead of t C overestimates carbon by 3.67 times.
- Absolute numbers taken at face value. Without calibration, compare scenarios, and say so.
Going further#
- Carbon storage and sequestration: the four pools, a future map and the value of the change.
- Habitat quality and rarity: threats, their decay with distance, sensitivity, access and rarity.
- Annual water yield: Budyko's curve, consumption and hydropower.
- Sediment delivery ratio: soil loss, connectivity, export and retention.
- Nutrient delivery ratio: nitrogen and phosphorus, their loads and what the land between a field and the river retains.
- Seasonal water yield: quickflow, recharge and baseflow month by month.
- Crop pollination by wild bees: guilds of bees, their nests and flowers, and the pollination of coffee farms.
- The operators' reference:
services.carbon,services.habitat_quality,services.water_yield,services.sdr,services.ndr,services.seasonal_water_yield,services.pollination.
References#
- Costanza, R., d'Arge, R., de Groot, R., Farber, S., Grasso, M., Hannon, B., Limburg, K., Naeem, S., O'Neill, R. V., Paruelo, J., Raskin, R. G., Sutton, P., & van den Belt, M. (1997). The value of the world's ecosystem services and natural capital. Nature, 387(6630), 253–260. https://doi.org/10.1038/387253a0
- Guerry, A. D., Polasky, S., Lubchenco, J., Chaplin-Kramer, R., Daily, G. C., Griffin, R., Ruckelshaus, M., Bateman, I. J., Duraiappah, A., Elmqvist, T., Feldman, M. W., Folke, C., Hoekstra, J., Kareiva, P. M., Keeler, B. L., Li, S., McKenzie, E., Ouyang, Z., Reyers, B., Ricketts, T. H., Rockström, J., Tallis, H., & Vira, B. (2015). Natural capital and ecosystem services informing decisions: From promise to practice. Proceedings of the National Academy of Sciences, 112(24), 7348–7355. https://doi.org/10.1073/pnas.1503751112
- Natural Capital Alliance. (2026). InVEST 3.20.2 User's Guide. https://storage.googleapis.com/releases.naturalcapitalproject.org/invest-userguide/latest/en/index.html
- Nelson, E., Mendoza, G., Regetz, J., Polasky, S., Tallis, H., Cameron, D. R., Chan, K. M. A., Daily, G. C., Goldstein, J., Kareiva, P. M., Lonsdorf, E., Naidoo, R., Ricketts, T. H., & Shaw, M. R. (2009). Modeling multiple ecosystem services, biodiversity conservation, commodity production, and tradeoffs at landscape scales. Frontiers in Ecology and the Environment, 7(1), 4–11. https://doi.org/10.1890/080023
- Redhead, J. W., Stratford, C., Sharps, K., Jones, L., Ziv, G., Clarke, D., Oliver, T. H., & Bullock, J. M. (2016). Empirical validation of the InVEST water yield ecosystem service model at a national scale. Science of the Total Environment, 569–570, 1418–1426. https://doi.org/10.1016/j.scitotenv.2016.06.227
- Tallis, H., & Polasky, S. (2009). Mapping and valuing ecosystem services as an approach for conservation and natural-resource management. Annals of the New York Academy of Sciences, 1162(1), 265–283. https://doi.org/10.1111/j.1749-6632.2009.04152.x