Skip to content

CDNetworks Documentation

Frequently Asked Questions permalink

How is the cache time for an object determined? permalink

There are many directives you can use in the Edge Logic to control the cache time. If none of them is configured, the default behavior of CDN Pro edge servers is to "honor the origin". That is, the instructions in the Cache-Control and Expires header fields are followed. If these two fields are not present in a response from the origin, the response is not cached. The presence of the Set-Cookie header field also prevents caching of the response.

We modified the open-source NGINX to strictly follow the HTTP standard regarding 'zero-time cache'. When no-cache or max-age=0 is present in the Cache-Control header field, the response is still cached but expires immediately. Any subsequent request for this object will result in a revalidation request to the origin with the If-Modified-Since header. If no-store is in the Cache-Control header field, the response will not be cached.

By default, the Date header field is passed all the way from the origin to the edge servers. Efforts have also been made to ensure the Age header field reflects the time since the response is retrieved from the origin, even when parent cache is used.

If the default behavior mentioned above does not meet your requirement, use the following directives to alter it.

  • To ignore one or more of the three special header fields above, you can use the proxy_ignore_headers directive. For example:
proxy_ignore_headers Set-Cookie;

In this case, the servers will behave as if the Set-Cookie header does not exist.

  • proxy_cache_valid can be used to set a cache time if the three special header fields are not present or ignored. You can use it multiple times to set different cache times for different status codes. For example:
location / { # the default location
    proxy_cache_valid 5m; # cache 200, 301 and 302 for 5 minutes
    proxy_cache_valid 404 2m; # cache 404 for 2 minutes
}
location /no-cache {
    proxy_cache_valid 200 0; # cache 200 response, but revalidate every time.
}
proxy_ignore_cache_control no-cache no-store;
  • The CDN Pro proprietary directive proxy_cache_min_age can be used to override the max-age in the Cache-Control header field to enforce a minimum cache time.
  • If you don't want a request to be served from the cache, you can use the proxy_cache_bypass directive. proxy_no_cache can be used to prevent a response from being cached.

Since you are interested in the caching behavior of CDN Pro, you may want to also learn how to customized the cache key and how the Vary header is treated.

How do I include query parameters, request headers and body in the cache key? permalink

By default, the CDN Pro cache key includes only the hostname and URI without the query string. It also includes a special variable that is accessible in the Edge Logic: $cache_misc. Therefore, if you want to add anything to the cache key, add it to this variable. For example, to keep the entire query string in the cache key:

set $cache_misc "?$sorted_querystring_args";

If you want to include only some of the query parameters, the following example shows how to add parameters "abc" and "def" to the cache key:

set $cache_misc "?abc=$arg_abc&def=$arg_def";

Similarly, the following example shows how to include some request headers in cache key:

set $cache_misc "ae=$http_accept_encoding";
set $cache_misc $cache_misc."hdr1=$http_header1&hdr2=$http_header2";

If you want to keep any previously assigned value, you can append to this variable:

set $cache_misc "${cache_misc}hdr1=$http_header1&hdr2=$http_header2";

The POST method is often used today to query information with complex or long parameters. A prominent example is the GraphQL. In these cases, the POST requests are idempotent and safe as the GET requests, and the response are well cacheable. The only question is how to include the parameters in the request body to the cache key. CDN Pro created the proprietary directive proxy_request_body_in_cache_key for this exact purpose. When this feature is turned on, our server would calculate an MD5 hash from the request body and append it to the cache key. Due to performance considerations, this only happens when the body size is less than 4kB, otherwise the cache key is not appended and the variable $ignored_body_in_cache_key is set to 1 to indicate this fact. You can use this variable with proxy_cache_bypass to avoid serving incorrect cached content. If you really need to include larger request body in the cache key, you are advised to calculate a hash of the request body in the client and pass it through the request header. You can then use the method introduced earlier to include it in the cache key via $cache_misc.

Last but not least, don't forget to use the proxy_cache_methods directive to enable the caching of POST requests.

HTTP Header Manipulation permalink

If you need to add, modify, or delete some header fields in the request to the origin, use the origin_set_header directive. For example:

origin_set_header CDN-Name Quantil;

In particular, this is the code to send the client's IP address to the origin server:

origin_set_header Client-IP $client_real_ip;

In order to consolidate the responses from the origin to improve the cache hit ratio, we created a dedicated directive sanitize_accept_encoding to modify the accept-encoding request header received from the client.

If you need to add, modify, or delete some header fields in the response to clients, use the add_header directive. For example:

add_header CDN-Name Quantil;

We also created a proprietary directive origin_header_modify to manipulate the response header from the origin prior to processing the response. This can be very useful if you need to override a header value (such as cache time) from the origin that may affect the CDN servers' behavior.

The support (and non-support) of Vary permalink

By default, CDN Pro servers remove any Vary header in the response from origin servers. Therefore, every URL will have no more than one cached version. If you want to cache different versions based on a request header or cookie values, put them explicitly into the cache key by setting the $cache_misc variable mentioned above. For example:

set $cache_misc "ae=$http_accept_encoding";

If you want to send a Vary header to the clients to make sure they cache different variations properly, use the add_header directive. If you have to pass the Vary header from the origin to the client, use the following configuration to "undo" the default removal of the header:

# preserve the Vary header from origin
origin_header_modify Vary "" policy=preserve;
# ignore the Vary header, just pass it to the client
proxy_ignore_headers Vary; 

In this case, the servers cache the content as if the Vary header does not exist. Without proxy_ignore_headers Vary, the preserved Vary header would prevent the response from being cached because proxy_cache_vary off is configured by default. If it is absolutely important for the CDN Pro servers to cache multiple versions based on the Vary header, contact CDNetworks customer support to obtain permission to set proxy_cache_vary on.

How to follow redirections from origin? permalink

When the origin responds with a 30x redirect, you may want the CDN servers to chase it until the redirection stops. Passing the redirection to the client takes more time to get the final content. If you want to turn on this feature, use the directive origin_follow_redirect in the location where it is needed.

China Delivery and Beian permalink

The Chinese Ministry of Industry and Information Technology (MIIT) requires every domain served from a server in Mainland China to have a record in its system. This is called ICP Beian (备案). For certain domains, a Security Beian is also required. As a CDN provider, CDNetworks cannot use our servers in China to serve domains without ICP Beian. Any violation may result in our China-based servers being blocked. Customers are responsible for filing and obtaining Beian for any domain that needs local delivery in China. We can provide consulting services to assist with this process. For domains without Beian, CDNetworks can use servers located in close proximity to Mainland China (for example, Hong Kong, Korea, and Japan) to deliver content to clients in Mainland China; however, the performance will not be as good as local delivery.

If you have one or more domains with ICP Beian and want them to be accelerated in China, contact customer service to ensure we have all the required information on file about your business. After confirming that we have the necessary information, your China Delivery service will be enabled. You can then perform the following steps to enable local delivery of domains in Mainland China:

  1. Set "hasBeian" to true in the property of this domain. This ensures the configuration will be deployed to servers in China and that those servers will handle client requests to this domain. Otherwise, they will return status code 451.

  2. Create an Edge Hostname with "hasBeian" set to true, and use this edge hostname for the domain to be accelerated. This ensures that GSLB will direct traffic of this domain to our servers in Mainland China.

How to support WebSocket? permalink

Use the directive enable_websocket in the location where the WebSocket protocol is needed. Make sure the client uses HTTP/1.1 (not HTTP/2) to connect. This directive also sets the read and send timeouts to 21s by default. They can be changed using the origin_read_timeout or origin_send_timeout directives.

What about dynamic content? permalink

Dynamic contents are usually generated on-the-fly for each request and are different for different visitors. Some examples are:

  • Realtime stock prices, sports game scores
  • Search results based on keywords entered by the visitor
  • API calls that have lots of query parameters

If you only have the origin server in a central data center or in the cloud, the performance can be quite poor if the visitor is far away from or does not have a good connection to the data center. How can we accelerate those contents through CDN Pro? Here are a few things you can do:

  • Simply using CDN Pro can shave off a few seconds

If you use CDN Pro, your clients will connect to the PoP that is closest to them. The round trip time (RTT) can be a few hundred milliseconds faster than directly connecting to the origin server. The TCP and TLS handshakes usually take 3-4 RTTs which can be a second faster through the CDN. By default, the CDN Pro servers maintain persistent connections to the origin. You can increase the keep-alive timeout to up to 10 minutes in the origin configurations. In the meantime, if you know the content is not cacheable at all, use proxy_no_cache 1; and proxy_cache_bypass 1; to completely skip caching to minimize latency.

  • Cache the response!

In many cases, "dynamic" does not mean the content is not cacheable. For example, end users will not experiance the difference if you cache the score of a basketball game for 1 second. If you have 10 requests per second to fetch the score, you can save 90% of the bandwidth and processing power. If the response depends on some query parameter or request header values, make sure those variables are included in the cache key.

  • Enable Fast Route to origin

CDN Pro has a directive origin_fast_route that enables a "Fast Route" to access the origin. This powerful feature is based on our award-winning High-speed Data Transmission (HDT) technology. It ensures that our servers always have the best possible channel to reach your origin, even under challenging situations. This directive can also be used for highly cacheable contents if the origin is hard to reach from certain networks or when the cache-miss performance is critical to you. However, the traffic served through the ""Fast Route" may be charged a higher price due to the extra cost associated with it. To try out this feature, contact the CDN Pro support team.

How are CDN Pro API calls rate limited? permalink

To prevent CDN Pro's API servers from being overwhelmed, the CDN Pro API enforces a limit on the number of requests that customers can send per minute. If a customer sends too many requests, API rate limiting throttles the customer by returning error messages with HTTP status code 429.

Token Bucket Algorithm

CDN Pro uses the token bucket algorithm to enforce rate limiting. The token bucket algorithm is based on an analogy of a fixed capacity bucket into which tokens are added at a fixed rate. Before allowing an API request to proceed, the bucket is inspected to see whether it contains at least one token. If it does, one token is removed from the bucket and the API request is allowed to proceed. If there is not a sufficient number of tokens available, the request is blocked, with an error that says the quota has been exceeded during the 1-minute sliding window.

The capacity of the bucket and the filling rate are controlled by the configs.apiMaxBurst and configs.apiRate fields in the customer management API. For example, if the customer has configs.apiMaxBurst = 45 and configs.apiRate = 120, tokens are added to the bucket at a fixed rate of 120 tokens per minute, and the total capacity of the bucket is 45. The bucket is refilled in a “greedy” manner. CDN Pro tries to add tokens to the bucket as soon as possible. For example, refilling at "120 tokens per minute" adds 1 token every 500 milliseconds. In other words, the refill does not wait a full minute to regenerate a bunch of 120 tokens.

Indicator and Error Handling

After the token gets consumed, an x-rate-limit-remaining: X header is added to the API call’s HTTP response, indicating the number of tokens remaining in the bucket. This header represents the remaining quota of API requests a customer can make at this time. Failed or malformed requests consume one token from the bucket as well. If there is not a sufficient number of tokens in the bucket, the API gateway returns an HTTP 429 error with response header x-rate-limit-retry-after-seconds: Y to tell the client to retry after Y seconds.

Best Practices for Avoiding Rate Limiting Errors

  1. Check the API request history. “GET /ngadmin/apicalls” shows the API calls you have made. (The customer admin API credential is required to call this API.) Carefully check the records for potential abuses.

  2. Reduce the number of requests by using APIs that are more suitable for the scenario or by combining similar requests into one. For example, if you want to monitor the traffic volume of a list of domains, an ineffective approach is:

    for domain in domain_list:
        call GET /cdn/report/vol 
             {filters: {hostnames: [$domain]}}

Instead, use the following recommended approach:

    POST /cdn/report/volSummary 
         {filters: {hostnames: [$domain_list]}, groupBy: [hostnames]}

Another example is purging multiple files in one request instead of making an API call for each purge URL. If there are thousands of purge URLs that follow a certain pattern, use directory or regex purge by specifying the dirUrls or regexPatterns fields when creating a purge request. The number of requests should not scale as you acquire more domains, properties, and other resources.

  1. If you call the API through scripts, it should be resilient to intermittent or non-specific errors. The script should honor the x-rate-limit-retry-after-seconds header and retry the request after a delay. Consider including a process in your code that regulates the rate of your requests so that they are distributed evenly over time.

  2. If a problem persists, contact our technical support team. If there is a legitimate need to increase the rate limit or burst ceiling, the technical support team will evaluate your requirements and raise the threshold.

Notes

  1. Rate limiting applies at the customer level. All API accounts under the same customer share the same token bucket. Excessive use of one account exhausts the customer’s quota. The rate limits of a reseller's children are independent of each other. In addition, the children’s API calls will not use the parent’s quota.

  2. Because the CDN Pro portal calls the APIs, operations in the portal UI also consume the API rate limit tokens.

  3. Unauthorized API calls such as signups and login attempts consume tokens from the bucket corresponding to the client’s IP address. This bucket has a default capacity of 30 tokens and a refill rate of 60 per minute.

  4. Modifications to the configs.apiRate and configs.apiMaxBurst using the customer management API do not take effect immediately. It typically takes 10-15 minutes to change the refill rate and refill the bucket.