maxmind-db/reader
The official PHP API for reading MaxMind DB files, which store data indexed by IPv4 or IPv6 subnets. Install via Composer for the pure PHP implementation or the C extension for faster lookups.
.mmdb) binary format — a Reader, a get() and a getWithPrefixLen(), and nothing else. If the decision is on the table, this is the cheapest possible "build" half: no per-lookup fee, no outbound HTTP, no PII leaving your infrastructure, sub-millisecond local reads.libmaxminddb/PIE/PECL to your image build. That's an ops cost decision: adopt the extension only when lookup volume or latency SLOs justify it. Note the extension is a runtime swap, so you can defer this decision indefinitely without an architecture change.InvalidDatabaseException on breach). This is the difference between "we can only read databases we produced" and "we can read a customer- or partner-supplied .mmdb safely." If a "bring your own database" or partner-data-import feature is on the roadmap, that release is your green light.Adopt when:
.mmdb files — GeoLite2, commercial GeoIP2, or your own custom MMDB built for any IP-keyed dataset (this format is a general-purpose IP-subnet keyed store, not geo-only).Look elsewhere when:
geoip2/geoip2 wraps this and gives you typed records; a Laravel wrapper adds the service provider. Most teams should consume that, and take this transitively.CF-IPCountry or CloudFront-Viewer-Country, you may not need a database at all.gmp/bcmath where 128-bit values might appear (no MaxMind-published database currently uses them).One caveat on the data: the "0 dependents" figure reflects incomplete registry metadata, not reality — this is a foundational package with substantial transitive reach. Don't let that number drive the decision.
To executives: A small, permissively licensed library that lets us answer "where is this user?" from our own servers with no per-lookup fees and no user IPs leaving our infrastructure. It is infrastructure, not a feature — the feature value comes from the data subscription and the refresh pipeline we build around it. Low lock-in, low cost, low risk; the two things to fund are the data license and the update job, not the code.
To engineering: composer require maxmind-db/reader, three lines to a working lookup, returns plain arrays, PSR-1/2, semver, actively released. It's a pure-PHP reader with an optional drop-in C extension for hot paths — same class, no code change, so we can defer that tuning. Realistically it's already in the dependency tree via geoip2/geoip2; the decision is whether we call it directly or wrap it. Wrap it: one small service class, config-driven path, a cache in front, getWithPrefixLen() where we care about subnet granularity, and error handling for missing/corrupt files. Keep the Reader out of controllers, and pin the version — recent releases have carried meaningful decoder hardening.
How can I help you explore Laravel packages today?