diff --git a/lib/Zonemaster/Backend/DB.pm b/lib/Zonemaster/Backend/DB.pm
index 119ee1823f1a482d1d438f290a2cb8e8372bdcd2..969e28e1be863aa56ead3b7d5b7fc211e125f468 100644
--- a/lib/Zonemaster/Backend/DB.pm
+++ b/lib/Zonemaster/Backend/DB.pm
@@ -857,6 +857,34 @@ sub add_result_entries {
     $sth = $sth->execute(map { @$_ } @records);
 }
 
+sub add_result_entries_multiple {
+    my ( $self, %test_results ) = @_;
+    my @records;
+
+    my $json = JSON::PP->new->allow_blessed->convert_blessed->canonical;
+
+    foreach my $hash_id (keys %test_results ) {
+        foreach my $m ( @{$test_results{$hash_id}} ) {
+            my $r = [
+                $hash_id,
+                $m->level,
+                $m->module,
+                $m->testcase,
+                $m->tag,
+                $m->timestamp,
+                $json->encode( $m->args // {} ),
+            ];
+
+            push @records, $r;
+        }
+    }
+
+    my $query_values = join ", ", ("(?, ?, ?, ?, ?, ?, ?)") x @records;
+    my $query = "INSERT INTO result_entries (hash_id, level, module, testcase, tag, timestamp, args) VALUES $query_values";
+    my $sth = $self->dbh->prepare($query);
+    $sth = $sth->execute(map { @$_ } @records);
+}
+
 no Moose::Role;
 
 1;
diff --git a/lib/Zonemaster/Backend/RedisQueue.pm b/lib/Zonemaster/Backend/RedisQueue.pm
index 6a1edfc87e51ab93a8e4151b4258e304472b0ccd..7c6b4ea24bd174685cbb2388d442554bf71607b1 100644
--- a/lib/Zonemaster/Backend/RedisQueue.pm
+++ b/lib/Zonemaster/Backend/RedisQueue.pm
@@ -21,6 +21,16 @@ has 'db' => (
     required => 1,
 );
 
+=comment
+
+Schema:
+* zm-test-requests -> list of test ids, list of ids of to tests that need to be run
+* zm-test-processing -> list of test ids, list of ids of tests that are currently running
+* zm-test-lock:$test_id -> value, arbitrary value that expired after $test_timeout, used to track test that have timed out.
+* zm-test-params -> hash { test id => json encoded params }
+* zm-test-results -> hash { test id => json encoded result entries}
+=cut
+
 sub from_config {
     my ( $class, $config ) = @_;
 
@@ -66,6 +76,38 @@ sub expired_tests {
     return @tests;
 }
 
+sub add_result_entries {
+    my ( $self, $hash_id, $entries ) = @_;
+    my $json = JSON::PP->new->allow_blessed->convert_blessed;
+
+    my @out;
+    foreach my $m ( @{$entries} ) {
+        my %r;
+        $r{timestamp} = $m->timestamp;
+        $r{module}    = $m->module;
+        $r{testcase}  = $m->testcase;
+        $r{tag}       = $m->tag;
+        $r{level}     = $m->level;
+        $r{args}      = $m->args if $m->args;
+
+        push @out, \%r;
+    }
+
+    $self->redis->hset("zm-test-results", $hash_id, $json->encode(\@out));
+}
+
+sub get_test_results {
+    my ( $self ) = @_;
+
+    $self->redis->hgetall( "zm-test-results" );
+}
+
+sub remove_results {
+    my ( $self, $hash_id ) = @_;
+
+    $self->redis->hdel( "zm-test-results", $hash_id );
+}
+
 sub queue_batch_job {
     my ( $self, $batch_id ) = @_;
     my $query = q[
diff --git a/lib/Zonemaster/Backend/TestAgent.pm b/lib/Zonemaster/Backend/TestAgent.pm
index 45fefd1d1595e0a6cf9d6fe7c4cf3ac631b7ff10..1901fd92cb55e13ff910239afc46fe8409089965 100644
--- a/lib/Zonemaster/Backend/TestAgent.pm
+++ b/lib/Zonemaster/Backend/TestAgent.pm
@@ -54,11 +54,11 @@ sub new {
 }
 
 sub run {
-    my ( $self, $params, $show_progress ) = @_;
+    my ( $self, $queue, $test_id, $show_progress ) = @_;
 
     my @accumulator;
 
-    my $test_id = $params->{hash_id};
+    my $params = $queue->get_test_params( $test_id );
 
     my ( $domain ) = $params->{domain};
     if ( !$domain ) {
@@ -158,14 +158,16 @@ sub run {
     my @entries = grep { $_->numeric_level >= $numeric{INFO} } @{ Zonemaster::Engine->logger->entries };
     Zonemaster::Backend::Metrics::timing("zonemaster.testagent.log_callback_add_result_entry_grep_duration",  tv_interval($start_time_2) * 1000);
 
-    $self->{_db}->add_result_entries( $test_id, \@entries);
+    #$self->{_db}->add_result_entries( $test_id, \@entries);
+    $queue->add_result_entries( $test_id, \@entries );
 
     my $callback_add_result_entry_duration = tv_interval($start_time_2);
     Zonemaster::Backend::Metrics::timing("zonemaster.testagent.log_callback_add_result_entry_duration", $callback_add_result_entry_duration * 1000);
 
     #$log->debug("Callback timing for $test_id: $callback_duration / $callback_add_result_entry_duration ");
 
-    $self->{_db}->test_progress( $test_id, 100 );
+    #$self->{_db}->test_progress( $test_id, 100 );
+    $queue->test_finished( $test_id );
 
     return;
 } ## end sub run
diff --git a/script/zonemaster_backend_results_inserter b/script/zonemaster_backend_results_inserter
new file mode 100644
index 0000000000000000000000000000000000000000..01e04ce4da67b5833ac2e17de2a2d67a1f4a9453
--- /dev/null
+++ b/script/zonemaster_backend_results_inserter
@@ -0,0 +1,71 @@
+#!/usr/bin/env perl
+
+use 5.14.2;
+use warnings;
+
+use Zonemaster::Backend::DB;
+use Zonemaster::Backend::Config;
+use Zonemaster::Backend::Metrics;
+use Zonemaster::Backend::RedisQueue;
+
+use Log::Any qw( $log );
+use Log::Any::Adapter;
+use JSON::PP;
+use Time::HiRes qw[time sleep gettimeofday tv_interval];
+
+
+Log::Any::Adapter->set(
+    '+Zonemaster::Backend::Log',
+    log_level => $ENV{ZM_BACKEND_INSERTER_LOGLEVEL} // "info",
+    json => $ENV{ZM_BACKEND_INSERTER_LOGJSON},
+    stderr => 1
+);
+
+$SIG{__WARN__} = sub {
+    $log->warning(map s/^\s+|\s+$//gr, map s/\n/ /gr, @_);
+};
+
+
+sub main {
+    my $config = Zonemaster::Backend::Config->load_config();
+    my $dbtype = $config->DB_engine;
+    my $dbclass = Zonemaster::Backend::DB->get_db_class( $dbtype );
+    my $db = $dbclass->from_config( $config );
+    Zonemaster::Backend::Metrics->setup($config->METRICS_statsd_host, $config->METRICS_statsd_port);
+
+    $log->info("Starting cleaner process");
+
+    my $queue = Zonemaster::Backend::RedisQueue->from_config( $config );
+    while ( 1 ) {
+        my %test_results = $queue->get_test_results;
+        if ( %test_results ) {
+            my $nb_tests = scalar %test_results;
+            $log->info( "Inserting new results for $nb_tests tests", { test_count => $nb_tests } );
+            my $start_time = [ gettimeofday ];
+
+            %test_results = map {
+                $_ => [
+                    map { Zonemaster::Engine::Logger::Entry->new($_) } @{decode_json( $test_results{$_} )}
+                ]
+            } keys %test_results;
+
+            $db->add_result_entries_multiple( %test_results );
+
+            foreach my $hash_id ( keys %test_results ) {
+                $db->test_progress( $hash_id, 100 );
+                Zonemaster::Backend::Metrics::increment("zonemaster.testagent.test_results_inserted");
+                $queue->remove_results( $hash_id );
+            }
+
+            Zonemaster::Backend::Metrics::timing("zonemaster.testagent.test_results_insert_duration_seconds", tv_interval($start_time) * 1000);
+        }
+
+        sleep $config->ZONEMASTER_max_zonemaster_execution_time;
+
+    }
+
+    return;
+}
+
+
+main;
diff --git a/script/zonemaster_backend_testagent b/script/zonemaster_backend_testagent
index 63e98719468f2f12f3e72d8d3744037bc401a7f4..9a382cbf46b440473d38c41a05bcc85204b7be8c 100755
--- a/script/zonemaster_backend_testagent
+++ b/script/zonemaster_backend_testagent
@@ -131,9 +131,7 @@ sub main {
                 Zonemaster::Backend::Metrics::increment("zonemaster.testagent.tests_started");
                 my $start_time = [ gettimeofday ];
 
-                my $params = $chlid_queue->get_test_params( $test_id );
-                $params->{hash_id} = $test_id;
-                eval { $agent->run( $params, $show_progress ) };
+                eval { $agent->run( $chlid_queue, $test_id, $show_progress ) };
 
                 if ( $@ ) {
                     chomp $@;
@@ -144,7 +142,6 @@ sub main {
                     #$self->db->process_dead_test( $test_id )
                 }
                 else {
-                    $chlid_queue->test_finished( $test_id );
                     Zonemaster::Backend::Metrics::increment("zonemaster.testagent.tests_completed");
                     $log->infof( "Test completed: %s", $test_id );
                 }