El problema: una factura que se dispara en cada pico de tráfico
VoglioMap es un mapa interactivo que localiza a los distribuidores de Voglio Bene en todo el mundo. En cada visita, el navegador carga el mapa, geolocaliza al usuario, geocodifica su dirección, calcula rutas, muestra marcadores. Multiplica eso por unos cientos de visitantes al mes y la factura de Google Maps sube rápido.
Al principio rondaba los 250 €/mes. No era catastrófico, pero era inútil: la mayoría de esas llamadas eran redundantes. Con unas cuantas optimizaciones puntuales, bajé por debajo de los 50 €/mes - un -80% - sin perder funcionalidad.
Estas son las 4 técnicas que marcaron la diferencia.
1. Cachear el geocoding en base de datos
El geocoding (transformar una dirección en coordenadas GPS) es la llamada más cara de la API de Maps. Y también la más frecuente: cada vez que se añade un nuevo distribuidor, cada vez que se re-geocodifican direcciones en una visita.
Pero una dirección no cambia todos los días.
Añadí una tabla geocode_cache en MySQL:
CREATE TABLE geocode_cache (
address_hash VARCHAR(64) PRIMARY KEY,
address TEXT,
lat DECIMAL(10, 7),
lng DECIMAL(10, 7),
geocoded_at DATETIME
);
Antes de cada llamada a la API de Geocoding, calculo el hash SHA-256 de la dirección normalizada y miro si ya está en caché. Si sí, devuelvo las coordenadas almacenadas. Si no, llamo a Google, guardo el resultado y lo reutilizo en todas las peticiones futuras.
Resultado: 95% de las llamadas de Geocoding eliminadas. La factura en esa línea pasó de ~80 €/mes a ~5 €/mes.
2. Rate limiting en los endpoints públicos
Sin rate limiting, cualquiera puede saturar tu frontend (un script que recarga la página, un bot malintencionado) y hacer explotar la factura en unas horas. A mi sitio le pasó una vez - y la mala sorpresa se vio en la factura del mes siguiente.
Añadí un middleware en PHP:
function checkRateLimit($ip) {
$key = "rate:$ip";
$count = apcu_fetch($key) ?: 0;
if ($count >= 60) return false; // máx. 60 peticiones / hora
apcu_store($key, $count + 1, 3600);
return true;
}
60 peticiones por IP a la hora es de sobra para un uso humano y bloquea los abusos. También añadí un check en la API para los endpoints sensibles (búsqueda, navegación), con un umbral más bajo (10/h para la navegación).
Resultado: cero picos anormales desde entonces. La factura se ha vuelto predecible.
3. Lazy load de los marcadores y clustering
Mostrar todos los marcadores de golpe cuando tienes unos cientos sobrecarga el navegador y dispara más llamadas a la API. La solución: cargar solo los marcadores visibles en el viewport.
Uso el evento bounds_changed de Google Maps para obtener las coordenadas visibles y después hago un fetch de los marcadores en esa zona. En el servidor es un simple WHERE lat BETWEEN x AND y AND lng BETWEEN x AND y - rápido con índices espaciales.
También activé MarkerClusterer: en vez de mostrar 200 marcadores individuales al hacer zoom out, se agrupan en clusters numerados. Mucho más legible y mucho menos DOM que gestionar.
Resultado: menos llamadas a places.nearbySearch() y un sitio que sigue fluido incluso con muchos distribuidores.
4. Static Maps para las vistas no interactivas
No todas las páginas necesitan un mapa interactivo. En las fichas individuales de distribuidor, por ejemplo, el usuario solo quiere ver la ubicación - no va a hacer zoom ni explorar.
Para esos casos, sustituí el embed de JavaScript por la API Static Maps, que devuelve una imagen PNG. El coste es ~10 veces menor por llamada y además carga más rápido (una simple imagen frente a un script JS que inicializa el mapa).
<img src="https://maps.googleapis.com/maps/api/staticmap?
center=43.6108,3.8767
&zoom=14
&size=400x300
&markers=color:red%7C43.6108,3.8767
&key=YOUR_API_KEY"
/>
Bonus: las imágenes las cachea el navegador, así que volver a la misma ficha = cero llamadas nuevas.
Resultado: ~30% de las llamadas JavaScript convertidas en Static Maps, ~10 veces más baratas.
El balance en cifras
| Concepto | Antes | Después |
|---|---|---|
| Geocoding API | 80 €/mes | 5 €/mes |
| Maps JavaScript API | 130 €/mes | 30 €/mes |
| Places API | 40 €/mes | 8 €/mes |
| Total | 250 €/mes | 43 €/mes |
¿Y la experiencia de usuario? Ninguna degradación visible. Al contrario, el sitio carga más rápido (Static Maps + lazy load de marcadores) y está protegido contra abusos.
Lo que me llevo de esto
La API de Google Maps no es cara en absoluto - es cara por defecto, porque no hace ninguna optimización por ti. Pagas cada llamada, sea útil o redundante.
Cachear, aplicar rate limiting, hacer lazy load: son cosas básicas, pero rara vez se hacen en las implementaciones estándar. Si partes de un mapa no optimizado, dividir tu factura entre 3 o 5 está probablemente a unas pocas horas de desarrollo.
Y si tu tráfico se dispara un día: tus optimizaciones te protegen del shock tarifario. Eso también es ROI.
