Creating and using Edge Dictionaries

  Last updated April 20, 2018

Edge Dictionaries allow you to create logic that doesn't need to be attached to a configuration service version. Edge Dictionaries are made up of dictionary containers and dictionary items. You can use dictionary items to create and store key-value pairs. Attaching dictionary containers to a service version allows you to turn frequently repeated statements into single function statements that act as a constant.

To create an Edge Dictionary and use it within your service you need to:

  1. Create an empty dictionary container in a working service on a version that's unlocked and not yet activated.
  2. Activate the new version of the service you associated with the empty dictionary container.
  3. Add dictionary items to the newly created dictionary container.

Once the dictionary container is created, properly associated, and filled with dictionary items, it can be called in your service.

For example, say you have a referer blacklist that changes frequently and you want to associate it with a service. Any time that service's configuration changes, especially if the configuration rolls back to a previous version, you would want the blacklisted referer domains to continue to remain with the service configuration instead of being removed. Edge Dictionaries would help you do this.

Create an empty dictionary container within a service

In order to use a dictionary container, start by creating an empty one within an unlocked version of a service.

Before an Edge Dictionary can be manipulated, its dictionary container must be associated with at least one service version that is not locked and not active so that the service becomes aware of the dictionary's existence.

For example, if you were creating a referer blacklist via the API, you would make an API call by running this command:

curl -X POST -H 'Fastly-Key: FASTLY_API_TOKEN' -d 'name=referer_blacklist' https://api.fastly.com/service/<service_id>/version/<version_number>/dictionary

which would return:

  "created_at": "2017-05-03T16:11:41+00:00",
  "deleted_at": null,
  "id": "<dictionary_id>",
  "name": "referer_blacklist",
  "service_id": "<service_id>",
  "updated_at": "2017-05-03T16:11:41+00:00",
  "version": <version_number>,
  "write_only": false

Activate the service associated with the dictionary container

In order for an Edge Dictionary to appear in generated VCL so it can be referred to later, the version associated with the dictionary container must be activated.

In our referer blacklist example, you would make this API call to activate service version associated with the empty dictionary container you created:

curl -X PUT -H 'Fastly-Key: FASTLY_API_TOKEN' https://api.fastly.com/service/<service_id>/version/<version_number>/activate

The response would be this:

  "number": <version_number>,
  "active": true,
  "service_id": "<service_id>"

Add dictionary items

Once the dictionary container becomes associated with the configuration of a service, you can begin populating it with dictionary items.

For example, you would use the following API call for each URL you want to add a URLs to your referer blacklist:

curl -X POST -H 'Fastly-Key: FASTLY_API_TOKEN' -d 'item_key=example-referer.org&item_value=true' "https://api.fastly.com/service/<service_id>/dictionary/<dictionary_id>/item"

The response for each URL added would look similar to this:

  "dictionary_id": "<dictionary_id>",
  "service_id": "<service_id>",
  "item_key": "example-referer.org",
  "item_value": "true"

Once the blacklisted URLs are added as items in your dictionary container, you can find them in your generated VCL by looking for a table similar to this:

table referer_blacklist {
  "example-referer.org": "true",
  "another-referer.net": "true",
  "sample-referer.com": "true",

Using a service to call Edge Dictionaries

When you create Edge Dictionaries via API calls, the dictionary contents aren't tied to any single version of your service.

The logic needed to interact with the table of information the Edge Dictionary creates, however, is always tied to a service version.

For example, adding a new referer to your blacklist requires that you specifically interact with the Edge Dictionary at some point after you create it. You could do this via API calls because its data would not require a service version activation. The dictionary was created via API calls not via custom VCL.

Specifically, you would set the host of the referer to a header by including custom VCL like this:

// versioned vcl
sub vcl_recv {

  # capture host of referer into a header
  set req.http.Referer-Host = regsub(req.http.Referer, "^https?://?([^:/\s]+).*$", "\1");

  # check if referrer host is in blacklisted table
  if (table.lookup(referer_blacklist, req.http.Referer-Host)) {
    # ResponseObject: forbidden-referrer
    error 900 "Fastly Internal";
  #end condition

sub vcl_error {

  if (obj.status == 900) {
    set obj.http.Content-Type = "";
    synthetic {""};

Custom VCL examples

These examples illustrate how to use Edge Dictionaries in custom VCL. The dictionaries are created via API calls and are displayed in the tables.

Referer blacklist

This example returns a 403 error message if the referer is in the dictionary.

// dictionary items can be added, updated, removed via the API
// does not require cloning and activating versions
table bad_guys {
  "example.com" : "nope",
  "fastly.com" : "nope",
// versioned vcl
sub vcl_recv {
  set req.http.Referer-Host = regsub(req.http.Referer, "https?://([^/]+)/.*", "\1");
  set req.http.Referer-Check = table.lookup(bad_guys, req.http.Referer-Host, "yes");
  if (req.http.Referer-Check == "nope") {
    error 403;

CORS origin database

This example adds the origins in the dictionary to the Access-Control-Allow-Origin header.

// dictionary items can be added, updated, removed via the API
// does not require cloning and activating versions
table acceptable_origins {
  "http://example.com" : "yes",
  "http://fastly.com" : "yes",
// versioned vcl
sub vcl_deliver {
  set req.http.CORS = table.lookup(acceptable_origins, req.http.Origin, "nope");
  if (req.http.CORS == "yes") {
    set resp.http.Access-Control-Allow-Origin = req.http.Origin;

TTL database

This example sets the TTLs for the URLs in the dictionary.

// dictionary items can be added, updated, removed via the API
// does not require cloning and activating versions
table ttls {
  "/" : "60",
  "/public" : "86400",
  "/api" : "3600",
  "/foo" : "7200",
  "/user" : "5"
// versioned vcl
sub vcl_fetch {
  /* cut URL down to first directory, or just / */
  if (req.url.path ~ "^(/[^/\?]*)") {
    /* should always be true */
    set beresp.ttl = std.atoi(table.lookup(ttls, re.group.1, "30"));

Additional resources:

Back to Top