Skip to content

This is the multi-page printable view of this section. .

Return to the regular view of this page.

Documentation

Learn the architecture, run the examples, integrate the library, and look up exact behavior.

Choose the path that matches what you need:

  • Overview explains the project and its boundaries.
  • Get started takes you from prerequisites to a rendered tile.
  • Guides cover styling, mosaics, and production operation.
  • Reference records exact HTTP parameters, features, and configuration.

1 - Overview

Understand what async-geotiff owns and how data moves through it.

Start here for the project model, architecture, and deliberate boundaries.

1.1 - What is async-geotiff?

The project’s purpose, supported data, and deliberate boundaries.

async-geotiff is a Rust library for turning Cloud-Optimized GeoTIFFs (COGs) into styled XYZ map tiles. It reads only the byte ranges needed for a tile, decodes native TIFF blocks, optionally reprojects them, applies a rendering style, and encodes the result.

Core capabilities

  • Async COG access over HTTPS or any caller-configured object_store backend.
  • Shared, byte-bounded caching of decoded native TIFF blocks.
  • WebMercatorQuad (EPSG:3857) and WorldCRS84Quad (EPSG:4326) tile grids.
  • U8, U16, I16, U32, I32, F32, and F64 source pixels.
  • Nearest, bilinear, cubic, cubic-spline, Lanczos, and average resampling.
  • Rescaling, colormaps, RGB composition, color formulas, and arithmetic band math.
  • PNG output, plus feature-gated WebP and JPEG output.
  • Multi-asset mosaics backed by MosaicJSON, STAC, or a custom source.

What the library deliberately does not own

No GDAL runtime. TIFF I/O uses async-tiff and object_store. The default proj feature uses the system libproj library only for coordinate transformations that do not have a built-in fast path.

No web framework in the library. The Axum HTTP layer and MapLibre, OpenLayers, and Leaflet viewers live under examples/. Applications can use CogReader, Tiler, or MosaicTiler without inheriting Axum.

No credentials manager. When opening S3, GCS, MinIO, or another object store, the application configures authentication on the store and passes the ready object to the library.

No telemetry backend. The crate emits tracing spans and exposes cache statistics. The application decides whether to export them to OpenTelemetry, Prometheus, logs, or another system.

Note

A tile fully outside the dataset or projection domain returns Ok(None). The example HTTP server maps that result to 204 No Content.

1.2 - Architecture

Follow a tile from an HTTP request or library call to encoded bytes.

The library separates asynchronous range I/O from CPU-heavy decode, warp, render, and encode work. Applications compose the public layers they need.

flowchart LR
    Client[HTTP client or Rust caller] --> Style[TileStyle]
    Client --> Tiler[Tiler]
    Tiler --> Grid[TileMatrixSet]
    Tiler --> Reader[CogReader]
    Reader --> Store[object_store / HTTP range reads]
    Reader <--> Cache[Shared BlockCache]
    Reader --> CPU[CpuLimiter + spawn_blocking]
    CPU --> Warp[Warp and resampling]
    Warp --> Render[Rescale / colormap / composite]
    Style --> Render
    Render --> Encode[PNG / WebP / JPEG]
    Encode --> Result[Option&lt;Bytes&gt;]
    Mosaic[MosaicTiler] --> ReaderPool[ReaderPool]
    ReaderPool --> Reader
    Mosaic --> Render

Main components

ComponentResponsibility
CogReaderOpen a COG, read metadata and overviews, select and stitch native blocks, and sample points or windows.
BlockCacheShare decoded native blocks across readers under one byte budget; coalesce concurrent cold fetches.
TilerPlan a tile, choose an overview, read the source window, warp when required, and render encoded bytes.
TileStyleParse and validate titiler-style query parameters before rendering.
MosaicTilerFind assets, open readers through a pool, warp each asset, reduce overlapping pixels, and render once.
CpuLimiterBound CPU-heavy blocking work across readers and tilers.

Tile data flow

  1. TileCoord identifies a tile in a supported TileMatrixSet.
  2. Tiler computes the destination bounds and checks whether they intersect the source dataset.
  3. It selects an overview whose ground resolution is appropriate for the requested tile.
  4. CogReader loads missing native blocks through range requests and reuses cached blocks where possible.
  5. Same-CRS tiles use an affine fast path. Cross-CRS tiles use an inverse warp; EPSG:4326 ↔ EPSG:3857 has a closed-form fast path, while other pairs require the proj feature.
  6. The render pipeline applies nodata, scaling, optional band math, rescaling, colormaps or RGB composition, and the requested output encoder.

Concurrency model

Tokio drives asynchronous metadata and byte-range I/O. Decode, stitch, warp, reduction, render, and encode jobs run through spawn_blocking behind a semaphore. Applications can inject one Arc<BlockCache> across single-COG and mosaic readers to avoid multiplying decoded-cache budgets. They can also inject one CpuLimiter across non-mosaic CogReader/Tiler instances. Current MosaicTiler uses its own internal limiter and cannot join that permit budget, so mixed traffic has no automatic process-wide CPU cap.

2 - Get started

Install dependencies, run the example server, and render a tile through the library.

Follow the shortest path from a fresh checkout to a visible map tile.

2.1 - Requirements

Rust, system libraries, and optional documentation tooling.

Library and examples

  • Rust 1.88 or newer, matching Cargo.toml.
  • The default feature set requires system libproj 9.x.
  • Git is required when working from the repository.

On macOS:

brew install proj

On Debian or Ubuntu:

sudo apt install libproj-dev libsqlite3-dev libtiff-dev clang

On other platforms, install libproj with the platform’s supported package manager or build without the default features. The project does not currently provide platform-specific Windows installation commands.

If you only need same-CRS tiles or the built-in EPSG:4326 ↔ EPSG:3857 fast path, build without the default features:

cargo build --no-default-features

Documentation site

The OINK site under website/ requires Go 1.27 or newer and Hugo Extended 0.165.0 or newer. Hugo must report extended in its version string.

go version
hugo version

The library itself does not depend on Hugo or Go.

2.2 - Quick start

Run the example server and request your first rendered tile.

Clone and run

git clone https://github.com/mapseekai/async-geotiff-rs.git
cd async-geotiff-rs
COG_URL='https://raw.githubusercontent.com/cogeotiff/rio-tiler/0b08b7f35a8b639cee2f35a0cb565034f7b55bfd/tests/fixtures/cog.tif'
cargo run --release --example serve -- "$COG_URL"

The pinned 800 KiB rio-tiler fixture is a public, range-capable COG intended for tests and first-run verification. Replace it with your own COG after the smoke test. The server listens on 127.0.0.1:8080 by default and prints the available viewer and tile URLs when startup completes.

Open one of the included viewers:

The viewer automatically centers on the opened dataset and is the most reliable visual smoke test. You can also request the world tile directly:

curl --fail --output tile.png \
  'http://127.0.0.1:8080/tiles/WebMercatorQuad/0/0/0.png'

Success produces a PNG file that you can open in any image viewer. A valid tile coordinate outside the source extent returns HTTP 204 instead of a synthetic blank image; if that happens, use one of the included viewers to request an in-bounds tile at the dataset’s calculated center and zoom.

Browse local files

Run the server without a URL to discover data/*.tif and data/*.tiff files:

mkdir -p data
cp /path/to/example.tif data/
cargo run --release --example serve

The viewers then display a dataset switcher.

Optional formats

PNG is always available. Enable WebP and JPEG explicitly:

cargo run --release --features webp,jpeg --example serve -- \
  https://example.com/cog.tif

The /formats endpoint reports only the encoders compiled into the running binary.

2.3 - Library usage

Open a COG and render a tile directly from Rust.

The repository currently sets publish = false, so another local project uses a path dependency while developing. Create the application next to the clone, then replace the relative path if your directories differ:

# Starting inside the async-geotiff-rs checkout:
cd ..
cargo new async-geotiff-demo
cd async-geotiff-demo
[dependencies]
async-geotiff = { path = "../async-geotiff-rs" }
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }

To avoid the system libproj dependency while retaining the mosaic APIs used by the example server, set default-features = false, features = ["mosaic"] on the path dependency. General CRS transformations will then be unavailable.

Render one tile

use std::sync::Arc;

use async_geotiff::io::cog::CogReader;
use async_geotiff::style::TileStyle;
use async_geotiff::tiler::Tiler;
use async_geotiff::tms::{TileCoord, TileMatrixSet};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let url = "https://raw.githubusercontent.com/cogeotiff/rio-tiler/0b08b7f35a8b639cee2f35a0cb565034f7b55bfd/tests/fixtures/cog.tif";
    let reader = Arc::new(
        CogReader::builder()
            .source_id(url)
            .open_http(url)
            .await?,
    );
    let tiler = Tiler::new(reader);
    let style = TileStyle::from_query("colormap_name=viridis&rescale=0,3000")?;
    let coord = TileCoord {
        tms: TileMatrixSet::WebMercatorQuad,
        z: 0,
        x: 0,
        y: 0,
    };

    if let Some(bytes) = tiler.tile(coord, &style).await? {
        std::fs::write("tile.png", bytes)?;
    } else {
        eprintln!("tile is outside the dataset or projection domain");
    }
    Ok(())
}

TileStyle::from_query accepts the same query string used by the example HTTP server, without the leading ?. Save the example as src/main.rs, then run cargo run. The pinned URL is a small, range-capable test COG; replace it after verifying the integration.

Share memory and CPU budgets

For multiple COGs, create one block cache and give every reader a stable, distinct source ID:

use std::sync::Arc;

use async_geotiff::io::block_cache::BlockCache;
use async_geotiff::io::cache::CacheConfig;
use async_geotiff::io::cog::CogReader;

let cache = Arc::new(BlockCache::new(CacheConfig::default()));

let first = CogReader::builder()
    .source_id("scene-a")
    .block_cache(Arc::clone(&cache))
    .open_http("https://example.com/a.tif")
    .await?;

let second = CogReader::builder()
    .source_id("scene-b")
    .block_cache(Arc::clone(&cache))
    .open_http("https://example.com/b.tif")
    .await?;

Readers with the same cache share its default 512 MiB budget. The source ID is part of the cache key: reuse it only for the same logical COG.

3 - Guides

Apply styling, compose mosaics, and operate async-geotiff in production.

Task-oriented guides for the capabilities most applications compose.

3.1 - Styling and band math

Select bands, stretch values, apply colormaps, and derive bands with expressions.

The same TileStyle model serves the Rust API and the example server’s query string. Styles are validated before expensive COG reads and rendering work.

Common recipes

Natural-color RGB from three bands:

bidx=1&bidx=2&bidx=3&rescale=0,3000&rescale=0,3000&rescale=0,3000

Single-band color ramp:

bidx=1&colormap_name=viridis&rescale=0,3000

Percentile stretch:

stretch=percent&pc=2,98

Average downsampling and bilinear reprojection:

resampling=average&reproject=bilinear

Stretch behavior

For non-U8 data, the effective value range is selected in this order:

  1. Explicit rescale=min,max values.
  2. The requested stretch mode.
  3. stretch=stddev&sigma=2.0 when neither is present.

U8 RGB data keeps its 0–255 fast path. Dataset statistics come from embedded STATISTICS_* tags when present; otherwise the highest overview is sampled once and the estimate is memoized.

Arithmetic expressions

expression computes one derived output band. Band references are 1-indexed:

expression=(b5-b4)/(b5+b4)&rescale=-1,1&colormap_name=viridis

This NDVI formula is only correct when band 5 is near-infrared and band 4 is red in the selected COG. The library does not infer spectral roles from band numbers; verify the asset metadata and adjust the references before using the formula. A pre-rendered STAC visual asset is not automatically suitable for this example.

When used in a URL, percent-encode / and +:

curl --output ndvi.png \
  'http://127.0.0.1:8080/tiles/WebMercatorQuad/0/0/0.png?expression=(b5-b4)%2F(b5%2Bb4)&rescale=-1,1&colormap_name=viridis'

The grammar supports finite decimal numbers, parentheses, binary +, -, *, /, and unary -. Multiplication and division bind more tightly than addition and subtraction. Scientific notation is not supported.

expression is mutually exclusive with bidx and color_formula, and it accepts at most one rescale range. Nodata inputs, division by zero, and other non-finite results become transparent pixels. Input is bounded to 4096 bytes, 256 tokens, and 128 nesting levels.

Color formulas

The supported rio-color subset applies operations from left to right:

  • gamma
  • sigmoidal
  • saturation

For example:

color_formula=gamma RGB 1.5

Percent-encode spaces when the formula is placed in a URL query string.

3.2 - Mosaics and STAC

Render overlapping COG assets from MosaicJSON, STAC, or a custom source.

The default-enabled mosaic Cargo feature adds MosaicTiler and the MosaicSource trait; applications that do not need mosaics can disable default features. Because that also disables proj, use --no-default-features --features proj when general CRS transformation is still required. The source maps a tile coordinate to assets; the tiler opens and warps those assets, reduces overlapping pixels, and renders the composite once.

MosaicJSON

Run the embedded example or pass a MosaicJSON file:

cargo run --example mosaic_json
cargo run --example mosaic_json -- /path/to/mosaic.json

The parser accepts MosaicJSON 0.0.3. Its quadkey index is defined in WebMercatorQuad; using a MosaicJSON source with WorldCRS84Quad returns a query error.

Connect the example server to a file at startup:

ASYNC_GEOTIFF_MOSAIC=/path/to/mosaic.json \
  cargo run --release --example serve

Tiles are then available under /mosaic/tiles/....

Pixel selection

StrategyBehavior
FirstFirst valid pixel wins; stops early after the tile is fully covered.
HighestMaximum value in the first output band per pixel across every asset.
LowestMinimum value in the first output band per pixel across every asset.
MeanStreaming mean of valid samples; constant memory in asset count.
MedianMedian of valid samples; retains every contributing image until completion.

“First output band” is internal index 0; user-facing bidx values remain 1-indexed.

MosaicConfig defaults to 8 assets processed concurrently per chunk, an opened-reader capacity of 256 in each MosaicTiler reader pool, and a hard cap of 64 assets per requested tile. When the cap is exceeded, the tiler logs a warning and keeps the first assets in source-provided order. Configure all three limits through the builder:

use std::sync::Arc;

use async_geotiff::io::block_cache::BlockCache;
use async_geotiff::io::cache::CacheConfig;
use async_geotiff::mosaic::{HttpAccessPolicy, MosaicConfig, MosaicTiler};

let cache = Arc::new(BlockCache::new(CacheConfig::default()));
let config = MosaicConfig {
    chunk_size: 4,
    reader_capacity: 64,
    max_assets_per_tile: 32,
};
let mosaic = MosaicTiler::builder(source)
    .config(config)
    .block_cache(Arc::clone(&cache))
    .http_policy(HttpAccessPolicy::strict())
    .build();

Keep the asset cap enabled for untrusted or low-zoom indexes to prevent fetch amplification. Choose a deterministic source order when truncation would affect visual correctness.

STAC demo

Enable stac and provide all three startup settings:

ASYNC_GEOTIFF_STAC_URL=https://earth-search.aws.element84.com/v1 \
ASYNC_GEOTIFF_STAC_COLLECTION=sentinel-2-l2a \
ASYNC_GEOTIFF_STAC_ASSET_KEY=visual \
  cargo run --release --example serve --features stac

The API, collection, and asset key are fixed at process startup. HTTP query parameters cannot turn the demo into an arbitrary STAC or COG proxy.

After startup, open http://127.0.0.1:8080/maplibre. When STAC is configured, the MapLibre viewer selects mosaic mode by default and lets you verify the configured collection without guessing a tile coordinate.

HTTP asset policy

The default policy allows public and private HTTP(S) assets but blocks loopback, link-local, and cloud-metadata destinations. Use HttpAccessPolicy::strict() for fully untrusted documents: it requires HTTPS and also blocks private address ranges. permissive() should be reserved for operator-controlled asset lists.

The example server uses the default policy and does not expose an environment override. A service that accepts untrusted mosaic or STAC documents should construct MosaicTiler itself and pass strict() through the builder as shown above.

Presigned query strings are redacted from mosaic errors and log messages. The access policy is a URL-resolution guard, not a complete outbound proxy sandbox. Applications still own client timeouts, redirect policy, egress firewalling, document-size limits, and any logging they add around the library.

3.3 - Production operation

Size caches, bound CPU work, secure remote assets, and export observability.

Share one cache

The default decoded-block cache budget is 512 MiB. A server with many readers should inject the same Arc<BlockCache> into every reader and mosaic. Give each distinct COG a stable source ID so cache entries cannot collide.

This budget covers resident decoded blocks in the cache, not total process RSS. In-flight compressed bytes, decode and warp buffers, encoded responses, reader metadata, and mosaic reducer state are additional memory. In particular, Median retains every contributing image until reduction completes.

The library does not enforce a global request-concurrency limit, so a hard RSS bound cannot be derived from cache capacity alone. Bound concurrent tile requests at the server or gateway, keep per-tile asset fan-out finite, and size the container from load tests that include the largest source windows and output tile sizes you permit.

Use BlockCache::stats() to observe:

  • hits and misses
  • decoded and fetched
  • entries
  • resident_bytes

Useful derived signals include hit ratio, fetched-to-decoded amplification, and resident bytes divided by the configured budget.

Bound CPU work

Decode, stitch, warp, mosaic reduction, render, and encode are CPU-heavy. They run in spawn_blocking behind CpuLimiter. Non-mosaic CogReader and Tiler instances accept a caller-owned limiter. MosaicTiler shares one internal limiter across its assets and final render, but does not accept the non-mosaic limiter. Defaults follow the host’s available parallelism and clamp zero to one permit.

Tiler::new reuses the limiter carried by its reader:

use std::sync::Arc;

use async_geotiff::CpuLimiter;
use async_geotiff::io::cog::CogReader;
use async_geotiff::tiler::Tiler;

let cpu = CpuLimiter::new(8);
let reader = Arc::new(
    CogReader::builder()
        .source_id("scene-a")
        .cpu_limiter(cpu.clone())
        .open_http("https://example.com/a.tif")
        .await?,
);
let tiler = Tiler::new(reader);

The example server’s CPU accounting depends on the path. A command-line default COG uses separate reader-decode and tiler-render limiters, so those phases can overlap. Lazily selected local datasets reuse one AppState limiter sized to the larger configured value. MosaicTiler owns another shared limiter. Treat the two environment values as component tuning, not as a universal process-wide CPU cap. For non-mosaic readers and tilers, wire one library-level CpuLimiter through every component that supports injection.

Current MosaicTiler owns an internal shared limiter and does not expose a builder hook for injecting the non-mosaic limiter. A strict numeric CPU-job cap across mixed mosaic and single-COG traffic is therefore unsupported today. External request concurrency provides useful coarse backpressure, but is not equivalent to one shared permit budget.

Do not lower tile concurrency preemptively. Measure P95 latency and CPU contention first; an unnecessarily small limit adds queueing to every tile.

Tune access patterns

  • Increase cache capacity for multi-dataset servers or wide pan/zoom sessions.
  • Prefer ZSTD-compressed COGs over DEFLATE when read latency matters.
  • The example server prefetches a one-block ring by default. Set ASYNC_GEOTIFF_PREFETCH_RING=0 when extra object-store GETs are undesirable.
  • Keep MosaicConfig::max_assets_per_tile bounded for untrusted indexes.

Export traces and metrics

Tiler::tile and CogReader::read_window emit tracing spans. Connect a tracing-opentelemetry layer in the application when OTLP traces are needed. The library intentionally takes no OpenTelemetry dependency.

Record request count, latency, error count, and the Ok(None) rate at the HTTP or application boundary. Poll cache statistics separately for memory and fetch behavior.

Protect remote access

Use a strict HttpAccessPolicy when mosaic or STAC documents are not trusted. Configure credentials on an object_store instance rather than embedding them in asset identifiers. Avoid logging raw presigned URLs at application boundaries outside the library.

4 - Reference

Exact routes, parameters, features, defaults, and operational settings.

Use this section when you need exact supported values and defaults.

4.1 - Example HTTP API

Routes, tile path format, style parameters, and response behavior.

The HTTP API belongs to examples/serve.rs; it is not part of the library’s dependency surface.

Routes

Method and pathPurpose
GET /tiles/{tms}/{z}/{x}/{y}.{ext}Render a tile from the selected single COG.
GET /mosaic/tiles/{tms}/{z}/{x}/{y}.{ext}Render a tile from the configured mosaic or STAC source.
GET /datasetsList local TIFF files discovered under data/.
GET /cache/statsReturn decoded-block cache statistics.
GET /formatsReturn output formats compiled into the server.
GET /boundsReturn bounds used by the example viewers.
GET, HEAD /data/{name}Serve a discovered local TIFF with range support.

Supported TMS names are WebMercatorQuad and WorldCRS84Quad. Supported extensions are png, feature-gated webp, and feature-gated jpg/jpeg.

Style parameters

ParameterRepeatDefault or exampleMeaning
bidxyesbidx=1&bidx=2&bidx=31-indexed source-band selection.
expressionno(b5-b4)/(b5+b4)Arithmetic expression producing one derived band.
rescaleyes0,3000Explicit per-band min,max range; highest stretch priority.
stretchnominmax, percent, stddevAutomatic stretch mode.
pcno2,98Percentile cut used by stretch=percent.
sigmano2.0Standard-deviation multiplier.
nodatanonan, inf, -inf, or floatOverride the dataset nodata value.
colormap_namenoviridisBuilt-in single-band color ramp.
color_formulanogamma RGB 1.5Supported rio-color operation sequence.
resamplingnonearestSource read or resize kernel.
reprojectnonearestWarp-time resampling kernel.
tilesizeno256One of 64, 128, 256, 512, or 1024.
formatnopngOptional format assertion; must agree with the path extension.

Resampling kernels are nearest, bilinear, cubic, cubic_spline, lanczos, and average. Average computes a box mean for downsampling and uses nearest behavior when upsampling.

The mosaic tile route additionally accepts pixel_selection=first, highest, lowest, mean, or median. The default is first.

Responses

  • 200 OK returns encoded image bytes.
  • 204 No Content means the coordinate is valid but fully outside the source dataset or projection domain.
  • Invalid style values and malformed coordinates return a client error with a structured library error behind it.

The default output size is 256×256, chosen for broad XYZ-client compatibility.

4.2 - Cargo features

Compile-time capabilities and their dependency effects.
FeatureDefaultEffect
projyesEnables general CRS transformation through system libproj.
mosaicyesEnables MosaicTiler, MosaicSource, MosaicJSON, and async asset fan-out.
webpnoEnables lossless WebP encoding through image.
jpegnoEnables JPEG encoding; alpha is flattened because JPEG has no alpha channel.
stacnoAdds the STAC client and implies mosaic.
perf-tracingnoEmits detailed internal timing events.
tokio-consolenoEnables Tokio Console integration and implies perf-tracing.

Examples:

# Default: projection + mosaics + PNG
cargo build --release

# Minimal library without general PROJ or mosaics
cargo build --release --no-default-features

# Example server with all image formats
cargo run --release --example serve --features webp,jpeg

# STAC-backed mosaic demo
cargo run --release --example serve --features stac

# Full verification surface
cargo test --all-features --locked

The serve, mosaic_source, and mosaic_json examples require the mosaic feature. PNG support is always compiled.

4.3 - Example server configuration

Environment variables accepted by the included Axum server.

These variables configure cargo run --example serve. They are example-server contracts, not global library configuration.

VariableDefaultMeaning
ASYNC_GEOTIFF_BIND127.0.0.1:8080Socket address for the HTTP server.
ASYNC_GEOTIFF_BLOCK_CACHE_MB512Shared decoded-block cache capacity in MiB; must be positive.
ASYNC_GEOTIFF_MAX_DECODE_TASKSavailable parallelismMaximum concurrent decode/stitch CPU jobs; must be positive.
ASYNC_GEOTIFF_MAX_TILE_TASKSavailable parallelismMaximum concurrent tile warp/render CPU jobs; must be positive.
ASYNC_GEOTIFF_PREFETCH_RING1Number of native-block rings prefetched around a read; 0 disables it.
ASYNC_GEOTIFF_SLOW_TILE_MSunsetEmit a slow-tile warning above this positive millisecond threshold.
ASYNC_GEOTIFF_MOSAICunsetPath to a MosaicJSON file loaded at startup.
ASYNC_GEOTIFF_STAC_URLunsetFixed STAC API URL; requires the stac feature and the next two variables.
ASYNC_GEOTIFF_STAC_COLLECTIONunsetFixed STAC collection ID.
ASYNC_GEOTIFF_STAC_ASSET_KEYunsetFixed STAC COG asset key.
ASYNC_GEOTIFF_TOKIO_CONSOLEoffEnable Tokio Console with 1, true, yes, or on when compiled with tokio-console.
RUST_LOGasync_geotiff=debug,warnStandard tracing filter for the example server.

ASYNC_GEOTIFF_MOSAIC and the STAC configuration are mutually exclusive. All three STAC variables must be supplied together.

The decode-task and tile-task values tune single-COG work, but are not a single process-wide CPU cap. The command-line default COG uses separate limiters; lazily selected local datasets share one limiter sized to the larger value; mosaics own their own limiter. The example server does not expose environment variables for MosaicConfig fields such as max_assets_per_tile.

Example

ASYNC_GEOTIFF_BIND=0.0.0.0:8080 \
ASYNC_GEOTIFF_BLOCK_CACHE_MB=1024 \
ASYNC_GEOTIFF_MAX_DECODE_TASKS=8 \
ASYNC_GEOTIFF_MAX_TILE_TASKS=8 \
ASYNC_GEOTIFF_PREFETCH_RING=0 \
ASYNC_GEOTIFF_SLOW_TILE_MS=500 \
RUST_LOG=async_geotiff=info \
  cargo run --release --example serve -- https://example.com/cog.tif

Invalid numeric values fail at process startup instead of being silently clamped.