Auto-Location Inference for Posts: Building a Smart Geofencing System
In digital platforms where content relevance drives engagement, location-based geofencing plays a key role in connecting users with contextually meaningful information. It helps ensure users see posts that are local, timely, and personally relevant, a nearby dog park meet-up, a local pet store promotion, a real-time alert about a lost dog in the neighbourhood. By automatically inferring and assigning location context, platforms can personalise feeds, improve discovery accuracy, and strengthen community interaction.
The challenge
Building a context-aware posting system that personalises content by geography involves several challenges. Users may not always provide precise or consistent location information, posts might lack any geographic reference, fallbacks must handle missing or invalid data, and geofencing operations must remain performant at scale.
Multi-layer location inference
To address incomplete or missing location information, Hoomanely's layered location inference pipeline guarantees a fallback location that ensures every post includes a meaningful geographic context. The system first checks whether a post includes valid location metadata:

from typing import Dict, Optional
VALID_INDIA_IDENTIFIERS = ["India", "IN", "in", "Bharat"]
DEFAULT_COUNTRY = "India"
def validate_location(location: Optional[Dict]) -> bool:
"""Validate if location data is complete and usable."""
try:
return (
location is not None and
location.get('country') and
location['country'].strip() != ""
)
except (AttributeError, TypeError):
return False
post_location = post_data.get('location')
has_valid_post_location = validate_location(post_location)When creating a post, location data gets stored in a standardised nested structure in MongoDB, latitude, longitude, city, country, and zip code, ensuring consistent representation across all posts, easy querying for geofencing, and support for both precise coordinates and region-based filtering.
If the post's location is missing or incomplete, the system falls back to the user's saved profile location. When neither post nor profile location is available, IP-based geolocation acts as a fallback, though it comes with trade-offs, it may be inaccurate for VPN users, mobile users roaming across regions, or corporate networks with centralised IP addresses, and it raises privacy considerations around data protection regulations.
Finally, a predefined default ensures every post is tagged with a valid region, falling back to India as a system constant with specific latitude, longitude, city, and zip code values. Using a default location ensures data completeness but may result in posts being shown to geographically irrelevant users, acceptable for general content but ideally combined with other relevance signals like user interests or engagement patterns.

Smart geofencing system
The geofencing component filters content based on location proximity while maintaining high responsiveness. All geographic filters are executed at the database layer to optimize query performance:
from typing import List
def get_feed_with_geofencing(
self,
user_country: str,
limit: int = 10
) -> List[Dict]:
"""
Retrieve posts filtered by geographic location.
"""
try:
normalized_country = user_country.strip().lower()
if normalized_country in [id.lower() for id in VALID_INDIA_IDENTIFIERS]:
query = {
"$or": [
{"location.country": {"$in": VALID_INDIA_IDENTIFIERS}},
{"location.country": {"$exists": False}},
{"location.country": {"$eq": ""}},
{"location.country": {"$eq": None}}
]
}
else:
query = {
"$and": [
{"location.country": {"$nin": VALID_INDIA_IDENTIFIERS}},
{"location.country": {"$exists": True}},
{"location.country": {"$ne": ""}},
{"location.country": {"$ne": None}}
]
}
return list(self.collection.find(query).limit(limit))
except Exception as e:
logger.error(f"Geofencing query failed: {e}")
return []To ensure optimal query performance, we create indexes on the country field for geofencing queries and a compound index on country plus zip code for priority posts, with similar indexes maintained on the user collection for profile location lookups. These indexes significantly reduce query execution time, especially for large collections.
Critical post types such as alerts or emergency broadcasts use zipcode-level targeting to ensure precise visibility within relevant areas, marking the post as priority and defaulting to the target zipcode with the default country if no location is explicitly set.
Performance optimisation and results
Key optimisations include database-level filtering to minimise unnecessary data transfer, cached user location data to prevent redundant lookups, batch processing with cursor-based pagination, and indexed queries ensuring fast location-based filtering even at scale. The optimised location inference framework helped us achieve measurable improvements, every post now includes valid location context, increased content relevance through region-specific feeds, improved visibility for time-critical locality-based posts, and fast query performance through strategic indexing.
Key takeaways
- A layered approach ensures consistent location inference under all conditions.
- Server-level filtering enhances performance and scalability.
- Special handling for priority or emergency posts improves reliability.
- A standardized location schema simplifies querying and integration.
- And proper validation, error handling, and indexing are critical for production reliability.
- By implementing a structured, multi-layer inference model with standardised geofencing, Hoomanely delivers locally relevant, high-impact content experiences while maintaining reliable system performance.