Basics

The Cache API is used to store data that takes a long time to compute.
Caching can either be permanent or valid only for a certain timespan, and
the cache can contain any type of data.

To use the Cache API:

Request a cache object through \Drupal::cache() or by injecting a cache
service.

Define a Cache ID (cid) value for your data. A cid is a string, which must
contain enough information to uniquely identify the data. For example, if
your data contains translated strings, then your cid value must include the
interface text language selected for page.

Call the get() method to attempt a cache read, to see if the cache already
contains your data.

If your data is not already in the cache, compute it and add it to the
cache using the set() method. The third argument of set() can be used to
control the lifetime of your cache item.

Note the use of $data and $cache->data in the above example. Calls to
\Drupal::cache()->get() return a record that contains the information stored
by \Drupal::cache()->set() in the data property as well as additional meta
information about the cached data. In order to make use of the cached data
you can access it via $cache->data.

Cache bins

Cache storage is separated into "bins", each containing various cache items.
Each bin can be configured separately; see Configuration.

When you request a cache object, you can specify the bin name in your call to
\Drupal::cache(). Alternatively, you can request a bin by getting service
"cache.nameofbin" from the container. The default bin is called "default", with
service name "cache.default", it is used to store common and frequently used
caches.

Other common cache bins are the following:

bootstrap: Small caches needed for the bootstrap on every request.

render: Contains cached HTML strings like cached pages and blocks, can
grow to large size.

data: Contains data that can vary by path or similar context.

discovery: Contains cached discovery data for things such as plugins,
views_data, or YAML discovered data such as library info.

A module can define a cache bin by defining a service in its
modulename.services.yml file as follows (substituting the desired name for
"nameofbin"):

Deletion

There are two ways to remove an item from the cache:

Deletion (using delete(), deleteMultiple() or deleteAll()) permanently
removes the item from the cache.

Invalidation (using invalidate(), invalidateMultiple() or invalidateAll())
is a "soft" delete that only marks items as "invalid", meaning "not fresh"
or "not fresh enough". Invalid items are not usually returned from the
cache, so in most ways they behave as if they have been deleted. However,
it is possible to retrieve invalid items, if they have not yet been
permanently removed by the garbage collector, by passing TRUE as the second
argument for get($cid, $allow_invalid).

Use deletion if a cache item is no longer useful; for instance, if the item
contains references to data that has been deleted. Use invalidation if the
cached item may still be useful to some callers until it has been updated
with fresh data. The fact that it was fresh a short while ago may often be
sufficient.

Invalidation is particularly useful to protect against stampedes. Rather than
having multiple concurrent requests updating the same cache item when it
expires or is deleted, there can be one request updating the cache, while the
other requests can proceed using the stale value. As soon as the cache item
has been updated, all future requests will use the updated value.

Cache Tags

The fourth argument of the set() method can be used to specify cache tags,
which are used to identify which data is included in each cache item. A cache
item can have multiple cache tags (an array of cache tags), and each cache
tag is a string. The convention is to generate cache tags of the form
[prefix]:[suffix]. Usually, you'll want to associate the cache tags of
entities, or entity listings. You won't have to manually construct cache tags
for them — just get their cache tags via
\Drupal\Core\Cache\CacheableDependencyInterface::getCacheTags() and
\Drupal\Core\Entity\EntityTypeInterface::getListCacheTags().
Data that has been tagged can be invalidated as a group: no matter the Cache
ID (cid) of the cache item, no matter in which cache bin a cache item lives;
as long as it is tagged with a certain cache tag, it will be invalidated.

Because of that, cache tags are a solution to the cache invalidation problem:

For caching to be effective, each cache item must only be invalidated when
absolutely necessary. (i.e. maximizing the cache hit ratio.)

For caching to be correct, each cache item that depends on a certain thing
must be invalidated whenever that certain thing is modified.

A typical scenario: a user has modified a node that appears in two views,
three blocks and on twelve pages. Without cache tags, we couldn't possibly
know which cache items to invalidate, so we'd have to invalidate everything:
we had to sacrifice effectiveness to achieve correctness. With cache tags, we
can have both.

Drupal is a content management system, so naturally you want changes to your
content to be reflected everywhere, immediately. That's why we made sure that
every entity type in Drupal 8 automatically has support for cache tags: when
you save an entity, you can be sure that the cache items that have the
corresponding cache tags will be invalidated.
This also is the case when you define your own entity types: you'll get the
exact same cache tag invalidation as any of the built-in entity types, with
the ability to override any of the default behavior if needed.
See \Drupal\Core\Cache\CacheableDepenencyInterface::getCacheTags(),
\Drupal\Core\Entity\EntityTypeInterface::getListCacheTags(),
\Drupal\Core\Entity\Entity::invalidateTagsOnSave() and
\Drupal\Core\Entity\Entity::invalidateTagsOnDelete().

Cache contexts

Some computed data depends on contextual data, such as the user roles of the
logged-in user who is viewing a page, the language the page is being rendered
in, the theme being used, etc. When caching the output of such a calculation,
you must cache each variation separately, along with information about which
variation of the contextual data was used in the calculatation. The next time
the computed data is needed, if the context matches that for an existing
cached data set, the cached data can be reused; if no context matches, a new
data set can be calculated and cached for later use.

Typically, the cache context is specified as part of the #cache property
of a render array; see the Caching section of the
Render API overview topic for details.

Configuration

By default cached data is stored in the database. This can be configured
though so that all cached data, or that of an individual cache bin, uses a
different cache backend, such as APCu or Memcache, for storage.

In a settings.php file, you can override the service used for a particular
cache bin. For example, if your service implementation of
\Drupal\Core\Cache\CacheBackendInterface was called cache.custom, the
following line would make Drupal use it for the 'cache_render' bin: