diff --git a/src/Command/AuditLogDeleteOldLogsCommand.php b/src/Command/AuditLogDeleteOldLogsCommand.php
new file mode 100644
index 0000000..c5798ef
--- /dev/null
+++ b/src/Command/AuditLogDeleteOldLogsCommand.php
@@ -0,0 +1,101 @@
+<?php
+
+declare(strict_types=1);
+
+namespace DataDog\AuditBundle\Command;
+
+use Doctrine\DBAL\Connection;
+use Doctrine\DBAL\ParameterType;
+use Symfony\Component\Console\Attribute\AsCommand;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+#[AsCommand(
+    name: 'audit-logs:delete-old-logs',
+    description: 'Remove old records from the audit logs',
+)]
+class AuditLogDeleteOldLogsCommand extends Command
+{
+    public const DEFAULT_RETENTION_PERIOD = 'P3M';
+
+    public function __construct(
+        protected Connection $connection
+    ) {
+        parent::__construct();
+    }
+
+    #[\Override]
+    protected function execute(InputInterface $input, OutputInterface $output): int
+    {
+        $date = (new \DateTime())->sub(new \DateInterval(self::DEFAULT_RETENTION_PERIOD));
+        $formattedDate = $date->format('Y-m-d H:i:s');
+
+        $output->writeln(sprintf('<info>Delete all records before %s</info>', $formattedDate));
+
+        $result = $this->connection->executeQuery(
+            'SELECT * FROM audit_logs WHERE logged_at < ? ORDER BY logged_at DESC LIMIT 1',
+            [$formattedDate]
+        )
+            ->fetchAssociative();
+
+        if ($result === false) {
+            $output->writeln(sprintf('<info>No records to delete</info>'));
+
+            return 0;
+        }
+
+        $auditLogStartRecordId = $result['id'];
+        $auditAssociativeStartRecordId = max($result['source_id'], $result['target_id'], $result['blame_id']);
+
+        $count = $this->deleteFromAuditLogs($auditLogStartRecordId);
+        $output->writeln(sprintf('<info> %s records from audit_logs deleted!</info>', $count));
+
+        $count = $this->deleteFromAuditAssociations($auditAssociativeStartRecordId);
+        $output->writeln(sprintf('<info> %s records from audit_associations deleted!</info>', $count));
+
+        return 0;
+    }
+
+    private function deleteFromAuditLogs(int $startRecordId): int
+    {
+        $allRecords = 0;
+        $this->connection->executeQuery('SET FOREIGN_KEY_CHECKS=0');
+
+        $sql = 'DELETE LOW_PRIORITY FROM audit_logs WHERE id <= ? ORDER BY id LIMIT 10000';
+        $stmt = $this->connection->prepare($sql);
+        $stmt->bindValue(1, $startRecordId, ParameterType::INTEGER);
+        do {
+            $startTime = microtime(true);
+            $deletedRows = $stmt->executeStatement();
+            $allRecords += $deletedRows;
+            echo round((microtime(true) - $startTime), 3) . "s ";
+            sleep(1);
+        } while ($deletedRows > 0);
+
+        $this->connection->executeQuery('SET FOREIGN_KEY_CHECKS=1');
+
+        return $allRecords;
+    }
+
+    private function deleteFromAuditAssociations(int $startRecordId): int
+    {
+        $allRecords = 0;
+        $this->connection->executeQuery('SET FOREIGN_KEY_CHECKS=0');
+
+        $sql = 'DELETE LOW_PRIORITY FROM mscm.audit_associations WHERE id <= ? ORDER BY id LIMIT 10000';
+        $stmt = $this->connection->prepare($sql);
+        $stmt->bindValue(1, $startRecordId, ParameterType::INTEGER);
+        do {
+            $startTime = microtime(true);
+            $deletedRows = $stmt->executeStatement();
+            $allRecords += $deletedRows;
+            echo round((microtime(true) - $startTime), 3) . "s ";
+            sleep(1);
+        } while ($deletedRows > 0);
+
+        $this->connection->executeQuery('SET FOREIGN_KEY_CHECKS=1');
+
+        return $allRecords;
+    }
+}
diff --git a/src/DependencyInjection/DataDogAuditExtension.php b/src/DependencyInjection/DataDogAuditExtension.php
index 48cdd1e..7a47a68 100644
--- a/src/DependencyInjection/DataDogAuditExtension.php
+++ b/src/DependencyInjection/DataDogAuditExtension.php
@@ -2,6 +2,7 @@
 
 namespace DataDog\AuditBundle\DependencyInjection;
 
+use DataDog\AuditBundle\EventListener\AuditListener;
 use Symfony\Component\Config\FileLocator;
 use Symfony\Component\DependencyInjection\ContainerBuilder;
 use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
@@ -17,7 +18,7 @@ public function load(array $configs, ContainerBuilder $container): void
         $configuration = new Configuration();
         $config = $this->processConfiguration($configuration, $configs);
 
-        $auditListener = $container->getDefinition('datadog.event_listener.audit');
+        $auditListener = $container->getDefinition(AuditListener::class);
 
         if (isset($config['audited_entities']) && !empty($config['audited_entities'])) {
             $auditListener->addMethodCall('addAuditedEntities', array($config['audited_entities']));
diff --git a/src/EventListener/AuditListener.php b/src/EventListener/AuditListener.php
index 571e08b..5b3627d 100644
--- a/src/EventListener/AuditListener.php
+++ b/src/EventListener/AuditListener.php
@@ -5,6 +5,7 @@
 use DataDog\AuditBundle\DBAL\AuditLogger;
 use DataDog\AuditBundle\Entity\Association;
 use DataDog\AuditBundle\Entity\AuditLog;
+use Doctrine\Bundle\DoctrineBundle\Attribute\AsDoctrineListener;
 use Doctrine\DBAL\Logging\LoggerChain;
 use Doctrine\DBAL\Logging\SQLLogger;
 use Doctrine\DBAL\Types\Type;
@@ -13,11 +14,14 @@
 use Doctrine\ORM\Event\OnFlushEventArgs;
 use Doctrine\ORM\Events;
 use Doctrine\ORM\Mapping\ClassMetadataInfo;
+use Symfony\Component\DependencyInjection\Attribute\AsAlias;
 use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
 use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
 use Symfony\Component\Security\Core\Role\SwitchUserRole;
 use Symfony\Component\Security\Core\User\UserInterface;
 
+#[AsDoctrineListener(Events::onFlush)]
+#[AsAlias(id: 'datadog.event_listener.audit', public: false)]
 class AuditListener
 {
     /**
diff --git a/src/Resources/config/services.php b/src/Resources/config/services.php
index caea8b2..a9a6075 100644
--- a/src/Resources/config/services.php
+++ b/src/Resources/config/services.php
@@ -7,13 +7,26 @@
 use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
 
 return static function (ContainerConfigurator $container) {
-    // @formatter:off
-    $services = $container->services();
-    $services
-        ->set('datadog.event_listener.audit', AuditListener::class)->private()
-        ->arg(0, new Reference(TokenStorageInterface::class))
-        //->tag('doctrine.event_subscriber')
-        ->tag('doctrine.event_listener', ['event' => 'onFlush',])
+    // default configuration for services in *this* file
+    $services = $container->services()
+        ->defaults()
+        ->autowire()      // Automatically injects dependencies in your services.
+        ->autoconfigure() // Automatically registers your services as commands, event subscribers, etc.
     ;
-    // @formatter:on
+
+    // makes classes in src/ available to be used as services
+    // this creates a service per class whose id is the fully-qualified class name
+    $services->load('DataDog\\AuditBundle\\', '../../../src/')
+        ->exclude('../../../src/{DependencyInjection,Entity,Resources,DataDogAuditBundle.php}');
+
+
+//    // @formatter:off
+//    $services = $container->services();
+//    $services
+//        ->set('datadog.event_listener.audit', AuditListener::class)->private()
+//        ->arg(0, new Reference(TokenStorageInterface::class))
+//        //->tag('doctrine.event_subscriber')
+//        ->tag('doctrine.event_listener', ['event' => 'onFlush',])
+//    ;
+//    // @formatter:on
 };