How to Configure Apache Sedona SQL Engine for Spatial SQL Queries in the Browser

GeoLibre provides a dual-engine architecture that runs Apache Sedona spatial SQL directly in the browser via WebAssembly (CereusDB) or falls back to a Python side-car, with automatic detection and a 50,000 feature limit for in-browser processing.

The open-source GeoLibre project enables advanced geospatial analytics without server infrastructure by embedding the Apache Sedona SQL engine directly into web applications. This guide explains how to configure the system to execute spatial SQL queries using either the Rust-backed WebAssembly runtime or an optional Python side-car for larger datasets.

Understanding the Dual-Engine Architecture

GeoLibre ships two implementations of the Apache Sedona spatial-SQL engine:

  • CereusDB (WebAssembly): Runs directly in the browser via sedona-workspace.ts as a Rust-backed, WASM-compiled version of SedonaDB.
  • SedonaDB Side-car (Python): Runs as a FastAPI process on the client machine defined in sedona_ops.py.

When the side-car is reachable, the UI prefers it for larger data volumes and native raster support. If unavailable, the browser automatically falls back to CereusDB according to the routing logic in runSedonaQuery.

How the In-Browser Engine Works

Loading the WASM Bundle

The first call to any Sedona query triggers loadCereusDb() in apps/geolibre-desktop/src/lib/sedona-workspace.ts. This fetches the compiled cereus.wasm file and creates a singleton CereusInstance (stored as dbPromise).

Registering Spatial Layers

Every GeoJSON layer in the current map is converted into a source table via registerGeoJSON and exposed as a view that parses the geometry column with ST_GeomFromText. This registration happens in registerLayerTables within the same module.

Feature Count Limits

The browser engine enforces a hard cap of 50,000 features per layer (MAX_CEREUS_FEATURES). Exceeding this limit throws an error and prompts the user to use the side-car instead.

Query Execution and Routing

The runSedonaQuery function sanitizes statements using cleanStatement, checks for multiple statements, and executes via either runCereusQuery (in-browser) or runSidecarQuery (Python). Side-car availability is probed via /sql/status and cached for 5 seconds (SIDECAR_PROBE_TTL_MS).

Step-by-Step Configuration for Pure Browser Use

  1. Ensure WASM Bundle Accessibility: The build includes cereus.wasm by default. The bundle loads relative to the app's base URL with no additional network configuration required.

  2. Disable Side-Car Detection: For web-only deployments, ensure the Python server is not running. Desktop builds set IS_MAS_BUILD to true for Mac App Store compatibility, which disables side-car probes.

  3. Initialize the Engine: Import and call runSedonaQuery from your UI code. The first call lazily loads the WASM bundle automatically.

  4. Monitor Data Volume: Keep individual layers below 50,000 features. Split larger datasets into multiple layers or use the desktop app with the side-car enabled.

Optional: Enabling the Python Side-Car for Larger Datasets

To process datasets exceeding browser limits:

  1. Install the Sedona package:
pip install "apache-sedona[db]"
  1. Start the FastAPI side-car using the convenience script python/hatch_build.py in the repository to build the wheel and launch geolibre_server.

  2. Verify the health endpoint:

curl http://127.0.0.1:8765/sql/status

A successful response returns "available": true.

  1. The runSedonaQuery function automatically routes queries to the side-car when detected, as implemented in sedona-workspace.ts.

Code Examples

Running a Simple Spatial Query

import { runSedonaQuery } from '@geolibre/processing';

const sql = `
  SELECT name, ST_Area(geometry) AS area_m2
  FROM my_layer
  WHERE ST_Intersects(geometry, ST_MakeEnvelope(-120, 35, -119, 36, 4326))
`;

runSedonaQuery(sql, layers)
  .then(result => {
    console.table(result.rows);
    // result.geojson contains a FeatureCollection for mapping
  })
  .catch(err => console.error('Sedona query failed:', err));

Forcing In-Browser Execution

import { IS_MAS_BUILD } from './build-flags';

// Bypass side-car probe for testing
(IS_MAS_BUILD as any) = true;
await runSedonaQuery(sql, layers);

Handling Feature Limit Errors

try {
  await runSedonaQuery(sql, layers);
} catch (e) {
  if (e.message.includes('exceeding the 50000-feature limit')) {
    console.error('Switch to side-car for large datasets');
  }
}

Key Configuration Files

File Role
apps/geolibre-desktop/src/lib/sedona-workspace.ts Core engine loader, layer registration, and query routing logic
backend/geolibre_server/geolibre_server/sedona_ops.py Python side-car wrapping apache-sedona[db]
backend/geolibre_server/geolibre_server/app/sql.py FastAPI endpoints exposing SedonaDB over HTTP
apps/geolibre-desktop/src/lib/sql-workspace.ts Statement sanitization and result normalization

Summary

  • GeoLibre offers two Apache Sedona engines: CereusDB (WASM/browser) and SedonaDB (Python side-car).
  • The browser engine limits layers to 50,000 features (MAX_CEREUS_FEATURES) and lazy-loads via loadCereusDb().
  • Side-car availability is detected via /sql/status with a 5-second cache (SIDECAR_PROBE_TTL_MS).
  • Configure pure-browser mode by ensuring the WASM bundle is present and the side-car is unreachable.
  • For large datasets, install apache-sedona[db] and launch the FastAPI server to automatically upgrade query capacity.

Frequently Asked Questions

What is the maximum number of features the browser can process?

The in-browser CereusDB engine limits single layers to 50,000 features as defined by MAX_CEREUS_FEATURES in sedona-workspace.ts. Exceeding this requires the Python side-car.

How does GeoLibre detect which engine to use?

The runSedonaQuery function probes the /sql/status endpoint and caches the result for 5 seconds (SIDECAR_PROBE_TTL_MS). If the side-car responds, queries route to Python; otherwise, they execute in the browser via WebAssembly.

Can I run spatial queries without installing Python?

Yes. The CereusDB WebAssembly engine runs entirely in the browser without external dependencies, provided your data stays below the 50,000 feature limit per layer.

Where is the WebAssembly bundle loaded from?

The cereus.wasm file is bundled with the application build and fetched relative to the base URL when loadCereusDb() is first called in sedona-workspace.ts.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →