Looking at Tarpit and LLM Maze Stats

speckx1 pts0 comments

Looking At Tarpit and LLM Maze Stats | www.bentasker.co.uk

Skip to main content

About 4 years ago, I looked into how effective my SSH tarpits were.

Since then, I've also deployed an AI crawler tarpit (technically a maze - it generates an endless number of pages) to serve "content" up to crawlers who ignore my "No Entry" signs.

I thought that it might be interesting to take a quick look at trends for both, so this post provides high-level analysis of the statistics that my tarpits generate.

SSH Tarpit

The analysis that I performed in 2022 used a week of data, so to keep things consistent, I'll do the same here.

from(bucket: "telegraf/telegraf_low_granularity")<br>|> range(start: 2026-08-01T00:00:00Z, stop: 2026-08-08T00:00:00Z)<br>|> filter(fn: (r) => r._measurement == "ssh_tarpit")<br>|> filter(fn: (r) => r._field == "after_sum")<br>|> filter(fn: (r) => exists r.country)<br>|> group()<br>|> sum()

In the last week, my tarpits have burnt 11.6 days of bot time. In 2022, a single week burnt 20.14 days, meaning that 2026 represents a 42.5% reduction in bot time wasted by the tarpit.

Is that because fewer bots get stuck in the tarpit, or because they spend less time in there?

from(bucket: "telegraf/telegraf_low_granularity")<br>|> range(start: 2026-08-01T00:00:00Z, stop: 2026-08-08T00:00:00Z)<br>|> filter(fn: (r) => r["_measurement"] == "ssh_tarpit")<br>|> filter(fn: (r) => r["_field"] == "after_count")<br>|> aggregateWindow(every: v.windowPeriod, fn: sum, createEmpty: false)<br>|> group(columns: ["country"])<br>|> sum()<br>|> group()<br>|> sum()

There were 9387 tarpitted connections, vs 6354 in 2022. So we saw 47% more bots, but they stuck around for much shorter times.

Breaking that down by country:

from(bucket: "telegraf/telegraf_low_granularity")<br>|> range(start: 2026-08-01T00:00:00Z, stop: 2026-08-08T00:00:00Z)<br>|> filter(fn: (r) => r["_measurement"] == "ssh_tarpit")<br>|> filter(fn: (r) => r["_field"] == "after_count")<br>|> filter(fn: (r) => exists r.country)<br>|> aggregateWindow(every: v.windowPeriod, fn: sum, createEmpty: false)<br>|> group(columns: ["country"])<br>|> sum()<br>|> group()<br>|> top(n: 5)

Position<br>Country<br>Count

Unknown<br>3707

CN<br>1550

IN<br>967

US<br>939

VN<br>710

This is quite a big change: back in 2022, the US was the most common source of connections (with Russia a close second).

If we look at what proportion of each country's connections stick for over 1 minute:

threshold = 60.0

from(bucket: "telegraf/telegraf_low_granularity")<br>|> range(start: 2026-08-01T00:00:00Z, stop: 2026-08-08T00:00:00Z)<br>|> filter(fn: (r) => r._measurement == "ssh_tarpit")<br>|> filter(fn: (r) => r._field == "after_mean")<br>|> filter(fn: (r) => exists r.country)<br>|> group(columns: ["country"])<br>|> filter(fn: (r) => r._value >= threshold)<br>|> count()<br>|> map(fn: (r) => ({ r with<br>// What percentage of conns?<br>_value: (float(v: r._value) / 6365.0) * 100.0<br>}))<br>|> group()<br>|> top(n: 5)

We can see the that top 5 countries by stick time have shifted:

Position<br>2026

2022

2021

VN<br>8.3%<br>CN<br>4.95%<br>CN<br>10.64%

Unknown<br>8.13%<br>VN<br>1.29%<br>VN<br>1.29%

CN<br>0.88%<br>RU<br>0.39%<br>RU<br>0.39%

IR<br>0.29%<br>US<br>0.17%<br>US<br>0.17%

US<br>0.16%<br>ZA<br>0.09%<br>ZA<br>0.09%

Connections originating from China are now much less likely to stick than previously.

We can expect, then, that the average and max stick times have also shifted quite heavily:

from(bucket: "telegraf/telegraf_low_granularity")<br>|> range(start: 2026-08-01T00:00:00Z, stop: 2026-08-08T00:00:00Z)<br>|> filter(fn: (r) => r._measurement == "ssh_tarpit")<br>|> filter(fn: (r) => r._field == "after_mean")<br>|> aggregateWindow(every: 1d, fn: mean)<br>|> group()<br>|> mean()

from(bucket: "telegraf/telegraf_low_granularity")<br>|> range(start: 2026-08-01T00:00:00Z, stop: 2026-08-08T00:00:00Z)<br>|> filter(fn: (r) => r._measurement == "ssh_tarpit")<br>|> filter(fn: (r) => r._field == "after_max")<br>|> aggregateWindow(every: 1d, fn: max)<br>|> group()<br>|> max()

Stat<br>2022<br>2026<br>Delta

Mean<br>539.31s<br>16.50s<br>- 97%

Max<br>273670s<br>582828s<br>+ 112%

So, despite the maximum stick time increasing significantly, the mean stick time greatly reduced in 2026. For the record, the biggest stick time (7 days) was a bot from Sweden.

Summary

Four years later, running a SSH tarpit looks like this:

Stats<br>%age change

Bots entering<br>+ 47%

Total Time Wasted<br>- 42.5%

Average Stick Time<br>- 97%

The tarpit is still effective enough to give some warm fuzzies but also probably isn't really effective enough to be worth fixing if it were to break.

LLM Tarpit

Introduction

With the exception of the occasional social media post I've not written about this before.

The crawlers that are used to train AI models have proven to be a scourge of the internet. So many companies are caught up in gold-rush fever and operate crawlers which collectively overload services intended for humans.

Previously, I deployed Anubis in front of some of my services, however it only really catches the lower hanging fruit and at the cost of inconveniencing actual humans.

Although I still have Anubis deployed in various places, many of my sites now quietly...

filter tarpit country group time from

Related Articles