A high-performance Rust-based Ruby gem for reading MaxMind DB files. Provides API compatibility with the official maxmind-db gem while leveraging Rust for superior performance.
Note: This is an unofficial library and is not endorsed by MaxMind. For the official Ruby library, see maxmind-db.
- High Performance: Rust-based implementation provides significantly faster lookups than pure Ruby
- API Compatible: Familiar API similar to the official MaxMind::DB gem
- Thread-Safe: Safe to use from multiple threads
- Memory Modes: Support for both memory-mapped (MMAP) and in-memory modes
- Iterator Support: Iterate over all networks in the database (extension feature)
- Type Support: Works with both String and IPAddr objects
Add this line to your application's Gemfile:
gem 'maxmind-db-rust'And then execute:
bundle installOr install it yourself as:
gem install maxmind-db-rust- Ruby 3.2 or higher
- Rust toolchain (for building from source)
require 'maxmind/db/rust'
# Open database
reader = MaxMind::DB::Rust::Reader.new(
'GeoIP2-City.mmdb',
mode: MaxMind::DB::Rust::MODE_MEMORY
)
# Lookup an IP address
record = reader.get('8.8.8.8')
if record
puts record['country']['iso_code']
puts record['country']['names']['en']
puts record['city']['names']['en']
end
# Close the database
reader.closerequire 'maxmind/db/rust'
reader = MaxMind::DB::Rust::Reader.new('GeoIP2-City.mmdb')
record, prefix_length = reader.get_with_prefix_length('8.8.8.8')
puts "Record: #{record}"
puts "Prefix length: #{prefix_length}"
reader.closerequire 'maxmind/db/rust'
require 'ipaddr'
reader = MaxMind::DB::Rust::Reader.new('GeoIP2-City.mmdb')
ip = IPAddr.new('8.8.8.8')
record = reader.get(ip)
reader.closerequire 'maxmind/db/rust'
# MODE_AUTO: Uses memory-mapped files (default, best performance)
reader = MaxMind::DB::Rust::Reader.new(
'GeoIP2-City.mmdb',
mode: MaxMind::DB::Rust::MODE_AUTO
)
# MODE_MMAP: Explicitly use memory-mapped files (recommended)
reader = MaxMind::DB::Rust::Reader.new(
'GeoIP2-City.mmdb',
mode: MaxMind::DB::Rust::MODE_MMAP
)
# MODE_MEMORY: Load entire database into memory
reader = MaxMind::DB::Rust::Reader.new(
'GeoIP2-City.mmdb',
mode: MaxMind::DB::Rust::MODE_MEMORY
)require 'maxmind/db/rust'
reader = MaxMind::DB::Rust::Reader.new('GeoIP2-City.mmdb')
metadata = reader.metadata
puts "Database type: #{metadata.database_type}"
puts "Node count: #{metadata.node_count}"
puts "Record size: #{metadata.record_size}"
puts "IP version: #{metadata.ip_version}"
puts "Build epoch: #{metadata.build_epoch}"
puts "Languages: #{metadata.languages.join(', ')}"
puts "Description: #{metadata.description}"
reader.closeIterate over all networks in the database:
require 'maxmind/db/rust'
reader = MaxMind::DB::Rust::Reader.new('GeoLite2-Country.mmdb')
# Iterate over all networks
reader.each do |network, data|
puts "#{network}: #{data['country']['iso_code']}"
break # Remove this to see all networks
end
# Iterate over networks within a specific subnet (String CIDR notation)
reader.each('192.168.0.0/16') do |network, data|
puts "#{network}: #{data['city']['names']['en']}"
end
# Iterate over networks within a specific subnet (IPAddr object)
require 'ipaddr'
subnet = IPAddr.new('10.0.0.0/8')
reader.each(subnet) do |network, data|
puts "#{network}: #{data['country']['iso_code']}"
end
# Use Enumerable methods
countries = reader.map { |network, data| data['country']['iso_code'] }.uniq
puts "Unique countries: #{countries.size}"
reader.closeCreate a new Reader instance.
Parameters:
database_path(String): Path to the MaxMind DB fileoptions(Hash): Optional configuration:mode(Symbol): One of:MODE_AUTO,:MODE_MEMORY, or:MODE_MMAP
Returns: Reader instance
Raises:
Errno::ENOENT: If the database file does not existMaxMind::DB::Rust::InvalidDatabaseError: If the file is not a valid MaxMind DB
Look up an IP address in the database.
Parameters:
ip_address(String or IPAddr): The IP address to look up
Returns: Hash with the record data, or nil if not found
Raises:
ArgumentError: If looking up IPv6 in an IPv4-only databaseMaxMind::DB::Rust::InvalidDatabaseError: If the database is corrupt
Look up an IP address and return the prefix length.
Parameters:
ip_address(String or IPAddr): The IP address to look up
Returns: Array [record, prefix_length] where record is a Hash or nil
Get metadata about the database.
Returns: MaxMind::DB::Rust::Metadata instance
Close the database and release resources.
Check if the database has been closed.
Returns: Boolean
Iterate over networks in the database.
Parameters:
network(String or IPAddr, optional): Network CIDR to iterate within (e.g., "192.168.0.0/16"). If omitted, iterates over all networks in the database.
Yields: IPAddr network and Hash data for each entry
Returns: Enumerator if no block given
Raises:
ArgumentError: If network CIDR is invalid or IPv6 network specified for IPv4-only database
Metadata attributes:
binary_format_major_version- Major version of the binary formatbinary_format_minor_version- Minor version of the binary formatbuild_epoch- Unix timestamp when the database was builtdatabase_type- Type of database (e.g., "GeoIP2-City")description- Hash of locale codes to descriptionsip_version- 4 for IPv4-only, 6 for IPv4/IPv6 supportlanguages- Array of supported locale codesnode_count- Number of nodes in the search treerecord_size- Record size in bits (24, 28, or 32)node_byte_size- Size of a node in bytessearch_tree_size- Size of the search tree in bytes
MaxMind::DB::Rust::MODE_AUTO- Automatically choose the best mode (uses MMAP)MaxMind::DB::Rust::MODE_MEMORY- Load entire database into memoryMaxMind::DB::Rust::MODE_MMAP- Use memory-mapped file I/O (recommended)
MaxMind::DB::Rust::InvalidDatabaseError- Raised when the database file is corrupt or invalid
| Feature | maxmind-db (official) | maxmind-db-rust (this gem) |
|---|---|---|
| Implementation | Pure Ruby | Rust with Ruby bindings |
| Performance | Baseline | 10-50x faster |
| API | MaxMind::DB | MaxMind::DB::Rust |
| MODE_FILE | ✓ | ✗ |
| MODE_MEMORY | ✓ | ✓ |
| MODE_AUTO | ✓ | ✓ |
| MODE_MMAP | ✗ | ✓ |
| Iterator support | ✗ | ✓ |
| Thread-safe | ✓ | ✓ |
Expected performance characteristics (will vary based on hardware):
- Single-threaded lookups: 300,000 - 500,000 lookups/second
- Significantly faster than pure Ruby implementations
- Memory-mapped mode (MMAP) provides best performance
- Fully thread-safe for concurrent lookups
Interested in contributing? See CONTRIBUTING.md for detailed developer documentation, including:
- Development setup and prerequisites
- Building and testing the extension
- Code quality guidelines
- Project structure
- Submitting changes
git clone https://github.com/oschwald/maxmind-db-rust-ruby.git
cd maxmind-db-rust-ruby
git submodule update --init --recursive
bundle install
bundle exec rake compile
bundle exec rake test- Fork it
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request
This software is licensed under the ISC License. See the LICENSE file for details.
- Issues: https://github.com/oschwald/maxmind-db-rust-ruby/issues
- Documentation: https://www.rubydoc.info/gems/maxmind-db-rust
This gem uses the maxminddb Rust crate for the core MaxMind DB reading functionality.