RepoPilotOpen in app →

tidwall/tile38

Real-time Geospatial and Geofencing

Healthy

Healthy across the board

weakest axis
Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 2w ago
  • 14 active contributors
  • MIT licensed
Show all 6 evidence items →
  • CI configured
  • Tests present
  • Concentrated ownership — top contributor handles 71% of recent commits

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/tidwall/tile38)](https://repopilot.app/r/tidwall/tile38)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/tidwall/tile38 on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: tidwall/tile38

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/tidwall/tile38 shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across the board

  • Last commit 2w ago
  • 14 active contributors
  • MIT licensed
  • CI configured
  • Tests present
  • ⚠ Concentrated ownership — top contributor handles 71% of recent commits

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live tidwall/tile38 repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/tidwall/tile38.

What it runs against: a local clone of tidwall/tile38 — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in tidwall/tile38 | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | Last commit ≤ 43 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>tidwall/tile38</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of tidwall/tile38. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/tidwall/tile38.git
#   cd tile38
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of tidwall/tile38 and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "tidwall/tile38(\\.git)?\\b" \\
  && ok "origin remote is tidwall/tile38" \\
  || miss "origin remote is not tidwall/tile38 (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 43 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~13d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/tidwall/tile38"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Tile38 is an in-memory geospatial database and realtime geofencing server written in Go that indexes and searches geographic objects (points, bounding boxes, GeoJSON, geohashes, XYZ tiles, quadkeys) using R-tree spatial indexing. It provides HTTP, WebSocket, Redis RESP, and Telnet protocol support with webhook-triggered geofencing alerts when objects enter/exit defined geographic boundaries. Single-binary project: cmd/tile38-server/ is the main server entry point, cmd/tile38-cli/ wraps the client interface, cmd/tile38-benchmark/ provides load testing. Core logic lives in core/commands.go (command handler dispatch), core/commands.json (command schema), and internal/ contains auxiliary modules (bing geo, etc). Data structure uses tidwall/rtree (spatial index), tidwall/buntdb (persistence), tidwall/geojson (geo objects).

👥Who it's for

Backend engineers and DevOps teams building location-aware applications (ride-sharing, fleet tracking, geofence monitoring) who need sub-millisecond spatial queries and realtime geofencing without running a full PostGIS/PostgreSQL stack. Also used by developers integrating live location tracking with pub/sub webhooks.

🌱Maturity & risk

Production-ready and actively maintained. The codebase is Go-heavy (893KB), has a comprehensive Dockerfile/CI pipeline (see .github/workflows/main.yml), includes test coverage (*_test.go files present), maintains a CHANGELOG.md, and shows consistent recent activity. The MIT license and clear command structure indicate stable public API.

Low risk overall. Dependency surface is well-curated (tidwall/* libraries are author-maintained, external deps are industry-standard like AWS SDK, gRPC, NATS). Main risk: project appears single-maintainer (Josh Tidwall), so extended absence could slow issue triage. No recent breaking changes evident in visible structure, though large go.mod suggests integration complexity.

Active areas of work

No specific recent PR/milestone data visible in provided file list, but the .github/workflows/main.yml and active maintenance of go.mod (Go 1.24.0) indicate ongoing updates. The repo maintains multiple client library integrations and webhook/pub-sub channels suggest active feature work around event distribution.

🚀Get running

git clone https://github.com/tidwall/tile38.git
cd tile38
make
./tile38-server

Then in another terminal: ./tile38-cli to connect. The Makefile orchestrates builds for tile38-server, tile38-cli, and tile38-benchmark binaries.

Daily commands: After cloning and make:

./tile38-server                    # Starts server on default port (typically 9851)
./tile38-cli                       # Connects interactive CLI to server
./tile38-benchmark -h              # Runs performance benchmarks

Server listens on multiple protocols simultaneously. No external services required (embedded BuntDB).

🗺️Map of the codebase

  • core/commands.go: Main command dispatcher and handler implementation for all Tile38 commands (SET, GET, NEARBY, WITHIN, INTERSECTS, SETHOOK, etc)
  • core/commands.json: Schema definition for all commands; editing this and running gen.sh auto-generates command boilerplate
  • cmd/tile38-server/main.go: Server bootstrap: initializes multi-protocol listeners (HTTP, WebSocket, RESP, Telnet) and persistence layer
  • core/version.go: Version constant, ensures build consistency across CLI and server binaries
  • go.mod: Comprehensive dependency list; pinned versions of tidwall libs (rtree, buntdb, geojson, expr) are critical to spatial query correctness
  • Makefile: Build orchestration for tile38-server, tile38-cli, tile38-benchmark; defines standard dev workflow

🛠️How to make changes

Adding commands: Edit core/commands.json (schema), regenerate with core/gen.sh → modifies core/commands_gen.go, implement handler in core/commands.go. Adding protocol support: Modify protocol handlers (look for HTTP/WebSocket/RESP logic in core/). Adding geo types: Extend tidwall/geojson or add shape handlers in core command logic. Tests: Add *_test.go files alongside implementation (e.g., core/commands_test.go has integration examples).

🪤Traps & gotchas

No hardcoded env vars or exotic config requirements visible, but be aware: (1) core/gen.sh must be re-run after editing commands.json or generated code will be stale, (2) Lua scripting support (gopher-lua) adds memory overhead—test with tile38-luamemtest/main.go if scripting is used, (3) Multi-protocol listeners can cause port conflicts; default port is typically 9851 but verify startup logs, (4) Replication (leader/follower) is implicit in command handling—test distributed scenarios early.

💡Concepts to learn

  • R-tree Spatial Indexing — Tile38's core search performance (NEARBY, WITHIN, INTERSECTS) depends on the R-tree data structure; understanding bounding box hierarchy and node splitting is essential to optimize geospatial queries
  • Redis RESP Protocol — Tile38 implements the Redis Serialization Protocol for client communication, enabling use of existing Redis clients and tooling without modification
  • Geofencing / Geohashes — Tile38's primary use case is realtime geofencing (detecting when objects enter/exit boundaries); geohashes provide efficient spatial partitioning for webhooks
  • B-tree Indexing — BuntDB (used for persistence) implements B-trees; understanding this data structure is crucial for disk I/O and query plan optimization
  • Pub/Sub with Webhooks — Tile38's SETHOOK and event delivery mechanism combine publish/subscribe with HTTP/WebSocket webhooks, enabling decoupled event-driven architectures
  • Command Dispatch Patterns — Tile38 uses a code-generation approach (commands.json → commands_gen.go) to define and dispatch commands; understanding this pattern aids adding new features
  • GeoJSON Format — Tile38 natively stores and queries GeoJSON objects; RFC 7946 compliance is critical for interoperability with mapping libraries and geo tools
  • redis/redis — Tile38 mimics Redis RESP protocol and replication architecture; understanding Redis internals helps with command dispatch and pub/sub implementation
  • postgis/postgis — PostGIS is the heavyweight spatial database alternative; Tile38 trades persistent ACID guarantees for in-memory speed and realtime geofencing webhooks
  • tidwall/buntdb — Sibling project by same author; Tile38 uses BuntDB for disk persistence, so understanding its B-tree and index APIs is essential
  • tidwall/rtree — Core spatial indexing library that Tile38 depends on; directly implements the R-tree algorithm behind NEARBY, WITHIN, INTERSECTS queries
  • tidwall/geojson — Sibling library that Tile38 uses to parse and validate GeoJSON objects; handles shape normalization and coordinate extraction

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive integration tests for message queue connectors (MQTT, NATS, Kafka, Azure Event Hubs, AWS SQS)

The codebase has multiple message queue integrations (mqtt, nats, kafka, azure, aws) in the internal/endpoint directory, but based on the file structure shown, there are no visible test files for these critical connectors. These are complex integrations that deserialize geospatial data from external systems - they need integration tests to prevent regressions and ensure data integrity across different message formats.

  • [ ] Create internal/endpoint/*_test.go files for each queue type (mqtt_test.go, nats_test.go, kafka_test.go, etc.)
  • [ ] Add mock message publishers that send sample geospatial data (points, polygons) to each queue type
  • [ ] Verify that Tile38 correctly receives, parses, and indexes the data from each queue
  • [ ] Test error handling (malformed messages, connection failures, timeouts)
  • [ ] Add these tests to .github/workflows/main.yml to run on each commit

Add CLI command documentation and completion tests (tile38-cli)

The cmd/tile38-cli/main.go exists but there's no visible test coverage or integration tests for the CLI itself. Given that this is a user-facing tool for interacting with Tile38, comprehensive CLI tests would ensure commands work correctly, handle errors gracefully, and maintain compatibility across versions.

  • [ ] Create cmd/tile38-cli/main_test.go with tests for common CLI operations (SET, GET, SEARCH, GEOFENCE commands)
  • [ ] Test CLI connection handling, timeout behavior, and error message formatting
  • [ ] Add tests for edge cases: empty responses, malformed server responses, connection drops
  • [ ] Verify that all documented commands in core/commands.json have corresponding CLI test cases
  • [ ] Add a TestCLIIntegration workflow in .github/workflows/main.yml that spins up a Tile38 server and tests CLI interactions

Add performance benchmarking suite for spatial indexing operations with documented baselines

The tile38-benchmark tool exists (cmd/tile38-benchmark/main.go) but there's no visible benchmark results documentation, baseline comparisons, or performance regression tests in CI. This is critical for a geospatial database where users care deeply about query performance. Adding benchmarks with documented baselines and CI validation would prevent performance regressions.

  • [ ] Create internal/benchmark/benchmark_test.go with Go testing benchmarks for core operations (SET 1000 points, WITHIN search, INTERSECTS check, etc.)
  • [ ] Document baseline performance metrics in a new BENCHMARKS.md file (e.g., 'WITHIN query over 100k points: 5ms')
  • [ ] Add a GitHub Action in .github/workflows/main.yml that runs benchmarks and compares against baseline thresholds
  • [ ] Include benchmarks for different spatial index types (using the rtree package with various configurations)
  • [ ] Add regression detection: fail CI if performance degrades by >10% on key operations

🌿Good first issues

  • Add comprehensive command coverage tests: core/commands_test.go exists but review it against the full commands.json schema to identify untested commands (e.g., lesser-used SETHOOK variants, roaming geofence edge cases) and add integration test cases.
  • Expand internal/bing/ Bing Maps integration: The module has bing.go, bing_test.go, and ext.go but tests are likely incomplete. Add parametric test cases for coordinate system edge cases (antimeridian crossing, poles) and add documentation comments explaining the quadkey encoding logic.
  • Create CLI documentation snippets: cmd/tile38-cli/main.go is the entry point but likely lacks examples for complex multi-step geofence workflows. Add code comments or a companion EXAMPLE file showing typical SETHOOK + pub/sub flow with curl examples.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 5b8ce58 — Create CONTRIBUTING.md (tidwall)
  • f057090 — refactor(server): rename RX option to RETURN for clarity (XanderD99)
  • a85d534 — feat(server): add RX option for inline object response in SET and FSET (XanderD99)
  • 068e3b3 — fix: distinguish between hooks and channels in RENAME error message (majiayu000)
  • 932631a — fix: apply WHERE clause check for cross detection in geofence hooks (majiayu000)
  • 48aa3d2 — 1.37.0 (tidwall)
  • 6b2258b — Avoid inserting NaN points into spatial index (tidwall)
  • 3010191 — avoid search instead of throwing error (krkeshav)
  • 337348a — inf and NaN fixes (krkeshav)
  • 8ced811 — Fix tests for new =~ operator (tidwall)

🔒Security observations

  • High · Outdated Go Version — go.mod. The project specifies Go 1.24.0 in go.mod. While this is a recent version, it's important to ensure all dependencies are regularly updated. Go 1.24 is still in development/early release phase and may have stability concerns for production use. Fix: Use a stable, well-tested Go version (1.23.x or latest stable release). Monitor Go security advisories and update promptly.
  • High · Vulnerable Dependency: aws-sdk-go v1.55.8 — go.mod (aws/aws-sdk-go). AWS SDK Go v1 (v1.55.8) is an older major version. AWS has released v2 with improved security, better error handling, and security patches. The v1 series may have unpatched vulnerabilities. Fix: Migrate to AWS SDK Go v2 (github.com/aws/aws-sdk-go-v2). Review AWS security advisories for v1 CVEs.
  • High · Vulnerable Dependency: IBM/sarama v1.46.0 — go.mod (IBM/sarama). The Sarama library (Kafka client) v1.46.0 is an older version. There may be unpatched security vulnerabilities related to authentication, encryption, or protocol handling. Fix: Update to the latest stable version of Sarama and review the changelog for security fixes. Consider using Kafka's official Go client if applicable.
  • Medium · Potential MQTT Man-in-the-Middle Vulnerability — internal/endpoint/mqtt.go, go.mod. The project includes paho.mqtt.golang v1.5.1. MQTT connections may not enforce TLS/encryption by default, potentially allowing unencrypted credential transmission and message interception. Fix: Ensure all MQTT connections use TLS (mqtts://). Implement certificate validation and enforce encryption in the MQTT endpoint configuration.
  • Medium · gRPC Service Exposure Without Authentication — internal/endpoint/grpc.go. The project includes gRPC support (google.golang.org/grpc v1.74.2). If gRPC endpoints are exposed, they may lack authentication/authorization checks, allowing unauthorized access. Fix: Implement authentication (mTLS, OAuth2, or custom interceptors) for all gRPC endpoints. Use TLS for all gRPC connections in production.
  • Medium · Lua Script Execution Risk — cmd/tile38-luamemtest, go.mod. The project includes Lua scripting capability (yuin/gopher-lua v1.1.1). User-supplied Lua scripts could potentially be used for arbitrary code execution or resource exhaustion. Fix: Implement strict sandboxing for Lua script execution. Use resource limits (memory, CPU, execution time). Validate and sanitize all script inputs. Consider disallowing dangerous Lua libraries.
  • Medium · Hardcoded Redis Credentials Risk — internal/endpoint/redis.go. The project includes Redis integration (gomodule/redigo v1.9.2 and internal/endpoint/redis.go). Redis connections may not enforce authentication or use default credentials. Fix: Require Redis AUTH for all connections. Use environment variables or secure vaults for credential storage. Never hardcode passwords in configuration.
  • Medium · HTTP Endpoint Security — internal/endpoint/http.go. The project exposes HTTP endpoints (internal/endpoint/http.go). Without proper security headers, it may be vulnerable to CSRF, clickjacking, or other web-based attacks. Fix: Add security headers (X-Frame-Options, X-Content-Type-Options, Content-Security-Policy, Strict-Transport-Security). Implement CSRF protection and rate limiting.
  • Medium · Default Port Exposure — Dockerfile. The Dockerfile exposes port 9851 by default. If the service is exposed to untrusted networks without authentication, it could be accessible to attackers. Fix: Do not expose port 9851 directly to the internet. Use network segmentation, firewall rules, and require strong authentication.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · tidwall/tile38 — RepoPilot