Regional to Global - Adapting Amazon Location Service for Worldwide Use
Let me show you how to transform a regional AWS service into a global AWS service
Updated: 2024-03-18 - Post now has fully deployable Cloudformation Templates: https://github.com/jeeshofone/LocationServiceGateway
While building findyourfivepm.com, I found myself knee-deep in the world of mapping services. The heart and soul of the site, the map, had to be more than just functional - it had to be a cheetah on steroids.
This map had to be the trifecta of digital cartography - it's like the age-old dilemma: cost, speed, quality. pick any two; however, two will not do. For I am not made of money, have no desire to pan around slowly, and I refuse to provide you a mediocre product.
After a thorough comparison of many map providers, Amazon Location Service emerged as the winner. But it had one drawback.
(I'm going to save myself some carpal tunnel syndrome and refer to Amazon Location Service as ALS from here on out.)
When my map is zipping around at warp speed, it needs to serve up image tiles faster than a sushi chef on a Saturday night. Every millisecond is a race against time. This became glaringly obvious during a quick trip from Sydney to the US. I had initially set up my ALS-based map in Sydney (ap-southeast-2), and upon touching down in the US, I was eager to show my unimpressed friends this beautiful and exceptionally useful website. But the map was moving so fast that I couldn’t even see any of the tiles until it stopped. What had happened? This worked perfectly at my house in Sydney!
My latency to the mapping service was a mere 350ms, which might not sound like much, but in the world of real-time map tile delivery, it's a lifetime.
What doesn’t work
Using Amazon Location Services, you can create location-enabled, and mapping applications without the operational burden and complexity of building and maintaining your own location-based services. Maintaining your own mapping service is hard, needs constant updating and takes up a ton of disk space. https://github.com/maptiler/tileserver-gl While Amazon Location Services exists in 13 (as of December 2023) different AWS regions and 2 GovCloud regions, there is no native way to direct end users to use the API in the region closest to them.
So let’s first look at some obvious but non-functional options.
What if I simply put a Route53 Latency Based Routing DNS entry for each API endpoint provided by AWS (
geo.us-east-1.amazonaws.com
,geo.ap-southeast-2.amazonaws.com
, etc) to be mapped togeo.mydomain.com
?SSL validation will fail on the client side because Amazon Location Services provides the SSL certificate and it won’t match
geo.mydomain.com
What if I put client side logic into the website to select the closest region and then direct the user there??
Amazon Location Service uses either IAM, Cognito, or API Keys to facilitate access. If you wanted to have un-authenticated users access your location service, you would need to setup an API Key and enable CORS, or anyone could use your API to load maps on their services (expensive for you, cheap for them) You also need a way to manage all those API key in your client side and rotating those keys would become a
funtask.
What does work
Let me show you why and how it works.
In each region - I have created a copy of the same architecture.
ALS with an Esri Navigation style map, and an API Key (you can’t use the same API keys across multiple regions and
you can’t use Cloudformation to make API Keys for ALS!!)API-Gateway with a request path proxy rule that injects the right API key for this region into the query string, and a certificate for geo.findyourfivepm.com
In Route53 I have created a set of A Records for geo.findyourfivepm.com
that uses latency based routing to automatically direct you to the closest region. Additionally I have health checks on these endpoints. If a region is having a bad day, I can send you over to one that isn’t, keeping those 5pm moments flowing.
Now I just need to update my javascript to use this new technique properly.
Above is what I was using to call ALS on a single region. I provide the API Key, the region name, the map name and then combine those into a style URL.
Now I only need to define the mapName. Route53 will direct the user to the location with the least latency between them and the request will land on API-Gateway which will inject ?key=”v1.public.abcdefg123…”
into the end of the URL string and pass the request onto ALS.
Let’s explore this in more depth.
🎵Simply having a wonderful mapping time🎵
Remember when I mentioned that I care about cost?
Let’s review how this changes the price of the solution.
For HTTP APIs, the API Gateway free tier includes one million API calls per month for up to 12 months. (1)
Now if I became really popular (probably because you’re going to share this post and visit findyourfivepm.com every day?) how much would it cost me?
In the last 30 days I’ve had 60.8k tiles served and 941 page views/cities returned.
I get about 400k map tiles served every 6months. You can also see in the graph below the period of time where I was only using ap-southeast-2 to serve my map tiles. When I switched to the architecture in this post, you can see both how the number of views increased, but also from which locations they originate. Most of my current user base is closer to us-east-2 than not, and traffic in eu-central-1 is picking up as well.
So pricing. It could get expensive, if I had many million API calls, and after you make my website popular, and I have 100 million tiles served a month will I be paying $3.50/million * 99 Million = $346/month just for this localized routing via API Gateway?
No, I will not and here’s why.
Lets inspect the initial request to geo.findyourfivepm.com.
Our call goes out to the URL of my latency based Route53 query and is handled by our API Gateway to:
geo.findyourfivepm.com/maps/v0/maps/Geo-5pm-Map/style-descriptor
We then get back this style descriptor document. Let’s inspect that.
Fantastic. We sent a single request thru the API-Gateway, it returned a style document from Amazon Location Service and in that style document we find paths directly to ALS (and not our API-Gateway!) with our API key pre-injected. No further requests will be sent to this API-Gateway endpoint as this document configures the local client to make calls directly to these endpoints on ALS. This should be free for me to use up to about 1 million page views a month. The ratio of page views to tile’s served is currently 60800 Tiles / 941 cities viewed or about 64.6 tiles served per city. I will be more concerned about the cost of serving ALS tiles well before I begin to pay anything for my global API-Gateway setup.
Let’s do that math.
If I have the maximum free tier usage of API-Gateway at 1,000,000 requests in a month thats 64,000,000 tiles served. I am using Esri maps
, which is a commercial data provider so I pay $0.040 per 1,000 tiles. This is about $2,560 for 64 million tiles and $0.00 for 1 million requests to API-Gateway. While I hope that if my site is that popular I can make some return on investment, I will be much more concerned about the tiles than the efficient, local and speedy way I can serve them to you.
Let’s look at the other costs.
I have an ACM certificate in each region for geo.findyourfivepm.com
but all ACM certs are free.
There’s one more cost to consider and it might surprise you. Route53.
You might think I’m paying $0.20/million queries more than a standard query for a latency based query but they’re actually free. These are alias queries and alias queries are all FREE.
Free is good and if my math is right, this solution costs no more than if all my map tiles are served from a single region - unless you finally make me popular and start sending me over a million page views a month.
This solution is ingeniously simple yet effective if i do say so myself. By replicating the Amazon Location Service setup across various regions(I’m using 7) and utilizing API-Gateway with custom proxy rules, I can dynamically inject the correct regional API key. All the while, Route53's latency-based routing seamlessly directs users to the closest endpoint, ensuring optimal performance.
This architecture not only solved the latency issue but also proved to be cost-efficient. Leveraging API Gateway's free tier and the fact that additional requests are handled directly by ALS!
I hope you’ve found this post while working on your own mapping solution and that it can guide you towards a fast, good and cheap win.
Try it for yourself!
Take a look at https://github.com/jeeshofone/LocationServiceGateway for my full guide on deploying this solution yourself. You’ll find fully functional Cloudformation Templates and deployment scripts. Happy Mapping!