---
title: "System registry"
manual: "TYPO3 Explained"
version: "main"
permalink: "https://docs.typo3.org/permalink/t3coreapi:registry@main"
source: "ApiOverview/SystemRegistry/Index.rst"
rendered: "2026-09-21T11:24:09+00:00"
---

# System registry {#registry}

-   [Introduction](https://docs.typo3.org/permalink/t3coreapi:introduction@main)
-   [The registry API](https://docs.typo3.org/permalink/t3coreapi:the-registry-api@main)
-   [The registry table (sys_registry)](https://docs.typo3.org/permalink/t3coreapi:the-registry-table-sys-registry@main)

## Introduction {#registry-introduction}

The purpose of the registry is to store key-value pairs of information. It can
be considered an equivalent to the Windows registry (only not as complicated).

You might use the registry to hold information that your script needs
to store across sessions or requests.

An example would be a setting that needs to be altered by a PHP
script, which currently is not possible with [TypoScript](https://docs.typo3.org/m/typo3/reference-typoscript/main/en-us/Index.html#start).

Another example: The [Scheduler system extension](https://docs.typo3.org/c/typo3/cms-scheduler/main/en-us/Index.html#start)
stores when it ran the last time. The
[Reports system extension](https://docs.typo3.org/c/typo3/cms-reports/main/en-us/Index.html) then checks that value, in
case it determines that the Scheduler has not run for a while, it issues
a warning. While this might not be of much use to someone who has set up an
actual cron job for the Scheduler, but it is useful for users who
need to run the Scheduler tasks manually due to a lack of access to a
cron job.

The registry is not intended to store things that are supposed to go into
a [session](https://docs.typo3.org/permalink/t3coreapi:sessions@main) or a [cache](https://docs.typo3.org/permalink/t3coreapi:caching@main), use the appropriate
API for them instead.

## The registry API {#registry-api}

TYPO3 provides an API for using the registry. You can inject an instance of
the `Registry` class via [dependency injection](https://docs.typo3.org/permalink/t3coreapi:dependencyinjection@main).
The instance returned will always be the same, as the registry is a singleton:

**EXT:my_extension/Classes/MyClass.php**

```php
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension;

use TYPO3\CMS\Core\Registry;

final class MyClass
{
  public function __construct(
    private readonly Registry $registry,
  ) {}

  public function doSomething()
  {
    // Use $this->registry
  }
}

```

You can access registry values through its `get()` method. The `get()`
method provides a third parameter to specify a default value that is returned,
if the requested entry is not found in the registry. This happens, for example,
the first time an entry is accessed. A value can be set with the `set()`
method.

> [!NOTE]
> Do not store binary data in the registry, it is not intended for this
> purpose. Use the file system instead, if you have such needs.

### Example {#registry-examples}

The registry can be used, for example, to write run information of a
[console command](https://docs.typo3.org/permalink/t3coreapi:symfony-console-commands@main) into the registry:

**EXT:my_extension/Classes/Command/MyCommand.php**

```php
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use TYPO3\CMS\Core\Registry;

final class MyCommand extends Command
{
  private int $startTime;

  public function __construct(
    private readonly Registry $registry,
  ) {
    parent::__construct();
  }

  protected function execute(InputInterface $input, OutputInterface $output): int
  {
    $this->startTime = \time();

    // ... some logic

    $this->writeIntoRegistry();

    return Command::SUCCESS;
  }

  private function writeIntoRegistry(): void
  {
    $runInformation = [
      'startTime' => $this->startTime,
      'endTime' => time(),
    ];

    $this->registry->set('tx_myextension', 'lastRun', $runInformation);
  }
}

```

This information can be retrieved later using:

**EXT:my_extension/Classes/MyClass.php**

```php
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension;

use TYPO3\CMS\Core\Registry;

final class MyClass
{
  public function __construct(
    private readonly Registry $registry,
  ) {}

  // ... some method which calls retrieveFromRegistry()

  private function retrieveFromRegistry(): ?array
  {
    return $this->registry->get(
      'tx_myextension',
      'lastRun',
    );
  }
}

```

### API {#registry-api-api}

-   **class Registry**

    -   *Fully qualified name:* `\TYPO3\CMS\Core\Registry`

    A class to store and retrieve entries in a registry database table.

    This is a simple, persistent key-value-pair store.

    The intention is to have a place where we can store things (mainly settings)
    that should live for more than one request, longer than a session, and that
    shouldn't expire like it would with a cache. You can actually think of it
    being like the Windows Registry in some ways.

    -   **get(?string $namespace, ?string $key, ?mixed $defaultValue = NULL)**

        Returns a persistent entry.

        -   *param $namespace:* Extension key of extension
        -   *param $key:* Key of the entry to return.
        -   *param $defaultValue:* Optional default value to use if this entry has never been set. Defaults to NULL., default: NULL
        -   *Return description:* Value of the entry.

        *Returns:* `mixed`

    -   **set(?string $namespace, ?string $key, ?mixed $value)**

        Sets a persistent entry.

        This is the main method that can be used to store a key-value-pair.

        Do not store binary data into the registry, it's not build to do that,
        instead use the proper way to store binary data: The filesystem.

        -   *param $namespace:* Extension key of extension
        -   *param $key:* The key of the entry to set.
        -   *param $value:* The value to set. This can be any PHP data type; This class takes care of serialization

    -   **remove(?string $namespace, ?string $key)**

        Unset a persistent entry.

        -   *param $namespace:* Extension key of extension
        -   *param $key:* The key of the entry to unset.

    -   **removeAllByNamespace(?string $namespace)**

        Unset all persistent entries of given namespace.

        -   *param $namespace:* Extension key of extension

## The registry table (`sys_registry`) {#registry-table}

Following a description of the fields that can be found in the `sys_registry`
table:

-   **uid**

    -   *Type:* int

    Primary key, needed for replication and also useful as an index.

### entry_namespace {#sys-registry-entry-namespace}

-   **entry_namespace**

    -   *Type:* varchar(128)

    Represents an entry's namespace. In general, the namespace is an
    extension key starting with `tx_`, a user script's prefix `user_`,
    or `core` for entries that belong to the Core.

    The purpose of namespaces is that entries with the same key can exist
    within different namespaces.

### entry_key {#sys-registry-entry-key}

-   **entry_key**

    -   *Type:* varchar(128)

    The entry's key. Together with the namespace, the key is unique for the
    whole table. The key can be any string to identify the entry. It is
    recommended to use dots as dividers, if necessary. In this way, the
    naming is similar to the syntax already known in TypoScript.

### entry_value {#sys-registry-entry-value}

-   **entry_value**

    -   *Type:* mediumblob

    The entry's actual value. The value is stored as a serialized string,
    thus you can even store arrays or objects in a registry entry – it is
    not recommended though. The value in this field is stored as a binary.
