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.tsas 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
-
Ensure WASM Bundle Accessibility: The build includes
cereus.wasmby default. The bundle loads relative to the app's base URL with no additional network configuration required. -
Disable Side-Car Detection: For web-only deployments, ensure the Python server is not running. Desktop builds set
IS_MAS_BUILDtotruefor Mac App Store compatibility, which disables side-car probes. -
Initialize the Engine: Import and call
runSedonaQueryfrom your UI code. The first call lazily loads the WASM bundle automatically. -
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:
- Install the Sedona package:
pip install "apache-sedona[db]"
-
Start the FastAPI side-car using the convenience script
python/hatch_build.pyin the repository to build the wheel and launchgeolibre_server. -
Verify the health endpoint:
curl http://127.0.0.1:8765/sql/status
A successful response returns "available": true.
- The
runSedonaQueryfunction automatically routes queries to the side-car when detected, as implemented insedona-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 vialoadCereusDb(). - Side-car availability is detected via
/sql/statuswith 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →