We built our own geo-grid rank tracker. A 49-point scan costs about two rupees.

The commercial geo-grid tools are priced for agencies. We are not an agency. So we tested whether the underlying idea was even possible, then built the thing, and the cost engineering turned out to be the interesting part.

Repeatable measurementPrompt set
Fixed questionsRun ARun BRun C
Category queryComparison queryProblem queryLocation query
Same prompts. Same conditions. Repeated over time.
One caveat up front

This tool queries the Google Places API. Places results are a proxy for Google Maps visibility, not the local pack. They are not the same thing, and nothing below should be read as a local pack ranking.

Why not just buy one

Geo-grid rank tracking is a good idea. A single ranking number for a local business is close to meaningless, because local results change with the position of the person searching. A grid shows you the shape of that, and the shape is where the useful information is.

The problem is price. The commercial tools are built and priced for agencies running many clients. For a two-person consultancy checking a handful of businesses, the monthly cost was not proportionate to the value. So the question became whether the thing could be built directly on the API instead.

The test that came first

Everything depended on one assumption, so we tested it before writing anything else.

Google Places API Text Search accepts a locationBias parameter. The entire concept of a geo-grid rests on that parameter genuinely changing the results by location. If it returned the same ranked list regardless of where you pointed it, there is no tool to build.

Five points around Melbourne CBD, tracking one clinic, 500m radius:

PointTarget positionTop result at that point
Centre1A CBD clinic
North 4km14A Brunswick clinic
South 4km7A South Melbourne clinic
East 4km20+An eastern suburbs clinic
West 4km4A western suburbs clinic

Different results and a different top three at every point. The target moved from first to outside the top twenty across eight kilometres. The method was sound, so the build was worth doing.

Why test first

This took an afternoon and would have saved a week if the answer had been no. The temptation with a build like this is to start with the map and the interface, which are the enjoyable parts, and discover the load-bearing assumption was wrong much later.

The field mask decision

Places API Text Search is billed by field mask, not per call. This is the whole economics of the tool and it is easy to miss.

  • Requesting only places.id puts every call in the Essentials tier: 10,000 free per month, then $5 per 1,000.
  • Adding places.displayName moves it to Pro: 5,000 free per month, then $32 per 1,000.

A rank tracker does not need names. You already know the client's place ID. All you need from each grid point is the ordered list of IDs and the index yours sits at.

With the right mask

49 calls per 7x7 grid. 10,000 free calls a month is 204 free keyword scans. Past that, $0.245 per scan.

With names included

Roughly six times the cost, for a field the tool reads once and throws away.

Asking for the display name feels harmless. It is the difference between a tool that runs essentially free and one that does not.

Designing for the terms, not retrofitting

Google place IDs are explicitly exempt from the Places caching restrictions and can be stored indefinitely. Almost nothing else can. Storing competitor names, addresses, or ratings in a database would breach the terms.

So the tool stores three things: grid coordinates, the client's place ID, and an integer position. That is derived data. The CSV export is the record.

The policy also requires results shown to a user to appear on a Google Map with attribution, which is why the tool renders on a real map rather than drawing its own grid. That constraint turned out to be a feature, for reasons that show up below.

The point

Compliance decided the data model before any code was written. Retrofitting it later would have meant tearing out the storage layer, because the shape of what you are allowed to keep is different from the shape of what the API returns.

What the finished tool found

A dental clinic in central Melbourne, query "dentist", 7x7 grid at 1km spacing:

7x7 grid, 1km spacing, central Melbourne“dentist”
21
16
13
14
14
20
21
16
10
9
9
10
16
21
13
11
6
5
6
19
21
14
13
8
3
2
14
18
12
11
10
4
3
10
17
11
11
12
9
7
10
21
11
12
13
12
11
18
21
WestEast
Top 34 to 1011 to 20Outside 20Failed request
The two darkest cells are not at the centre. The clinic sits at the middle of this grid, and its best visibility is one square down and to the right.

Average position 12.4. In the top three at 6% of points. Outside the top twenty at 12% of points, every one of them on the eastern edge.

The interesting part is not the average. It is that the strongest visibility sits south-east of the clinic, not on it. Two grid points score better than the clinic's own doorstep.

That is a sentence you can say to a business owner and have them understand immediately. The number grid alone does not produce it. The map view does, which is the second reason rendering on a real map was worth the effort.

The undocumented limit

Google does not publish the Maps Demo Key's daily allowance. We found it by hitting it. The 429 response names it exactly:

Quota exceeded for quota metric 'SearchTextRequest'
and limit 'SearchTextRequest per day'
quota_limit_value: 100

100 Text Search calls per day. That is one business lookup plus one 7x7 scan, twice, and you are finished for the day.

One earlier failure looked like the same thing and was not. A single call failed mid-grid while the rest succeeded. That was a burst limit from firing five concurrent requests, not the daily cap. The daily cap fails every request, not one. Worth knowing, because the two look identical if you only read the status code.

What this does not do, and what is not proven

The tool has not been validated against a manual check. We have not sat at each grid point on a phone and compared what Google Maps actually shows against what the API returned. Until that happens, the honest position is that this measures Places API Text Search results, which are a reasonable proxy for Maps visibility and are not the same as it.

That is the outstanding question, and it is a real one. Anyone using a geo-grid tool, ours or a commercial one, is relying on the same proxy.

  • It does not measure the local pack.
  • It has not been validated against manual Maps checks at each point.
  • It reads position only, so it cannot tell you why a position is what it is.
  • The demo key's 100 calls a day makes it a diagnostic tool, not a monitoring one.
The useful output of a grid is not the average position. It is where the boundary sits.

That argument, and the grids that led to it, are in a separate piece.

Need a practical answer?

See what is limiting your visibility.

Send the URL and tell us what you sell. You will get the first issue worth fixing, with the reason behind it.

Request an audit Free · No call required