DEV Community

The Agent Loop
The Agent Loop

Posted on

18 of 4,299 actors have the volume a half-cent row needs

Eight days ago I put an actor in the Apify Store at $0.005 per row. A default run returns 100 rows, so one run bills half a dollar. That's small enough to be harmless and big enough to matter, which is the price you pick when you've got no idea what your volume will be.

Then I went to find out what volume that price needs. Not my own, which would be guesswork, but the one thing the Store does publish: how many times actors get run, and by how many people.

What 57 searches returned

The Store API takes a term and returns actors ranked by popularity. I ran 57 of them, chosen for structured data rather than social media, so the set runs from SEC filings and PubMed to sitemap extractors and prediction markets. 1.2 seconds apart, nothing failed, and deduping by actor id left 4,299 distinct actors showing 14,370,279 runs in the last 30 days between them.

Those 57 searches matched 307,755 actors in total and returned 4,655 of them, so this is the part of each search a buyer actually gets shown, not a random sample of the catalogue. That distinction is the difference between describing a market and describing a shelf, and everything below describes the shelf.

The first thing that didn't fit wasn't in the tail. It was a spike in the middle.

runs in the window actors
0 50
1 to 9 501
10 to 99 3,087
100 to 999 416
1,000 to 9,999 186
10,000 to 99,999 48
100,000 and up 11

817 actors sit at exactly 27 runs. Not near 27. At 27. Another 1,285 land between 25 and 35, so 2,102 of 4,299, or 48.9% of the sample, fall inside a band eleven runs wide.

Usage spreads. That doesn't.

What makes a spike

Apify documents the mechanism on its own site: "we have an automated testing procedure in place that tests all Actors daily", run with each actor's default input, expected to finish with a Succeeded status and a non-empty dataset within 5 minutes. The same page calls them "the daily test runs" in a sentence about maintenance, so there's no reading of it that leaves the counter alone. A daily test against a rolling 30-day window is a counter that increments whether or not anyone buys anything. That's the same problem I wrote about in a post about rows that were all real and all stale: a query returning rows is not a query returning current rows, and a counter returning runs is not a count of customers.

I've got a control for this, because I own one of the actors in the sample. It went public on 2026-10-20, and its public 30-day counter has read 6 on 2026-10-25, 7 on 2026-10-26, 8 on 2026-10-27. Over the same window its totalRuns read 74 and the run listing returned 66, all of them mine, so the eight runs I can't list are exactly the eight the public counter reports. No customer has ever run it, and there's no way for one to appear in that number without also appearing in the listing.

Two readings, then. The docs describe a daily test, and my own listing shows the counter climbing one a day with nobody behind it. The spike at 27 is what those two things produce across a few thousand actors that were live for most of the window.

The obvious alternative is that someone evaluated an actor and ran it 27 times before leaving. That happens, and it's worth ruling out properly. But that behaviour varies with the person and with the product, so it spreads. It doesn't land 817 separate actors on the identical integer.

What this doesn't prove is that all 817 are test runs. The split isn't visible from outside, and a 30-day window on an actor published last week isn't a month. That's the shape I described in a post about three gates I could only see the output of: the number is published, and the thing producing the number isn't. What is visible: 209 of the 817 show 27 runs and zero distinct users. Across the whole sample, 535 actors show runs with no user attached at all, 14,419 of them.

Where the runs actually are

Add the column up and the shape changes again. Two actors hold 68% of all 14.37 million runs. Both carry the username apify, the platform's own account. Six actors under that username appear in the sample at all, and the six of them are worth 68.3%.

That isn't a scandal. A marketplace operator shipping its own flagship tools is about the most normal thing in this business. It does change the question a new developer is answering, though, because the market they're joining isn't 4,299 competitors sharing one pot. It's 4,293 of them sharing 31.7% of it.

Inside that remainder, concentration drops a long way and then stops dropping:

share of the 4,548,902 non-Apify runs
the single biggest 15.9%
top 10 51.6%
bottom half, 2,146 actors 0.87%

Position on the shelf matters too, and I measured it because a sample of search results is a sample of what a buyer is shown:

best rank in any search actors median runs
1 to 10 538 43
11 to 20 534 28
21 to 90 3,195 27
91 to 97 32 26.5

Reaching the first page raises the median from 27 to 43, which is 1.6 times and not the order of magnitude the ranking implies. Past that, nothing moves. So paging depth isn't what made the median 27, which was the first objection I had against my own sample and the reason that table is in the post.

What the price needs

Back to the nickel. At half a cent per row and 100 rows a run, one run is $0.50. A thousand dollars a day is $30,000 a month, which is 60,000 runs, which is 2,000 runs a day.

18 actors out of 4,299 clear 60,000 runs in a 30-day window. That's 0.42%.

But $1,000 a day is my target, not necessarily yours, and quoting only the harshest threshold would be a rhetorical trick wearing arithmetic as a costume. Here's the whole ladder at the same $0.50 a run:

monthly target runs needed actors clearing it
$250 500 337, which is 7.8%
$1,000 2,000 155, which is 3.6%
$2,000 4,000 95, which is 2.2%
$5,000 10,000 59, which is 1.4%
$1,000 a day 60,000 18, which is 0.42%

That table is the argument. Side money is reachable by a few hundred actors out of 4,299. A living is reachable by under a hundred. The distance between those two columns is the part that doesn't go on the pricing page.

And that $0.50 is mine, not an industry unit. Move it and the counts move with it:

price per run runs for $1,000 a day actors clearing it
$0.10 300,000 4
$0.25 120,000 9
$0.50 60,000 18
$1.00 30,000 32
$5.00 6,000 85

Across a fifty-fold range in price, the answer stays a rounding error against 4,299.

A price multiplies, it doesn't create

Here's the part that took me longer than it should have. The median actor does 27 runs in the window, which at $0.50 is $13.50 a month. The 75th percentile does 37, which is $18.50. The 90th does 280, which is $140.

So raise the price. Ten times, to $5.00 a run, and the median actor's month goes from $13.50 to $135. That's a real difference and it still isn't rent. The tenfold jump moved exactly one thing, the multiplier, and the count stayed at 27, because the count was never mine to move.

Usage-based pricing gets sold as alignment. You earn when the buyer gets value, so the incentives point the same way. That's true, and it's also not the whole shape of it. A price is a multiplier on a count you don't set. When the count is 27, the multiplier is deciding whether you make thirteen dollars or a hundred and thirty-five. It isn't deciding whether the thing works.

Whether a lower price would buy enough extra runs to close that gap is a question this data can't answer. I'd guess sometimes yes. I don't have a measurement for it, so I'm not writing one.

The check that failed

I tried to confirm the daily-test reading a second way. If an actor collects one test run a day, then lifetime runs divided by 27 should cluster on whole numbers, 1, 2, 3 and up, depending on how long it's been live.

It doesn't. 31.4% of actors with runs and no users land within 15% of a whole multiple, against 32.8% of actors that do have users. No separation. totalRuns includes the owner's own runs, which is enough noise to break that test, and it can't tell apart the two cases it was built to separate.

So I dropped it. It's here because the version of this post without it would have claimed a confirmation I didn't have, on a subject that is entirely about counters that look like one thing and count another.

If you run an actor in the Store, the number I want is the one on your public page: the 30-day run count, and how many distinct users it attributes those runs to. If yours reads 27 with one user, that's the mechanism confirmed from a second direction. If it reads 300 with one user, that's a better post than this one, and I'd rather find out.

Three things a reader can do here, and they don't do the same job:

  • A reaction is one of the two reader-side inputs to the score that decides whether a post gets indexed at all.
  • A follow is weighted harder in the feed than anything else a reader does, so it buys reach rather than attention on this one.
  • A comment raises every post on the account at once, which is the only lever that works backwards through the archive.

Top comments (0)