factbook 0.1.3

A high-speed, self-maintaining fact enricher for data at scale. Point it at reference data and it fetches, verifies, indexes and serves it, keeping itself current. IP geolocation is the batteries-included case.
Documentation

factbook

A high-speed, self-maintaining fact enricher for data at scale. Point it at reference data and it fetches, verifies, indexes and serves it. You call it on your own schedule, and it replaces only what is stale while lookups carry on.

IP geolocation is the batteries-included case, and it works with no account anywhere.

What it gives you

  • GeoIP with no signup: DB-IP Lite for location and sapics origin-asn for networks by default, with MaxMind and IPinfo when you hold an account.
  • Downloads checked before they go live: format, size, the provider's digest where there is one, and a content probe you can turn off. A refused file leaves the copy on disk serving.
  • Lookups behind a cache: a hit took about 300 ns against about 6 us for a database read (measured 2026-11-01, x86_64), and private or reserved addresses never reach it.
  • Refresh with no pause: refresh_if_changed swaps readers lock-free. factbook starts no timer, so call it and ensure_databases from your own.
  • A GeoIP database read onto the heap when it fits under the ceiling you set, and memory-mapped when it does not.
  • Your own reference tables: CSV or JSON, raw or gzipped, indexed by address, CIDR range or any column. A table is held in memory, and one past the ceiling is refused.
  • Credentials held as Secret, redacted in Debug, Display and the URLs factbook logs. IPinfo takes its token as a query parameter.

Example

cargo add factbook
cargo add tokio --features macros,rt-multi-thread
use factbook::geoip::{CacheConfig, GeoIp, GeoIpConfig, ensure_databases};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Downloads whatever is missing or stale, then opens it behind a cache.
    let databases = ensure_databases(&GeoIpConfig::default()).await?;
    let geoip = GeoIp::from_databases(&databases, CacheConfig::default())?;

    if let Some(record) = geoip.lookup("8.8.8.8".parse()?) {
        println!("{:?} / {:?}", record.country_code, record.city_name);
    }
    Ok(())
}

Features

Feature Adds
geoip geoip-download plus geoip-lookup (default)
geoip-download Resolve, freshness-check, download and verify, plus reference tables
geoip-lookup The resident or mapped readers and the cache
metrics Download outcomes and database age through the metrics facade (default)
metrics-lookup Cache hits, misses, size and lookup time (implies metrics)

A host running someone else's lookup engine takes default-features = false, features = ["geoip-download"] and pays for no reader.

factbook ships no reference data. It fetches at runtime from the source you configure, and each publisher sets its own terms.

API docs are at https://docs.rs/factbook, the source and the data source guide at https://github.com/hyperi-io/factbook-rs. Licensed Apache-2.0: https://github.com/hyperi-io/factbook-rs/blob/main/LICENSE.