I wonder if you can change the pricing plans and language around them a little. What happens if I'm going along happily on the 2500/day plan and suddenly I get hit with a traffic spike and need 20,000/day for 3 days until things calm down? If you're going to use pricing buckets like this it probably needs to also come with an automated way to bump the plan if needed.
Someone else in the thread suggested Maxmind as an alternative. Their prices seem to be several times higher than yours. Can you double your prices? It seems really cheap. Too cheap?
Also, the location identified for me was off by 60 miles.
On your Documentation page you've used 8.8.8.8 as an example IP address. And 1.1.1.1, and 2.2.2.2... I'd rather see you use the IPv4 address blocks reserved for documentation by RFC 5737 [0]. That's what they're for! Unfortunately, they probably don't have any actual data associated with them so the examples would need to be fabricated...hmm.
And it looks like actually using one of those results in some output that does not conform to the format on your documentation page, so you'd best also add documentation about error handling.
You can download the Maxmind database locally. I don't see the option for that from IpData. That's worth the price increase for me.
Having a web API is great for low- or mid-volume applications, but adding 10ms per user for an HTTPS call would still be like 1000x slower than hitting a local DB.
Just cache the responses so that only the first time a new IP connects it needs to be looked up (until cache fills)
Integrating maxmind is a bit of a pain and it’s a massive database. Not well suited to use cases like single purpose or ephemeral containers.
You’ll probably end up storing the maxmind db in a separate node on your local network, anyway. So you still have a latency issue (although lower, obviously). More importantly you now need to maintain an extra box per replicated cluster. It could make sense to outsource that management if the latency between your data center and ipdata is acceptable. Such low latency is easily achievable if ipdata has BGP anycast on servers in the same cloud region as your app.
We already do something like that, marking up the user information with geoip information when we first see them, but we just get a lot of unique users. (Yes, we could do batch lookups, but that would be a complete rewrite of our workflow.)
I found Maxmind integration to be pretty straight-forward. They have APIs for most popular languages and most of the time, usage amounts to instantiating a reader object with the path to the database, then calling methods on that object with the IP in question. So, db.city(ip) returns all of the city information, etc.
Massive is a relative term I guess. But the databases are segmented, so you only take what you need and all the ones I've worked with have been tens of megabytes in size.
I consider 100mb to be quite large. That could easily double memory consumption of an application. Most http services are light but widely replicated. Adding 100mb of memory usage to each replica is certainly a tradeoff.
What exactly do you mean by web server? Generally you will have at least one server process wherever you do the maxmind lookup, which could be at the LB/proxy (Nginx) or app server (node, python, go, etc).
Nowadays these services are often heavily decoupled and therefore built to be as lightweight as possible. Think about small single purpose containers. Adding 100mb of memory requirements per instance could be quite expensive, depending which existing process is calling maxmind.
Say you have python/ruby/js processes. You usually build 1 box/container with multiple processes inside. If you have 100 services and you distribute 1 process of each in each box then THAT is your problem.
are you passing the original ip addresses to all these containers? Why don't you just decode the ip to location at the edge of your network (typically load balancer) and add a header with location?
You're right, they're definitely many cases where incorporating any calls to external resources would be the wrong call and where hitting a local copy of a db would be the best solution.
An API such as this exists would be a great choice where you need to modify content on the frontend. In which case you'd benefit from the availability of 10 endpoints around the world from which the API is available to provide the lowest latency to your users.
I get what you mean. However from the use cases I've seen often whatever processing needs to be done eg. showing a banner ad to users from a particular state or redirecting to a country specific version of a site can be handled from the user's browser.
Even if you're not hosting the country specific site in that region your user will still save time on making the call to our endpoint local to them.
I've actually been seriously considering adding a pay as you go plan, where you pay for only per the number of requests you make,is this something that would interest you? The current prices are an extended Cyber Monday offer, I figured I'd let it run into the holidays.
Unfortunately it's never going to be spot on all the time.
Awesome points on the example ips and adding error handling documentation. Thanks for pointing me to rfc5737!
I'm adding the Error Code documentation right now.
Added a table with Error Codes and their accompanying messages.
It's more fun to sell metered services to people than "plans". You can get the best of both worlds by having a per unit price, and then giving people discounts for committing to certain usage levels.
Plans are kind of a pain because you have to have a sales process to get people to change. Mailchimp automatically upgrades/downgrades people between plans, which is a decent workaround, but still a little weird to customers.
Someone else in the thread suggested Maxmind as an alternative. Their prices seem to be several times higher than yours. Can you double your prices? It seems really cheap. Too cheap?
Also, the location identified for me was off by 60 miles.
On your Documentation page you've used 8.8.8.8 as an example IP address. And 1.1.1.1, and 2.2.2.2... I'd rather see you use the IPv4 address blocks reserved for documentation by RFC 5737 [0]. That's what they're for! Unfortunately, they probably don't have any actual data associated with them so the examples would need to be fabricated...hmm.
And it looks like actually using one of those results in some output that does not conform to the format on your documentation page, so you'd best also add documentation about error handling.
[0]: https://tools.ietf.org/html/rfc5737