Best practices
This is the most important page of our documentation. It'll help you with error handling, network hiccups, maximum uptime, security compliance, SLAs, and provide a ton of the really good practices that'll make your integration with Smarty run predictably.
In addition to our Technical Requirements, this document describes some of the best practices you should follow when using any web service. Failure to do these things may result in connectivity issues and service interruptions, neither of which are covered under our service level agreement.
Contents
- Persist connections
- Asynchronous I/O
- Use HTTP pipelining
- Rate limiting
- Batch your input
- Anticipate timeouts
- Expect change - Plan for it
- Data exceptions
- Forward proxy
Persist connections
There is significant overhead in establishing a TCP connection between client and server. Even in a tight loop, most HTTP clients by default naively destroy and re-create the TCP link between requests. We recommend keeping the connection open by using HTTP keep-alive. Exactly how you do this depends on your client environment and implementation. This should decrease latency by using the same TCP connection and, more significantly, the same TLS handshake.
Asynchronous I/O
Asynchronous I/O means executing input/output operations without blocking your program's execution. See HTTP pipelining for a practical way of using asynchronous I/O in your application.
Use HTTP pipelining
Sending multiple requests while others are still in transit is known as HTTP pipelining. Rather than sending a request and waiting for its response before sending the next one, send a batch of requests in immediate sequence.
Some languages send requests synchronously by default, so it is in those environments that you should give pipelining special consideration. Other languages, such as Javascript, perform asynchronous network requests, so pipelining is baked in. How you implement pipelining depends on your platform and environment.
Rate limiting
Here at Smarty, we have two different kinds of rate limits: “security-based” and “plan-based.” It’s important to understand the circumstances that trigger both types of rate limits and how to handle them. Both rate limit types will result in a 429 (Too Many Requests) response code being returned from the API.
Security-based rate limits:
Security-based rate limits only affect calls being made using embedded keys. Embedded keys are typically used in environments that allow the credentials to be easily exposed, but they’re typically only used a limited number of times by a single user. Because of this, security-based rate limits are used to limit the number of requests that a single IP address over an embedded key can make. This limit can be circumvented for known and trusted IPs by adding those IPs as a host to the relevant embedded key in order to “whitelist” them. Security-based rate limits for that embedded key won’t throttle whitelisted IPs.
Because security-based rate limits are handled per IP address, public cloud provider IPs, such as those from a VPN, AWS, Azure, or another web hosting provider, are not permitted to make calls with embedded keys unless the IP is specifically whitelisted on the embedded key in question.
Plan-based rate limits:
Plan-based rate limits only affect calls that use a license with a rate limit. The rate limit for a license can be found by selecting the desired license on the Subscriptions tab of your Smarty Account. Plan-based rate limits are typically measured in lookups per second.
Rather than throttling single machines as they break the rate limit, plan-based rate limits throttle the entire license.
How to handle rate limits:
Whenever a rate limit is hit, the API in question will return a 429 HTTP status code, indicating that the IP or License in use is being throttled. Along with this status code, a Retry-After header will be returned, indicating the amount of time in seconds until the rate limit expires. We recommend using the Retry-After header to implement a “dynamic retry process.” Whenever a 429 status code is returned, we recommend capturing the Retry-After header and waiting for the indicated number of seconds before retrying the request or sending any other requests. This retry process will increase the efficiency of recovering from a rate limit and prevent further throttling.
If you’re regularly experiencing 429 status codes on a single IP address while using an embedded key, you may be hitting a security-based rate limit. If the IP in question is known and trusted, you may want to whitelist that IP address on the embedded key in use.
All that said, the easiest way to handle rate limits is to use one of our SDKs! They have dynamic retry processes built in to handle 429 status codes efficiently.
Frequently asked questions:
How many IPs can be whitelisted per embedded key?
Up to 100 hosts can be added to the whitelist on a single embedded key.
What is the security-based rate limit?
We don’t publish the exact specifications of the security-based rate limit, as doing so would compromise its effectiveness.
How do the rate limits work?
Our rate limits use a “Leaky Bucket” algorithm. Lookups fill a bucket, which is then emptied at a certain rate (this rate depends on the license). The bucket then cannot be filled until it is first emptied. Let's look at a 300 lookups/second rate as an example. If 1500 lookups are made in a single second on a license that has a 300 lookups/second rate limit, only 300 lookups will leak from the “bucket” within that first second. The bucket will require 4 more seconds to empty before it can be filled again. In this case, the API would return a Retry-After header of ‘4’ to indicate that the “bucket” will take that many seconds to empty. Once those 4 seconds have passed, the rate limit will expire, and calls can again be made to the API.
Batch your input
Whenever possible, combine multiple requests into a single request. Some Smarty API endpoints, in particular, allow you to send batch requests. For example, you can send many addresses in a single POST request to /street-address rather than having to send as many GET requests. Our city/state/ZIP endpoint has a similar feature. The exact number of items you send per batch may vary; you should experiment to find the sweet spot. It might be about 25 or 30 addresses, or maybe 100.
Anticipate timeouts
Think of a timeout as a phone call. What do you do when you make an important phone call, and no one answers? Do you give up, or do you call back a little later?
Timeouts can happen because of network issues, severed fiber optic cables, dropped packets, Mynocks chewing on the power cables, or any of a hundred uncontrollable reasons. Here is an example of the various steps required in a typical HTTPS request.
Let's face it: timeouts happen. Say it again with me, "timeouts happen." Good. Now you can plan how you want to handle them.
Expect change - Plan for it
Data exceptions
There will always be addresses that can't be found in Smarty data due to reasons such as new construction, poor source data, or unreported addresses. To provide the best service to your customers, you should have a mechanism in place to handle these exceptions. You can choose to establish an automated or manual process depending on your business requirements. This proactive approach will prevent delays and improve customer satisfaction.
Non-breaking changes
Well-designed code should anticipate changes. Smarty will, from time to time, make non-breaking changes to improve or enhance the service. These changes may introduce any of the following (this list isn't comprehensive): new features, new data points, new object keys or array elements, new headers, and new input parameters. We recommend you watch our official changelogs for all the details.
Remember, not all non-breaking changes introduce new features; they may also alter performance or response times. An important class of non-breaking changes is data updates. Updated data may change the exact result from a specific request. (For example, an address that's valid for one month may not be valid for the next. Such is the nature of the data.)
Whatever the non-breaking changes are, they're not expected to require customer action. Non-breaking changes occur on existing endpoints, and new versions are not introduced.
Smarty will make breaking changes from time to time. Because they alter the contract or may be expected to break client implementations, breaking changes are only introduced on newly provisioned endpoints. Usually this provisioning is accomplished through versioning.
Customers who wish to adopt new changes may point their code to use a new endpoint as it becomes available. If the service doesn't support versioning or multiple endpoints, we at Smarty will do our best to notify customers of impending breaking changes by email, social media, or other means, with sufficient time for customers to take action. Customers using un-versioned services are responsible for being notified by having valid, useful contact information on file.
Customers who do not meet the technical requirements or follow best practices may unexpectedly experience non-breaking changes in a breaking way. However, in these situations, the change is still considered non-breaking.
Services in beta are subject to breaking changes even if the endpoint is not (yet) versioned.