---
title: "Configuration — Geolocation for Laravel | Roundly"
description: "Every config key, default and env variable — pipeline, providers, timeout, cache, events, the fallback location and each provider’s service block."
url: https://roundly-consulting.com/open-source/docs/geolocation-for-laravel/configuration
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Geolocation for Laravel](https://roundly-consulting.com/open-source/docs/geolocation-for-laravel.md)

# Configuration

Published to config/geolocation.php. The full file, with the per-provider rate\_limits blocks collapsed (they are covered in Rate limiting):

```php
use RoundlyConsulting\Geolocation\Providers\DefaultLocationProvider;
use RoundlyConsulting\Geolocation\Providers\GoogleProvider;
use RoundlyConsulting\Geolocation\Providers\IP2LocationProvider;
use RoundlyConsulting\Geolocation\Providers\IpInfoProvider;
use RoundlyConsulting\Geolocation\Providers\MaxMindDatabaseProvider;
use RoundlyConsulting\Geolocation\Providers\MaxMindWebServiceProvider;

return [
    'pipeline' => ['maxmind_database', 'maxmind_web', 'ip2location', 'ipinfo', 'google', 'default'],

    'providers' => [
        'maxmind_database' => MaxMindDatabaseProvider::class,
        'maxmind_web' => MaxMindWebServiceProvider::class,
        'ip2location' => IP2LocationProvider::class,
        'ipinfo' => IpInfoProvider::class,
        'google' => GoogleProvider::class,
        'default' => DefaultLocationProvider::class,
    ],

    'timeout' => env('GEOLOCATION_TIMEOUT', 5),

    'cache' => [
        'enabled' => env('GEOLOCATION_CACHE', false),
        'store' => env('GEOLOCATION_CACHE_STORE'),
        'ttl' => env('GEOLOCATION_CACHE_TTL', 86400),
        'prefix' => env('GEOLOCATION_CACHE_PREFIX', 'geolocation'),
    ],

    'events' => [
        'enabled' => env('GEOLOCATION_EVENTS', true),
    ],

    'default' => [
        'humanReadable' => env('GEOLOCATION_DEFAULT_HUMAN_READABLE', ''),
        'street' => env('GEOLOCATION_DEFAULT_STREET', ''),
        'city' => env('GEOLOCATION_DEFAULT_CITY', ''),
        'country' => env('GEOLOCATION_DEFAULT_COUNTRY_ISO_CODE', ''),
        'latitude' => env('GEOLOCATION_DEFAULT_LATITUDE', 0.0),
        'longitude' => env('GEOLOCATION_DEFAULT_LONGITUDE', 0.0),
    ],

    'services' => [
        'ipinfo' => [
            'url' => env('IPINFO_URL', 'https://ipinfo.io/'),
            'token' => env('IPINFO_TOKEN'),
            'retry' => env('IPINFO_RETRY_TIMES', 3),
            'retry_delay' => env('IPINFO_RETRY_DELAY_MS', 100),
            'rate_limits' => [/* see Rate limiting */],
        ],

        // Geocoding (address and coordinate lookups) calls the Geocoding API at "url";
        // distances call the Routes API (computeRouteMatrix) at "routes_url". The key
        // needs both APIs enabled.
        'google' => [
            'url' => env('GOOGLE_MAPS_URL', 'https://maps.googleapis.com/maps/api'),
            'routes_url' => env('GOOGLE_ROUTES_URL', 'https://routes.googleapis.com'),
            'key' => env('GOOGLE_MAPS_API_KEY'),
            'retry' => env('GOOGLE_MAPS_RETRY_TIMES', 3),
            'retry_delay' => env('GOOGLE_MAPS_RETRY_DELAY_MS', 100),
            'rate_limits' => [/* ... */],
        ],

        'ip2location' => [
            'url' => env('IP2LOCATION_URL', 'https://api.ip2location.io'),
            'key' => env('IP2LOCATION_API_KEY'),
            'retry' => env('IP2LOCATION_RETRY_TIMES', 2),
            'retry_delay' => env('IP2LOCATION_RETRY_DELAY_MS', 100),
            'rate_limits' => [/* ... */],
        ],

        'maxmind_web' => [
            'enabled' => env('MAXMIND_WEB_ENABLED', false),
            'base_url' => env('MAXMIND_WEB_URL', 'https://geoip.maxmind.com/geoip/v2.1'),
            'account_id' => env('MAXMIND_ACCOUNT_ID'),
            'license_key' => env('MAXMIND_LICENSE_KEY'),
            'service' => env('MAXMIND_WEB_SERVICE', 'city'), // city|country|insights
            'retry' => env('MAXMIND_WEB_RETRY_TIMES', 2),
            'retry_delay' => env('MAXMIND_WEB_RETRY_DELAY_MS', 100),
            'rate_limits' => [/* ... */],
        ],

        'maxmind_database' => [
            'enabled' => env('MAXMIND_DB_ENABLED', false),
            'path' => env('MAXMIND_DB_PATH', storage_path('app/geolocation/GeoLite2-City.mmdb')),

            // Used by the geolocation:db:update command to download the .mmdb file.
            'license_key' => env('MAXMIND_LICENSE_KEY'),
            'edition' => env('MAXMIND_DB_EDITION', 'GeoLite2-City'),
            'download_url' => env('MAXMIND_DB_DOWNLOAD_URL', 'https://download.maxmind.com/app/geoip_download'),
        ],
    ],
];
```

## Every key

| Key | Default | Env | Purpose |
| --- | --- | --- | --- |
| `pipeline` | all six names | — | Ordered provider names to consult; the first non-empty result wins and an unreachable provider is skipped. A bundled name you removed from providers is skipped; any other unregistered name throws UnknownProviderException, and a non-list throws InvalidConfigurationException. An empty list consults providers in its own order. |
| `providers` | bundled map | — | Name → provider class. Every entry needs a name; an unnamed one throws UnknownProviderException. |
| `timeout` | 5 | `GEOLOCATION_TIMEOUT` | HTTP timeout in seconds for every HTTP-backed provider, at least 1. A per-call timeout override is held to the same rule (a blank one is not set, so the config applies). |
| `cache.enabled` | false | `GEOLOCATION_CACHE` | Cache successful lookups and distances (never the default fallback). |
| `cache.store` | null | `GEOLOCATION_CACHE_STORE` | Cache store; null or blank = the default store. A non-string value throws. |
| `cache.ttl` | 86400 | `GEOLOCATION_CACHE_TTL` | Cache TTL in seconds, at least 1. |
| `cache.prefix` | geolocation | `GEOLOCATION_CACHE_PREFIX` | Cache key prefix. A blank value is not set (the default); a non-string value throws. |
| `events.enabled` | true | `GEOLOCATION_EVENTS` | Dispatch resolution events. |
| `default.humanReadable` | '' | `GEOLOCATION_DEFAULT_HUMAN_READABLE` | Fallback location’s display name. |
| `default.street` | '' | `GEOLOCATION_DEFAULT_STREET` | Fallback street. |
| `default.city` | '' | `GEOLOCATION_DEFAULT_CITY` | Fallback city. |
| `default.country` | '' | `GEOLOCATION_DEFAULT_COUNTRY_ISO_CODE` | Fallback ISO country code. |
| `default.latitude` | 0.0 | `GEOLOCATION_DEFAULT_LATITUDE` | Fallback latitude, -90 to 90. A blank value is not set (0.0); a non-number throws. |
| `default.longitude` | 0.0 | `GEOLOCATION_DEFAULT_LONGITUDE` | Fallback longitude, -180 to 180. A blank value is not set (0.0); a non-number throws. While every default.\* value is empty or zero (as shipped), the default provider answers null. |
| `services.ipinfo.url` | https://ipinfo.io/ | `IPINFO_URL` | IPinfo base URL. A blank value is not set (the default); a non-string value throws. |
| `services.ipinfo.token` | null | `IPINFO_TOKEN` | IPinfo token; omitted when null (unauthenticated request). |
| `services.ipinfo.retry` | 3 | `IPINFO_RETRY_TIMES` | Retry attempts, 0 or more. |
| `services.ipinfo.retry_delay` | 100 | `IPINFO_RETRY_DELAY_MS` | Retry delay in ms, 0 or more. |
| `services.google.url` | https://maps.googleapis.com/maps/api | `GOOGLE_MAPS_URL` | Geocoding API base URL (address and coordinate lookups). A blank value is not set (the default); a non-string value throws. |
| `services.google.routes_url` | https://routes.googleapis.com | `GOOGLE_ROUTES_URL` | Routes API base URL (distances and matrices, computeRouteMatrix). A blank value is not set (the default); a non-string value throws. |
| `services.google.key` | null | `GOOGLE_MAPS_API_KEY` | Google Maps Platform key with the Geocoding API and the Routes API enabled — sent as the key query parameter to Geocoding and in the X-Goog-Api-Key header to Routes. |
| `services.google.retry` | 3 | `GOOGLE_MAPS_RETRY_TIMES` | Retry attempts, 0 or more. |
| `services.google.retry_delay` | 100 | `GOOGLE_MAPS_RETRY_DELAY_MS` | Retry delay in ms, 0 or more. |
| `services.ip2location.url` | https://api.ip2location.io | `IP2LOCATION_URL` | IP2Location.io base URL. A blank value is not set (the default); a non-string value throws. |
| `services.ip2location.key` | null | `IP2LOCATION_API_KEY` | IP2Location.io API key. |
| `services.ip2location.retry` | 2 | `IP2LOCATION_RETRY_TIMES` | Retry attempts, 0 or more. |
| `services.ip2location.retry_delay` | 100 | `IP2LOCATION_RETRY_DELAY_MS` | Retry delay in ms, 0 or more. |
| `services.maxmind_web.enabled` | false | `MAXMIND_WEB_ENABLED` | Enable the MaxMind web-service provider. |
| `services.maxmind_web.base_url` | https://geoip.maxmind.com/geoip/v2.1 | `MAXMIND_WEB_URL` | Web-service base URL. A blank value is not set (the default); a non-string value throws. |
| `services.maxmind_web.account_id` | null | `MAXMIND_ACCOUNT_ID` | MaxMind account ID (HTTP Basic user). |
| `services.maxmind_web.license_key` | null | `MAXMIND_LICENSE_KEY` | MaxMind license key (HTTP Basic password); withToken('maxmind\_web', …) replaces it per call. |
| `services.maxmind_web.service` | city | `MAXMIND_WEB_SERVICE` | city, country or insights; a blank value is not set (city); anything else throws InvalidConfigurationException. |
| `services.maxmind_web.retry` | 2 | `MAXMIND_WEB_RETRY_TIMES` | Retry attempts, 0 or more. |
| `services.maxmind_web.retry_delay` | 100 | `MAXMIND_WEB_RETRY_DELAY_MS` | Retry delay in ms, 0 or more. |
| `services.maxmind_database.enabled` | false | `MAXMIND_DB_ENABLED` | Enable the local .mmdb provider. |
| `services.maxmind_database.path` | storage\_path('app/geolocation/GeoLite2-City.mmdb') | `MAXMIND_DB_PATH` | Path to the .mmdb file. |
| `services.maxmind_database.license_key` | null | `MAXMIND_LICENSE_KEY` | License key used by geolocation:db:update. |
| `services.maxmind_database.edition` | GeoLite2-City | `MAXMIND_DB_EDITION` | Edition the update command downloads. A blank value is not set (the default); a non-string value throws. |
| `services.maxmind_database.download_url` | https://download.maxmind.com/app/geoip\_download | `MAXMIND_DB_DOWNLOAD_URL` | Download URL base. A blank value is not set (the default); a non-string value throws. |
| `services.<provider>.rate_limits.*` | see Rate limiting | `GEOLOCATION_<PROVIDER>_RATELIMIT*` | Outbound pacing for google, ipinfo, ip2location and maxmind\_web. |

Every boolean switch (cache.enabled, events.enabled, the MaxMind enabled flags and the rate\_limits enabled / adaptive keys) accepts true/false, 1/0, on/off or yes/no, from .env or the published file; an unset or blank one takes its default, and anything else (say GEOLOCATION\_CACHE=disabled) throws package-toolkit’s InvalidConfigurationException naming the key on the first lookup.

Every other setting is just as strict. An integer must be a whole number (30 or "30"; five, 5.5 and 1e3 throw rather than becoming 0), a string setting must be a string, and a fixed vocabulary (per, services.maxmind\_web.service) rejects anything outside it. A key that is not set — absent, null or blank (a host’s KEY=) — takes its default (an optional max\_wait / jitter stays off).

## Environment

Credentials are read from your application’s environment, so they never live in the package or in version control. A typical production .env:

```bash
GEOLOCATION_TIMEOUT=5
GEOLOCATION_CACHE=true
GEOLOCATION_CACHE_STORE=redis
GEOLOCATION_EVENTS=true

IPINFO_TOKEN=your-ipinfo-token
GOOGLE_MAPS_API_KEY=your-google-maps-key
IP2LOCATION_API_KEY=your-ip2location-key

MAXMIND_DB_ENABLED=true
MAXMIND_LICENSE_KEY=your-license-key
```

services.maxmind\_web.license\_key and services.maxmind\_database.license\_key both read MAXMIND\_LICENSE\_KEY, so one key covers the web service and database downloads.

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/geolocation-for-laravel.md)
