This is a Go reader for the MaxMind DB format. Although this can be used to read GeoLite2 and GeoIP2 databases, geoip2 provides a higher-level API for doing so.
This is not an official MaxMind API.
go get github.com/oschwald/maxminddb-golang/v2Version 2.0 includes significant improvements:
- Modern API: Uses netip.Addrinstead ofnet.IPfor better performance
- Custom Unmarshaling: Implement Unmarshalerinterface for zero-allocation decoding
- Network Iteration: Iterate over all networks in a database with Networks()andNetworksWithin()
- Enhanced Performance: Optimized data structures and decoding paths
- Go 1.23+ Support: Takes advantage of modern Go features including iterators
- Better Error Handling: More detailed error types and improved debugging
package main import ( "fmt" "log" "net/netip" "github.com/oschwald/maxminddb-golang/v2" ) func main() { db, err := maxminddb.Open("GeoLite2-City.mmdb") if err != nil { log.Fatal(err)	} defer db.Close() ip, err := netip.ParseAddr("81.2.69.142") if err != nil { log.Fatal(err)	} var record struct { Country struct { ISOCode string `maxminddb:"iso_code"` Names map[string]string `maxminddb:"names"`	} `maxminddb:"country"` City struct { Names map[string]string `maxminddb:"names"`	} `maxminddb:"city"`	} err = db.Lookup(ip).Decode(&record) if err != nil { log.Fatal(err)	} fmt.Printf("Country: %s (%s)\n", record.Country.Names["en"], record.Country.ISOCode) fmt.Printf("City: %s\n", record.City.Names["en"]) }db, err := maxminddb.Open("GeoLite2-City.mmdb") if err != nil { log.Fatal(err) } defer db.Close() var record any ip := netip.MustParseAddr("1.2.3.4") err = db.Lookup(ip).Decode(&record)type City struct { Country struct { ISOCode string `maxminddb:"iso_code"` Names struct { English string `maxminddb:"en"` German string `maxminddb:"de"`	} `maxminddb:"names"`	} `maxminddb:"country"` } var city City err = db.Lookup(ip).Decode(&city)type FastCity struct { CountryISO string CityName string } func (c *FastCity) UnmarshalMaxMindDB(d *maxminddb.Decoder) error { mapIter, size, err := d.ReadMap() if err != nil { return err	} // Pre-allocate with correct capacity for better performance _ = size // Use for pre-allocation if storing map data for key, err := range mapIter { if err != nil { return err	} switch string(key) { case "country": countryIter, _, err := d.ReadMap() if err != nil { return err	} for countryKey, countryErr := range countryIter { if countryErr != nil { return countryErr	} if string(countryKey) == "iso_code" { c.CountryISO, err = d.ReadString() if err != nil { return err	}	} else { if err := d.SkipValue(); err != nil { return err	}	}	} default: if err := d.SkipValue(); err != nil { return err	}	}	} return nil }// Iterate over all networks in the database for result := range db.Networks() { var record struct { Country struct { ISOCode string `maxminddb:"iso_code"`	} `maxminddb:"country"`	} err := result.Decode(&record) if err != nil { log.Fatal(err)	} fmt.Printf("%s: %s\n", result.Prefix(), record.Country.ISOCode) } // Iterate over networks within a specific prefix prefix := netip.MustParsePrefix("192.168.0.0/16") for result := range db.NetworksWithin(prefix) { // Process networks within 192.168.0.0/16 }var countryCode string err = db.Lookup(ip).DecodePath(&countryCode, "country", "iso_code") var cityName string err = db.Lookup(ip).DecodePath(&cityName, "city", "names", "en")This library supports all MaxMind DB (.mmdb) format databases, including:
MaxMind Official Databases:
- GeoLite/GeoIP City: Comprehensive location data including city, country, subdivisions
- GeoLite/GeoIP Country: Country-level geolocation data
- GeoLite ASN: Autonomous System Number and organization data
- GeoIP Anonymous IP: Anonymous network and proxy detection
- GeoIP Enterprise: Enhanced City data with additional business fields
- GeoIP ISP: Internet service provider information
- GeoIP Domain: Second-level domain data
- GeoIP Connection Type: Connection type identification
Third-Party Databases:
- DB-IP databases: Compatible with DB-IP's .mmdb format databases
- IPinfo databases: Works with IPinfo's MaxMind DB format files
- Custom databases: Any database following the MaxMind DB file format specification
The library is format-agnostic and will work with any valid .mmdb file regardless of the data provider.
- Reuse Reader instances: The Readeris thread-safe and should be reused across goroutines
- Use specific structs: Only decode the fields you need rather than using any
- Implement Unmarshaler: For high-throughput applications, implement custom unmarshaling
- Consider caching: Use Result.Offset()as a cache key for database records
Download from MaxMind's GeoLite page.
- Go 1.23 or later
- MaxMind DB file in .mmdb format
Contributions welcome! Please fork the repository and open a pull request with your changes.
This is free software, licensed under the ISC License.