
I wanted Petroly to find fuel stations across borders.
That simple idea became one of the most interesting architecture projects I have trusted an AI coding agent with.
The constraint
Petroly treated every country as its own world, with a separate database, fuel taxonomy, currency, and routing logic. That worked fine as long as a user only cared about the country they were in.
It falls apart the moment someone is 2km from a border. A driver near the edge of Austria has no way of knowing that fuel is noticeably cheaper a few minutes across the line, because the app was never looking there.
The obvious fix, loading all known stations into the client, was not an option. Some users have weaker Android phones. A route across Europe should not force a phone like that to process tens of thousands of gas stations or run a large routing matrix just to render a map.
Why this task is expensive
Finding stations that look close to a line on a map is easy. Knowing which are actually convenient to visit is not.
A station might be 200 meters from the motorway but require a 15-minute detour because the next exit is kilometers away. A station that looks farther away on a straight line might sit directly beside an exit and cost almost no extra time.
To tell the difference, Petroly needs the driving time and distance from the start to each candidate station, and from each candidate to the destination. A routing matrix calculates these relationships in batches. Comparing that detour against the direct route reveals which stations are genuinely worth a stop.
Every matrix cell requires work across a large road graph. Multiply that by dozens of candidate stations, several route alternatives, and many simultaneous users, and a single unbounded request could occupy every routing worker on the server. That is a capacity problem as much as a routing problem.
The agentic workflow
GPT-5.6 Sol played a major part in solving this. I used it as an agentic engineering partner: analyze the existing code and infrastructure, challenge the architecture, implement changes, run tests, review risks, and fix issues found during real route tests.
I did not ask it to “build cross-border routing” in one prompt. I gave it a measurable goal instead: calculate a route, filter tens of thousands of stations down to a relevant handful, and respond within a second or two. It worked toward that goal iteratively, while I kept product direction and operational decisions explicit, things like which markets to launch with, how aggressive the rate limits should be, and when a proposed shortcut was not acceptable.
The architecture
The resulting design is deliberately boring, in the best possible way:
- Every market still owns its independent source database.
- A single writer imports station data into SQLite with an RTree spatial index.
- The live index contains more than 75,000 fuel stations across 10 countries.
- Spatial filtering reduces that down to at most 32 matrix candidates per request.
- Valhalla runs behind a protected API with bounded concurrency, queueing, timeouts, and rate limiting.
- Fuel matching, currency conversion, detours, and ranking all happen on the server.
- The client receives at most 20 compact station results and display geometry, nothing more.
That boundary solves three problems at once: it protects the expensive matrix work from any single device, it enables cross-border discovery without federating databases on the client, and it keeps performance predictable even on weak hardware.
The details mattered as much as the diagram. Fuel names are not equivalent across countries, “Gasoline” can mean a different product depending on the market. Prices have to be ranked in a common base currency before they can be compared across borders at all. Alternative routes need a sensible fallback for the moments an in-memory cache expires mid-session. None of that shows up in an architecture sketch, but all of it shows up the first time a real user crosses a real border.
A welcome side effect
Moving all of this behind one server boundary unlocked something I had not specifically set out to build: standalone Apple CarPlay and Android Auto support.
The recurring complaint before this was “data is outdated,” shown right after getting in the car. The native CarPlay/Android Auto integrations can now fetch a small, prefiltered set of nearby stations directly from the API, using the current location and saved preferences, without needing the phone app open and freshly synced first. Solving the heavier cross-border problem on the server made the simpler in-car problem fall out for free.
The result
Petroly can now search for addresses across every supported country, calculate routes that cross borders, and recommend suitable fuel stations along the complete journey, not just within whichever country the trip started in.
AI did not remove the need for architecture. GPT-5.6 Sol made it possible to explore, implement, test, and refine that architecture at a speed I would not have considered realistic before. The decisions were still mine to make. The distance between having the idea and having a working version of it got a lot shorter.
If you want to plan a trip around cheaper fuel stops, even across a border, Petroly is available on iOS and Android. The app is free to download.