# Celebrating a year of Tessera embeddings and releasing GeoTessera 0.10

*2026-08-27 — note*


I can't believe it's been a whole year since we [released the first GeoTessera library](https://anil.recoil.org/notes/geotessera-python)
to make the [TESSERA](https://anil.recoil.org/projects/tessera) embeddings easier to get your mittens on. Quite
a [lot of adoption](https://scholar.google.com/scholar?cites=8285391513046094203&as_sdt=2005&sciodt=0,5&hl=en) has happened since\!
I'm going to quickly review [a year of embedding requests](#a-year-of-embedding-requests) and the people who filed them,
explain the [move to the Source Cooperative](#geotessera-010-and-the-move-to-source-cooperative)
for our hosting, what the [Zarr upgrades](#zarr-conversions-for-v1-and-v2-beta-access)
with UTM routing and matryoshka entail, how the [CLI](#the-geotessera-cli) works, and show you a
[guided tour](#a-quick-guided-tour) that builds a land classifier and sonar panel detector.

<a href="https://www.cl.cam.ac.uk/~avsm2/embedding_requests_map.html"> <figure class="image-center"><img src="/images/embedding_requests_map.gif" alt="A year of public TESSERA embedding requests, in the order they were filed" title="A year of public TESSERA embedding requests, in the order they were filed" loading="lazy"><figcaption>A year of public TESSERA embedding requests, in the order they were filed</figcaption></figure> </a>

## A year of embedding requests

Because we didn't have enough GPUs to pre-generate embeddings for everywhere in the world,
we opened up our GitHub repo for people to request [priority map areas they needed](https://github.com/ucam-eo/geotessera/issues?q=is%3Aissue%20label%3Aembedding-request).
This turned out to be a great way for us to meet our users and build community;
there have been people [from all over the globe](https://www.cl.cam.ac.uk/~avsm2/embedding_requests_map.html) getting in touch\!

Geographically, most of the world is covered, and thematically the requests span agriculture, forests, land cover, water and urban
mapping.
From a machine learning perspective this involves downstream classification, segmentation and regression tasks from
the same model embeddings. Here's a [sample](https://scholar.google.com/scholar?cites=8285391513046094203&as_sdt=2005&sciodt=0,5&hl=en)
of what people are doing:

- [Tree species mapping in temperate mountain forests](https://anil.recoil.org/papers/2026-tessera-trentino),
  where the embeddings need far fewer field plots than a conventional geospatial pipeline.
- Groundnut basin of Senegal [crop type classification](https://doi.org/10.48550/arXiv.2601.16900)
  for smallholder agriculture.
- Côte d'Ivoire has the EU Joint Research Centre asking whether [sub-metre resolution is really necessary for cocoa mapping](https://doi.org/10.48550/arXiv.2607.08945),
  benchmarking Tessera against 0.5m Pleiades imagery.
- Five Swiss cities for [fine-scale local climate zone mapping](https://doi.org/10.48550/arXiv.2606.20034), upscaling coarse 100m LCZ records to 10m.
- The Netherlands has a [tree species classification for the Dutch national forest
  inventory](https://doi.org/10.48550/arXiv.2508.18829).
- There's an analysis of 219 flood events across 65 countries via [GEOID-Flood](https://doi.org/10.48550/arXiv.2608.02315),
  a Copernicus emergency-management benchmark where a 129-parameter linear probe on
  top of the embeddings works as a strong flood segmenter.

Klemmer et al did a great [review](https://doi.org/10.1109/mgrs.2026.3710416) of Earth embeddings as a
category of their own for those who want to learn more about the field.

Thank you to everyone who took the trouble to file a request with us or write a
paper about it, and please keep them coming as we roll out [Tessera v2](https://anil.recoil.org/papers/2026-tessera-v2) as well this year\!

## GeoTessera 0.10 and the move to Source Cooperative

I've also just released [GeoTessera 0.10.0](https://github.com/ucam-eo/geotessera/releases/tag/v0.10.0)
with a quick [0\.10.1](https://github.com/ucam-eo/geotessera/releases/tag/v0.10.1) followup
today after [Aneesh Naik](https://aneeshnaik.github.io/), [Michael Dales](https://mynameismwd.org) and [Sadiq Jaffer](https://toao.com) immediately found some rough edges as they
ported their code.

The main feature is that all our hosting is no longer hammering Cambridge private servers,
but now goes through the [Source Cooperative](https://source.coop) and is fronted by CloudFlare edge
caching. The [source.coop/tessera/tessera](https://source.coop/tessera/tessera) remote
replaces the AWS bucket we temporarily [moved to earlier this year](https://anil.recoil.org/notes/geotessera-python-0-7).
We desperately need our Cambridge storage capacity back as we develop new models, so the older endpoints
will be switched off shortly.

For our users, the primary benefit here is stability and lower latency access that's
more 'cloud native'. If you've got a lot of resources and are running on AWS or Azure,
you'll find you're closer to the Tessera data. On the other hand, when I was in India
running the [Tessera hackathon with IIT-Delhi](https://anil.recoil.org/notes/first-tessera-hackathon) at the
[AI Impact Summit](https://anil.recoil.org/notes/india-ai-summit), the performance was abysmal due to the
India-Cambridge link being slow. That should now be much improved
due to CloudFlare having plenty of edge caching all over the world. If not, let me know\!

## Zarr conversions for v1 and v2 beta access

The Zarr Tessera wrapper has also had a big overhaul. The key benefit of Zarr is that
no downloads are needed as the client can stream data directly over HTTP. Since the
[v3 layout work](https://anil.recoil.org/notes/tessera-zarr-v3-layout) and the [geo-embeddings convention proposal](https://anil.recoil.org/notes/tessera-embeddings-convention) earlier this year, our Zarr store has been
UTM-native to minimise coordinate skew around the globe. This works via `utmNN` Zarr
sub-groups that contain the tiles for that particular slice of the world.

The `GeoTesseraZarr` zarr wrapper now routes global lon/lats to the right UTM
zone subgroup that actually contains the requested point.  This is only necessary near
the seams of UTM zones where a point might be on either side.

The other new preview feature (only for v2 embeddings) is support for the "Matryoshka
embeddings" that we trained [that new model](https://anil.recoil.org/papers/2026-tessera-v2) with, following on from
[v1.1](https://anil.recoil.org/notes/tessera-v11-out).
The first 4 and the first 16 dimensions of a v2 embedding can be plucked out of the Zarr
store independently of the full 128 dimensions, making it much easier to do a quick sample analysis.

The 0.10.1 follow-up release was to fix caching in the Zarr. `GeoTesseraZarr` now accepts a `cache_dir=`
argument and calculates a cache key that disambiguates different model versions
so they never clash. There are also minor fixes to make it easier to use local
filesystems (Ceph in our case) which really don't like large directory reads.

<a href="https://tze.geotessera.org"> <figure class="image-center"><img src="/images/tze-v2-ss-1.webp" alt="Check out the Matryoshaka viewer on v2 embeddings" title="Check out the Matryoshaka viewer on v2 embeddings" loading="lazy" srcset="/images/tze-v2-ss-1.768.webp 768w, /images/tze-v2-ss-1.640.webp 640w, /images/tze-v2-ss-1.480.webp 480w, /images/tze-v2-ss-1.320.webp 320w, /images/tze-v2-ss-1.2560.webp 2560w, /images/tze-v2-ss-1.1920.webp 1920w, /images/tze-v2-ss-1.1600.webp 1600w, /images/tze-v2-ss-1.1440.webp 1440w, /images/tze-v2-ss-1.1280.webp 1280w, /images/tze-v2-ss-1.1024.webp 1024w"><figcaption>Check out the Matryoshaka viewer on v2 embeddings</figcaption></figure> </a>

## The geotessera CLI

The CLI is also quite handy to interactively do some tasks.
`uvx geotessera info` will tell you which variants are published; and you can also
poke at them interactively at [tze.geotessera.org](https://tze.geotessera.org).
Just click on the top right 'model version' button to switch to v2.

```
$ uvx geotessera info
╭─────────┬──────────────────────┬────────────────┬─────────────╮
│ Version │ Variant              │ Repository dir │ Status      │
├─────────┼──────────────────────┼────────────────┼─────────────┤
│ 1.0     │ vultr (default)      │ v1             │ available   │
│ 1.1     │ cambridge (default)  │ v1.1-cam       │ available   │
│ 1.1     │ dclimate             │ -              │ coming soon │
│ 2.0     │ 2B-L~beta1 (default) │ v2-2B-L~beta1  │ available   │
│ 2.0     │ 2B-L~beta2           │ v2-2B-L~beta2  │ available   │
╰─────────┴──────────────────────┴────────────────┴─────────────╯
```

Note that the v2 ones will have very little coverage as we're still exploring
different inference strategies. V1.1 is going through a complete global run at the
moment by dClimate, so those should be available en mass in September sometime.

<figure class="image-center"><img src="/images/geotessera-cli-0-10.gif" alt="" title="" loading="lazy"><figcaption></figcaption></figure>

## A quick guided tour

I've put together a [ucam-eo/geotessera-examples](https://github.com/ucam-eo/geotessera-examples)
repository to provide a little [teaching tour](https://github.com/ucam-eo/geotessera-examples/tree/main/teaching),
after [Michael Dales](https://mynameismwd.org) asked for one a while back.
The first of these is a land-cover classifier for any point on Earth:

```
uv run 01_classify.py --lon 0.12 --lat 52.20    # Cambridge, obviously
```

This is a single Python file, so one `uv` command fetches the dependencies and
runs it directly. There are four main dependencies: `geotessera` (obviously)
to fetch embeddings for a patch of land, and then [osmnx](https://osmnx.readthedocs.io)
to fetch labels from OpenStreetMap as ground truth, then [rasterio](https://rasterio.readthedocs.io)
to line the labels up and turn them into pictures, and finally [scikit-learn](https://scikit-learn.org)
to learn the mapping between the labels and embeddings.

To fetch the embeddings, `GeoTesseraZarr` is the client for the Zarr store. We
just hand it a lon/lat bounding box and it works out which UTM zone and tiles
it needs, streams just those chunks over HTTP through the magic of Zarr, and
gives you back a numpy array with 128 floats per 10m pixel.

```python
gt = GeoTesseraZarr(zarr_store_url("v2"), cache_dir="tessera-cache")
mosaic, transform, crs = gt.read_region((west, south, east, north), year)
```

Then we need some labels. The easiest ground truth for a bounding box is to
grab OpenStreetMap ones. `osmnx` issues a single
[Overpass](https://wiki.openstreetmap.org/wiki/Overpass_API) query (Overpass being
OSM's query service) and gets back vector outlines of water, woodland, farmland,
buildings and roads.

Those outlines then have to become pixels, which is what `rasterio` is for. It
paints them onto the same grid as the embeddings, using the coordinate
transform that `read_region` gives us:

```python
features = ox.features.features_from_bbox(bbox=bbox, tags=OSM_TAGS).to_crs(crs)
rasterize([(g, class_id) for g in shapes], out=labels, transform=transform)
```

That shared grid is pretty much all that's needed to do some basic machine learning
using a KNN:

```python
knn = KNeighborsClassifier(n_neighbors=5).fit(x_fit, y_fit)
logreg = LogisticRegression(max_iter=2000).fit(scaler.transform(x_fit), y_fit)
```

The remainder of the guided tour runs the same classifier using the v2 beta
model at a depth of 16, as well as the full 128 dimensions, and compares
the accuracy for you.

For regions too big to hold in memory there is also an `iter_region` function now,
which splits the mosaic into row strips while prefetching the next one. There's
a [solar panel detection](https://github.com/ucam-eo/geotessera-examples/tree/main/solarpanel)
example that pushes that to lots of pixels without materialising all of them at once;
[Sadiq Jaffer](https://toao.com) first demoed this in his [PROPL talk](https://anil.recoil.org/notes/icfp25-propl) last year.

<a href="https://github.com/ucam-eo/geotessera-examples/tree/main/solarpanel"> <figure class="image-center"><img src="/images/tessera-solar-ss-1.webp" alt="Build your own solar farm detector in minutes" title="Build your own solar farm detector in minutes" loading="lazy" srcset="/images/tessera-solar-ss-1.768.webp 768w, /images/tessera-solar-ss-1.640.webp 640w, /images/tessera-solar-ss-1.480.webp 480w, /images/tessera-solar-ss-1.320.webp 320w, /images/tessera-solar-ss-1.2560.webp 2560w, /images/tessera-solar-ss-1.1920.webp 1920w, /images/tessera-solar-ss-1.1600.webp 1600w, /images/tessera-solar-ss-1.1440.webp 1440w, /images/tessera-solar-ss-1.1280.webp 1280w, /images/tessera-solar-ss-1.1024.webp 1024w"><figcaption>Build your own solar farm detector in minutes</figcaption></figure> </a>

Once you get into segmentation, check out [Sadiq Jaffer](https://toao.com) writing about [the innards of tiny CNNs over Tessera](https://toao.com/blog/earth-observation-budget-solar-farms-tiny-model) to brew your own variations.

## Go forth and find your own tasks

All you need is `pip install geotessera` or `uvx geotessera` to invoke the CLI.

The [examples repository](https://github.com/ucam-eo/geotessera-examples) is a
good place to start. The [GeoTessera documentation](https://geotessera.readthedocs.io) covers the full API.
Our [EEG Zulip](https://eeg.zulipchat.com) has several public channels to reach out to for
more interactive help.

For the agentic hackers among you, there's also a Claude Code plugin in the
repository now. Just type `/plugin` in Claude Code and add `ucam-eo/geotessera`
and activate the resulting `geotessera` plugin to get you going.

Here's to another year of geospatial fun! Happy birthday Tessera\!
Synopsis: It's been a whole year of Tessera embeddings hacking, GeoTessera 0.10 moves hosting to the Source Cooperative, with UTM-native Zarr routing and matryoshka reads.
Words: 1521

## Related

- [Geospatial foundation models enable data-efficient tree species mapping in temperate mountain forests](https://anil.recoil.org/papers/2026-tessera-trentino) (paper, 2026-07-01)
- [TESSERA v2: Scaling Pixel-wise Earth Foundation Models](https://anil.recoil.org/papers/2026-tessera-v2) (paper, 2026-07-01)
- [Tessera v1.1 released, with smoother and temporally stable embeddings](https://anil.recoil.org/notes/tessera-v11-out) (note, 2026-06-12)
- [TESSERA now supports the Zarr geo-embeddings convention proposal](https://anil.recoil.org/notes/tessera-embeddings-convention) (note, 2026-03-27)
- [Streaming millions of TESSERA tiles over HTTP with Zarr v3](https://anil.recoil.org/notes/tessera-zarr-v3-layout) (note, 2026-03-14)
- [At the AI Impact Summit in Delhi: people, planet, progress](https://anil.recoil.org/notes/india-ai-summit) (note, 2026-02-21)
- [1st TESSERA/CoRE hackathon at the Indian AI Summit](https://anil.recoil.org/notes/first-tessera-hackathon) (note, 2026-02-19)
- [GeoTessera 0.7 out with efficient sampling and Zarr support](https://anil.recoil.org/notes/geotessera-python-0-7) (note, 2025-11-17)
- [Programming for the Planet at ICFP/SPLASH 2025](https://anil.recoil.org/notes/icfp25-propl) (note, 2025-10-05)
- [GeoTessera Python library released for geospatial embeddings](https://anil.recoil.org/notes/geotessera-python) (note, 2025-08-31)
- [TESSERA, a pixelwise geospatial foundation model](https://anil.recoil.org/projects/tessera) (project, 2025-01-01)

---
Canonical: https://anil.recoil.org/notes/geotessera-a-year-on
Type: note
Tags: tessera, spatial, zarr, ai, satellite
