diff --git a/release.nix b/release.nix
index 31ac8ada..813c3975 100644
--- a/release.nix
+++ b/release.nix
@@ -81,6 +81,18 @@ in rec {
 
       #nix = nixUnstable;
 
+      NetStatsd = buildPerlPackage {
+        name = "Net-Statsd-0.11";
+        src = fetchurl {
+          url = mirror://cpan/authors/id/C/CO/COSIMO/Net-Statsd-0.11.tar.gz;
+          sha256 = "0f56c95846c7e65e6d32cec13ab9df65716429141f106d2dc587f1de1e09e163";
+        };
+        meta = {
+          description = "Sends statistics to the stats daemon over UDP";
+          license = "perl";
+        };
+      };
+
       perlDeps = buildEnv {
         name = "hydra-perl-deps";
         paths = with perlPackages;
@@ -116,6 +128,7 @@ in rec {
             LWP
             LWPProtocolHttps
             NetAmazonS3
+            NetStatsd
             PadWalker
             Readonly
             SQLSplitStatement
diff --git a/src/script/hydra-send-stats b/src/script/hydra-send-stats
new file mode 100755
index 00000000..dd893d77
--- /dev/null
+++ b/src/script/hydra-send-stats
@@ -0,0 +1,48 @@
+#! /run/current-system/sw/bin/perl
+
+use strict;
+use utf8;
+use Net::Statsd;
+use JSON;
+
+STDERR->autoflush(1);
+binmode STDERR, ":encoding(utf8)";
+
+sub gauge {
+    my ($name, $val) = @_;
+    die unless defined $val;
+    Net::Statsd::gauge($name, $val);
+}
+
+sub sendQueueRunnerStats {
+    my $s = `hydra-queue-runner --status`;
+    die "cannot get queue runner stats\n" if $? != 0;
+
+    my $json = decode_json($s) or die "cannot decode queue runner status";
+
+    return if $json->{status} ne "up";
+
+    gauge("hydra.queue.steps.active", $json->{nrActiveSteps});
+    gauge("hydra.queue.steps.building", $json->{nrStepsBuilding});
+    gauge("hydra.queue.steps.runnable", $json->{nrRunnableSteps});
+    gauge("hydra.queue.steps.unfinished", $json->{nrUnfinishedSteps});
+    gauge("hydra.queue.steps.finished", $json->{nrStepsDone});
+    gauge("hydra.queue.steps.retries", $json->{nrRetries});
+    gauge("hydra.queue.steps.max_retries", $json->{maxNrRetries});
+    if ($json->{nrStepsDone}) {
+        gauge("hydra.queue.steps.avg_total_time", $json->{avgStepTime});
+        gauge("hydra.queue.steps.avg_build_time", $json->{avgStepBuildTime});
+    }
+
+    gauge("hydra.queue.builds.read", $json->{nrBuildsRead});
+    gauge("hydra.queue.builds.unfinished", $json->{nrQueuedBuilds});
+    gauge("hydra.queue.builds.finished", $json->{nrBuildsDone});
+
+    gauge("hydra.queue.checks", $json->{nrQueueWakeups});
+}
+
+while (1) {
+    eval { sendQueueRunnerStats(); };
+    if ($@) { warn "$@"; }
+    sleep(30);
+}