IPinfo / MaxMind GeoLite2 Replacement — DB-IP Powered IP Lookup avatar

IPinfo / MaxMind GeoLite2 Replacement — DB-IP Powered IP Lookup

Pricing

$0.50 / 1,000 ip geolocation lookups

Go to Apify Store
IPinfo / MaxMind GeoLite2 Replacement — DB-IP Powered IP Lookup

IPinfo / MaxMind GeoLite2 Replacement — DB-IP Powered IP Lookup

IPinfo gutted its free tier. MaxMind wants a license key. Here's the drop-in replacement: country, region, city, lat/lng, ASN, timezone, VPN/proxy heuristics — unified JSON schema, $0.0005/IP.

Pricing

$0.50 / 1,000 ip geolocation lookups

Rating

0.0

(0)

Developer

Stephan Corbeil

Stephan Corbeil

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

IPinfo / MaxMind GeoLite2 Replacement — DB-IP Powered IP Geolocation

IPinfo gutted its free tier. MaxMind wants a license key. Here's the drop-in replacement at $0.0005 per IP lookup.

If you landed here, you already know the story. In 2025 IPinfo cut its once-generous free tier down to a shadow of itself — 1,000 lookups/day is fine for a hobby project, useless in production. MaxMind's GeoLite2 is still "free," but only after you create an account, accept an EULA, generate a license key, and set up auto-updating infrastructure — all of which broke for thousands of users when MaxMind tightened registration requirements in December 2024. Every week someone asks on Stack Overflow why their GeoIP2.mmdb download is now returning 401s.

This actor is the straightforward escape hatch. No registration. No license keys. No auto-updater cron jobs. Feed it a list of IPv4 or IPv6 addresses, get back a unified JSON record for each: country, region, city, lat/lng, ASN, ISP, timezone, and optional VPN/proxy heuristics. One flat rate, no tiering games.

What it does

For each IP you pass in, the actor returns a record shaped like this:

{
"ip": "8.8.8.8",
"country_code": "US",
"country_name": "United States",
"region": "California",
"city": "Mountain View",
"latitude": 37.4056,
"longitude": -122.0775,
"timezone": "America/Los_Angeles",
"asn": 15169,
"asn_org": "Google LLC",
"is_proxy": false,
"is_vpn": false,
"data_source": "dbip+ipwho.is",
"lookup_time_ms": 4
}

Every field is stable. If something can't be resolved, you get null and a data_source: "error" marker instead of a cryptic stack trace — which means downstream pipelines don't crash when a single IP is bogus.

How it works (and why it's fast)

The primary data source is the DB-IP Lite dataset, which ships under a CC-BY-4.0 license. DB-IP publishes a fresh CSV snapshot every month covering both city-level geolocation and ASN/ISP records. The actor downloads the latest gzipped CSV on first run, caches it to /tmp, parses both files into sorted in-memory range trees, and resolves each IP via bisect — O(log n) per lookup, measured in microseconds once the dataset is in memory.

What that means in practice:

  • First run: ~20-40 seconds to download and parse the datasets (two CSVs totalling ~50 MB gzipped).
  • Subsequent lookups: sub-millisecond per IP once loaded. A run of 1,000 IPs typically finishes the IP-resolution phase in under a second.
  • No per-lookup outbound calls for the core geolocation data. You're not being throttled by somebody else's rate limiter.

For VPN / proxy detection — which DB-IP Lite doesn't include — the actor optionally hits the free ipwho.is API. Set include_vpn_check: true to turn it on. This path is rate-limited by ipwho.is (roughly 10,000 requests/month per requesting IP prefix, per their public docs), so leave it off unless you actually need the flags.

The hybrid fallback

Real-world robustness note: if the DB-IP CDN is slow or throws a 5xx during download, the actor doesn't just fail. It falls back to calling ipwho.is directly for every input IP. You lose the sub-millisecond local-lookup speed, but the JSON output shape is identical and your run still succeeds. The data_source key ("dbip" / "ipwho.is" / "dbip+ipwho.is" / "error") tells you exactly which backend served each record, so you can audit upstream reliability on your own datasets.

Input

{
"ips": ["8.8.8.8", "1.1.1.1", "208.67.222.222", "2606:4700:4700::1111"],
"include_asn": true,
"include_vpn_check": false,
"batch_size": 50
}
FieldTypeDefaultDescription
ipsstring[]1 to 1,000 IPv4 or IPv6 addresses.
include_asnbooltrueAttach asn + asn_org from the DB-IP ASN Lite dataset.
include_vpn_checkboolfalseCall ipwho.is to populate is_proxy / is_vpn.
batch_sizeint50Max concurrent per-IP tasks (1-100).

Output schema

One dataset record per input IP. The full field set is documented in .actor/dataset_schema.json. Highlights:

  • country_code, country_name, region, city — human-readable location.
  • latitude, longitude — decimal coordinates, typically accurate to a few kilometers at city level.
  • timezone — IANA identifier (e.g. "America/New_York").
  • asn, asn_org — Autonomous System Number + organization.
  • is_proxy, is_vpn — null unless include_vpn_check: true.
  • data_source"dbip", "ipwho.is", "dbip+ipwho.is", or "error".
  • lookup_time_ms — per-IP wall-clock resolution time.

Pricing

$0.0005 per IP lookup (event: ip-lookup). That's:

  • 1/60th of what IPinfo charges ($0.03/lookup on their paid plans, ballpark).
  • Roughly half of MaxMind's per-lookup cost on their licensed GeoIP2 products, without the flat annual fee.
  • Cheap enough that a 10,000-IP enrichment job costs $5.

You're paying for the orchestration, the CDN hit for the monthly DB-IP snapshot, the hybrid fallback logic, and the stable unified schema. The underlying data is CC-BY-4.0 — attribution to DB-IP is baked into this README and required for any redistribution of the raw dataset, but not for your use of the JSON output.

When not to use this

Be honest about the tradeoffs:

  • City-level accuracy. DB-IP Lite, like MaxMind GeoLite2, gives you city — not street. If you need rooftop accuracy, you need a commercial dataset (and you're going to pay 100x more for it).
  • Mobile carrier IPs. Cellular NAT pools bounce around; country is reliable, city often isn't. This is true of every IP geolocation provider.
  • Real-time fraud scoring. is_proxy / is_vpn here are a basic heuristic from ipwho.is. For high-stakes fraud workflows you still want a dedicated vendor like IPQualityScore or FingerprintJS.
  • Sub-second sync lookups embedded in a hot request path. This is a batch-oriented Apify actor, not a sidecar daemon. If you need per-request latency under 10ms, load the DB-IP CSV directly into your own process.

For "we need to enrich a million log lines a day with country + city + ASN, without getting rug-pulled by another provider" — this is exactly the tool.

Example run

from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("nexgendata/ip-geolocation-replacement").call(
run_input={
"ips": ["8.8.8.8", "1.1.1.1", "208.67.222.222"],
"include_asn": True,
"include_vpn_check": False,
}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item["ip"], "->", item["city"], item["country_code"], "|", item["asn_org"])

Expected output:

8.8.8.8 -> Mountain View US | Google LLC
1.1.1.1 -> Sydney AU | Cloudflare, Inc.
208.67.222.222 -> San Francisco US | Cisco OpenDNS LLC

Caveats & honest notes

  • DB-IP CDN flakiness. On a cold Apify container, downloading ~50 MB from the DB-IP mirror usually takes 15-30 seconds, but we've seen occasional 5xx spikes. The actor transparently falls back to ipwho.is when that happens — you'll see data_source: "ipwho.is" on every record and a warning in the log. Your results are still valid; they're just slower and subject to ipwho.is's per-prefix rate limits.
  • Country-name coverage. The built-in country_code -> country_name map covers ~70 common countries. For unlisted codes, country_name falls back to the uppercase two-letter code — is_proxy / asn / lat-lng are unaffected.
  • Attribution. Data is sourced from DB-IP Lite (https://db-ip.com, CC-BY-4.0) and ipwho.is (free tier). If you republish the raw CSV, maintain attribution. If you ship downstream features built on the JSON output, you don't have to.
  • Monthly data freshness. DB-IP publishes new Lite snapshots on the first of each month. The actor's /tmp cache is per-container, so a cold start pulls the latest automatically.

Why this exists

NexGenData builds drop-in replacements for "freemium → gated" data APIs. IPinfo's 2025 tier cut and MaxMind's license-key enforcement created a clear gap. DB-IP has been the quietly-excellent third choice for years, but using its CSV raw requires rolling your own range-tree parser, caching layer, and fallback logic. We did that. You get a stable Apify actor with one-line integration and a flat $0.0005/IP price.

If you're escaping IPinfo or wrestling with MaxMind's license-key plumbing, this is the fastest path forward.