Skip to content
monitor twitter accountx account monitoring costtwitter api polling costpoll intervaltwitter monitoring apix api cost

GUIDE

Watching 50 X Accounts: What Every Poll Cadence Actually Bills

Every monitoring page sells you an interval and calls it real time. None of them prices it. Here is what a one minute, fifteen minute and daily poll across a fixed fifty account roster costs per month, and the route where the watch itself bills nothing.

Per our own spec, 60 of 99 endpoints bill $0.0008, 24 are free, and 15 sit between $0.0016 and $0.01. Every price ships inside our published OpenAPI document as an x-cost-usd field, so any figure in this post can be checked against the contract that bills it rather than taken on trust.

By , developer relations at TwitterAPIs·
What it costs to monitor a roster of fifty X accounts at each poll interval, with monthly billing, mean detection latency and cost per captured post

TL;DR: Watching a named roster of fifty X accounts costs between $1.20 and $1,728.00 a month depending on one setting, and that setting is the poll interval. [Source: derived from the live per-call rate in lib/endpoint-costs.ts, one timeline read per account per cycle, thirty day month.] A daily pull is $1.20. Fifteen minutes is $115.20. One minute is $1,728.00, which is 1,440 times the daily figure for the same accounts on the same endpoint at the same rate. Mean detection delay is half the interval, so what the extra money buys is freshness and never coverage. At a fifteen minute cadence 94.79 percent of your calls return nothing new, and the webhook route bills nothing for the watch itself, which drops the same job to about $6.00 a month with no delay at all.

Every page that ranks for X account monitoring sells you an interval and calls it real time. Not one of them tells you what that interval costs. This post prices seven of them against a fixed fifty account roster, using the rates that actually charge for the calls, then shows the two numbers the vendor pages have no reason to publish: mean detection delay, and cost per post you actually captured.

The short answer

Watching a named roster of fifty X accounts costs between $1.20 and $1,728.00 a month, and the only input that moves it that far is the poll interval. A daily pull is $1.20, fifteen minutes is $115.20 and one minute is $1,728.00, all on the same endpoint at the same $0.0008 read rate. Mean detection delay is half the interval, so the extra money buys freshness and never coverage. At a fifteen minute cadence 94.79 percent of calls return nothing new, and the monitor and webhook surfaces bill nothing at all, which puts the same job at about $6.00 a month with no delay.

The three questions a monitoring vendor page does not answer about running a watch yourself
What the tool pages leave out

The reason this gap exists is structural rather than dishonest. A monitoring tool sells a seat, so its pricing page is a function of features and users. Your bill is a function of cycles and accounts. Those are different shapes, and no seat price can be converted into a cadence cost without knowing the roster, which the vendor does not know when it writes the page.

What a monitoring bill is actually made of

A poll-based watch has exactly four inputs, and once you have them the bill is arithmetic with no judgement left in it. Cycles per day, accounts in the roster, days in the month, and the billed rate for the endpoint you call. Everything else, the language you wrote it in, the queue you put it behind, the alerting on the other end, changes your engineering time and not your data bill.

The four multipliers that turn a per call rate into a monthly monitoring bill
Four numbers, one bill

For a named roster the correct call shape is one timeline read per account per cycle. That endpoint returns up to twenty posts per call and bills at the standard read rate of $0.0008, the same rate that covers most of the catalogue. Of the 99 documented endpoints, 63 are reads and 36 are writes, and the overwhelming majority of the priced rows sit on that one standard rate rather than on any premium tier.

That matters here because it removes a variable most cost discussions get stuck on. You are not choosing between endpoints with wildly different prices. You are choosing how many times to call the same cheap endpoint, and the multiplier is doing all the work.

There is one endpoint choice worth getting right, and it is not a price question. For a roster, poll the timeline endpoint rather than search. Search is ranked and filtered rather than exhaustive, so a post can exist and not appear in a result, which is a failure mode we have written about at length in why X advanced search misses posts. A timeline read cannot miss a post the account actually made. Picking search for a roster job is the most common way a build ends up both more expensive and less complete, because the empty results still bill.

The seven cadences, priced

Here is the whole question in one table. A poll cadence bills the same way at every interval, so the seven rows below differ only in how often the job runs: fifty accounts, one timeline read each per cycle, a thirty day month, and the standard read rate throughout. Nothing else about the job changes between rows.

What each poll interval bills per month on a fixed fifty account roster

IntervalCycles per dayCalls per monthMonthly costMean detection delaySource
Every minute1,4402,160,000$1,728.0030 secondsderived
Every 5 minutes288432,000$345.602 min 30 sderived
Every 15 minutes96144,000$115.207 min 30 sderived
Every 30 minutes4872,000$57.6015 minutesderived
Hourly2436,000$28.8030 minutesderived
Every 6 hours46,000$4.803 hoursderived
Daily11,500$1.2012 hoursderived

as of 2026-09-12

Method: One timeline read per account per cycle, fifty accounts, thirty day month, billed at the standard $0.0008 read rate read from the endpointCosts array in lib/endpoint-costs.ts on origin/main. Calls per month is cycles per day times fifty times thirty. Mean detection delay is half the interval, which is the expected wait for a post that lands at a uniformly random moment inside one cycle. Falsifiable by re-running the same multiplication against the rate in that file, or by instrumenting a real poller and comparing observed delay to the modelled half interval.

Run these numbers against your own roster

Every figure in this post is four multiplications on a published rate. Put your own account count and interval in and see what your watch actually bills before you change anything.

Monthly cost of watching fifty X accounts at seven poll intervals
The same roster, 1,440 times the bill

The first thing to notice is the range. $1.20 to $1,728.00 is a factor of 1,440, and it comes from a single configuration value that in most codebases is a constant nobody has revisited since the day the job was written. [Source: derived from the live per-call rate in lib/endpoint-costs.ts, roster and cadence inputs as stated in the table methodology.] The second thing to notice is that the rate never changed. Every row bills at $0.0008. There is no tier, no discount, no penalty. The entire spread is the interval.

The headline spread between a daily pull and a one minute poll on the same fifty accounts
The spread the interval decides

This is why comparing vendors on headline rate is close to useless for a monitoring job. A competitor charging ten percent less than us moves the fifteen minute row from $115.20 to about $103.68. Moving from a one minute interval to a fifteen minute interval on our own rate moves it from $1,728.00 to $115.20. The decision that is worth a meeting is the one people make without one.

You can check any of these figures against your own roster shape with the cost calculator, which runs the same multiplication with your numbers rather than ours.

What the money actually buys

A shorter interval does not find more posts. It finds the same posts sooner. That is worth saying plainly because the marketing language around monitoring, real time, instant, live, implies coverage when it is describing latency.

If a post lands at a uniformly random moment inside one poll cycle, the expected wait before your next poll sees it is half the cycle. That is the whole model, and it is accurate enough to budget against.

Mean detection delay at each poll interval, which is half the interval
What you are actually buying

So a one minute poll gives you a thirty second mean delay and a fifteen minute poll gives you seven minutes and thirty seconds. The difference between them is fourteen minutes and thirty seconds of average freshness, and $1,612.80 a month. [Source: derived from the live per-call rate in lib/endpoint-costs.ts, roster and cadence inputs as stated in the table methodology.]

Put that way, the question stops being "how fast can we go" and becomes "what is a minute worth", which is answerable.

What one minute of removed mean detection delay costs at each step up

StepExtra monthly costMean delay removedCost per minute of delay removedSource
Daily to hourly$27.60690 minutes4 cents per minutederived
Hourly to 15 minutes$86.4022.5 minutes$3.84 per minutederived
15 minutes to 5 minutes$230.405 minutes$46.08 per minutederived
5 minutes to 1 minute$1,382.402 minutes$691.20 per minutederived

as of 2026-09-12

Method: Each row subtracts two adjacent monthly costs from dt-cadence and divides by the difference in mean detection delay, which is half the difference in interval. The resulting series rises roughly one hundred times from the cheapest step to the most expensive, which is the finding: latency is priced as a staircase and each tread is steeper than the one below it. Falsifiable by recomputing from the dt-cadence figures.
Marginal monthly cost of removing one minute of mean detection delay at each step
Latency is a staircase, not a slope

Read that series again, because it is the most useful thing in this post. Going from a daily pull to hourly buys you eleven and a half hours of freshness for four cents a minute. Going from five minutes to one minute buys you two minutes of freshness at $691.20 a minute. That is not a gentle curve with diminishing returns, it is a staircase where each tread costs roughly a hundred times the one below it.

Almost every monitoring job has a point on that staircase where the next step stops being defensible. Very few have written down where it is.

Cost per post actually captured

The cadence table prices the job. This one prices the outcome, and it is the version that tends to end the argument in a planning meeting, because it converts an abstract interval setting into a unit cost for the only thing the watch exists to produce, which is a post you did not already have.

Take one account that posts five times a day. A one minute poller gives itself 1,440 opportunities a day to notice something, and five of them contain anything new. The other 1,435 are billed, parsed, logged and discarded.

Cost per post actually captured, for one account posting five times a day

IntervalCalls per dayCalls per post capturedCost per postCycles returning nothing newSource
Every minute1,440288.0$0.23040099.65%derived
Every 5 minutes28857.6$0.04608098.26%derived
Every 15 minutes9619.2$0.01536094.79%derived
Every 30 minutes489.6$0.00768089.58%derived
Hourly244.8$0.00384079.17%derived
Every 6 hours40.8$0.0006400.00%derived
Daily10.2$0.0001600.00%derived

n = 5 · as of 2026-09-12

Method: Models one account posting five times in a day, which is a stated assumption and not a measurement of any account. Calls per post captured is calls per day divided by five. Cost per post is that figure times the $0.0008 standard read rate. The empty cycle share is one minus five over cycles per day, floored at zero once cycles per day drops to five or below, where every cycle returns at least one new post. Substitute your own roster's real posting rate and the shape holds while the numbers move. Falsifiable by logging how many of your own poll responses contain a post you had not already seen.
Cost per thousand posts actually captured at each poll interval for an account posting five times a day
The number that ends the argument

Per thousand posts captured, which is the unit the rest of this market quotes in, that is $230.40 at a one minute interval against $15.36 at fifteen minutes and $0.16 at a daily pull. [Source: derived from the same live per-call rate, at the stated five posts a day.] The same posts, the same account, the same endpoint. The only thing that changed is how many times you asked.

The empty cycle column is the one to sit with.

Share of poll cycles that return nothing new at each interval
What you are paying for when nothing happened

At a fifteen minute interval, 94.79 percent of your calls return nothing you did not already have. That is not a defect in the API and it is not waste you can engineer away with better parsing. It is the definition of polling: you ask repeatedly because you cannot be told, and most of the time the answer is no.

Hold on to the figure 94.79 percent. It comes back later, exactly, and not by coincidence.

Roster size is the other multiplier

Cadence gets all the attention because it feels like a performance setting that engineers own. Roster size is the same lever wearing different clothes, it multiplies the bill by exactly the same arithmetic, and it is usually the easier of the two to move because removing an account nobody reads costs nothing and upsets no one.

Monthly cost by roster size, holding the interval at fifteen minutes

Accounts watchedCalls per monthMonthly costCost per accountSource
1028,800$23.04$2.304derived
2572,000$57.60$2.304derived
50144,000$115.20$2.304derived
100288,000$230.40$2.304derived
250720,000$576.00$2.304derived
5001,440,000$1,152.00$2.304derived

as of 2026-09-12

Method: Ninety six cycles a day times the account count times thirty days times $0.0008. Cost per account is constant by construction, which is the point of the table: there is no volume discount hiding in the arithmetic, so a roster decision and a cadence decision spend the same budget and can be traded against each other one for one. Falsifiable by the same multiplication.
Monthly monitoring cost by roster size at a fifteen minute interval
Roster size is the other multiplier

Cost per account is flat at $2.304 across every roster size, which is the useful part. [Source: derived from the live per-call rate in lib/endpoint-costs.ts, roster and cadence inputs as stated in the table methodology.] There is no volume discount hiding in the arithmetic, so an account added to the watch costs exactly what the fiftieth one did. That makes the two levers directly interchangeable: doubling the roster and halving the frequency leaves the bill where it was.

That trade is often the right one. A roster grows by accretion, someone adds a competitor, someone adds a journalist, someone adds an account that was relevant during one campaign in March. Those late additions are almost always lower signal than the original list, and they are charged at the same rate as the accounts you actually care about. Auditing the roster is usually cheaper than optimising the code.

Three monitoring archetypes and the interval each one can defend
Three watches, three correct answers

The three archetypes above are worth naming because they want genuinely different answers rather than different amounts of the same answer. A trading signal watch on twelve accounts can defend a short interval because the value of the information decays in seconds. A brand watch on two hundred accounts almost never can, because a mention that matters at nine in the morning still matters at nine fifteen. A research corpus wants a daily pull and a wide roster, because nothing about it is time sensitive at all.

We have priced the buy side of this decision separately in build versus buy for X monitoring, and the per-seat version of the same arithmetic lives in the X API as COGS. This post is the roster-level view that sits between them.

What the free credit actually covers

The signup credit is $0.50 with no card required, which at the standard $0.0008 rate is 625 calls. On a fifty account roster that is 12.5 poll cycles, and the honest arithmetic is short.

How long the free signup credit lasts on a fifty account roster at each interval
What the free credit really buys

A one minute poller exhausts the whole credit in 12.5 minutes. A five minute poller lasts just over an hour. A fifteen minute poller gets about three hours and eight minutes. A daily pull runs for 12.5 days.

That is enough to build the job end to end: confirm the response shape, watch it fire, check your parsing, verify your deduplication actually deduplicates. It is not enough to leave running, and a plan that assumes otherwise has an arithmetic error rather than a budget problem. We would rather say that here than have you discover it on day two. The same honesty applies to what the free tier is, which is a question with a more complicated answer than either yes or no.

The cheapest cadence is no cadence

Everything above prices polling. Polling is not the only shape a watch can take, and the alternative is missing from all ten results currently ranking for this query, which is why a route that removes most of the bill and the latency question at the same time reads as a trick rather than as the ordinary engineering it is.

The monitor and webhook surfaces sit in the biller's zero price set, alongside the account and session endpoints. Registering a watch bills nothing. Receiving a delivery bills nothing. You are charged when you fetch something, which means you are charged for signal and never for silence.

The webhook route where the subscription surface bills nothing and only the fetch is charged
The cheapest cadence is no cadence

Run the same fifty account roster through that shape. Fifty accounts posting five times a day is 250 posts a day, or 7,500 a month. If you take the worst case and bill a standard read for every single one of those deliveries, you pay 7,500 times $0.0008, which is $6.00 a month. [Source: derived from the live per-call rate in lib/endpoint-costs.ts, roster and cadence inputs as stated in the table methodology.]

Worked example

Fifty accounts, one month, at three intervals

Every 15 minutes: $115.20 · Webhook route: $6.00 · Saving: 94.79%

☑ The fifteen minute poll bills 144,000 calls a month · ☑ Only 5.21 percent of those cycles return anything new · ☑ The webhook route removes the delay as well as the cost · ☐ A one minute poll on the same roster costs $1,728.00 · ☐ Compute, storage and your own alerting are not included

An illustration of the worked roster in this post, not a customer account. Call counts and costs are derived from the live per-endpoint rates in lib/endpoint-costs.ts on 2026-09-12, and the webhook figure assumes one billed fetch per delivered post at 7,500 posts a month.

Against $115.20 for a fifteen minute poll, that is a 94.79 percent reduction. Against $1,728.00 for a one minute poll it is 99.65 percent.

Now look back at the empty cycle column in the capture table. At fifteen minutes, 94.79 percent of cycles returned nothing new. The saving and the empty share are the same number because they are the same calls. The webhook route does not make anything cheaper by being clever. It simply stops charging you for the calls that were always going to come back empty, and those calls were 94.79 percent of the job.

It also removes the latency question rather than answering it. There is no interval to tune, so there is no mean delay to halve, and the staircase in the earlier table stops applying.

The setup for that route is documented at the webhook API and account activity. It is not the right answer for every job, and the next section is about which jobs it is wrong for.

A developer in the community thread that currently ranks fifth for this exact query described the gap in one line, without prompting:

https://www.reddit.com/r/WebScrapingInsider/comments/1ukuwgj

"Most tools (TweetDeck, Hootsuite, AgoraPulse) do basic keyword streams but not developer-friendly, or with filterable JSON outputs wired to webhooks."

The same thread contains a request that is really a cost preference in disguise. One participant asked for a daily digest instead of a stream of alerts:

send a daily digest summary instead of a million pings

The person asking for less frequency is asking for a smaller bill without framing it that way, and on a fifty account roster the difference between those two products is $1,726.80 a month.

When a short interval is genuinely correct

There is a version of this post that argues everyone should poll slowly, and it would be wrong. Some jobs have a real cost attached to delay, and for those the staircase is worth climbing.

The jobs where a short poll interval is genuinely defensible against the ones where it is habit
When fast is actually worth it

Incident response and brand safety qualify. A hostile post compounds while nobody is looking, and the difference between finding it in thirty seconds and finding it in fifteen minutes is the difference between a reply and a statement. A participant in that same community thread named this case directly, describing a security background and a need for "incident response and brand safety alerts". The interval there is not a budget decision, it is a risk decision, and $1,728.00 a month is cheap against a single mishandled incident.

Market and trading signals qualify for a different reason. The value of the information does not merely decay, it goes to zero once it is priced in, and it is priced in quickly. A published bot that polled Musk's timeline described its own schedule plainly:

https://x.com/localminimaa/status/2038010833905517018

"The bot will hit the X API every 15 minutes and pull Musk's latest tweets"

Fifteen minutes for a market-adjacent job is a defensible number, and what is notable is that the author never says why fifteen. That is the common case. The interval is inherited rather than chosen, and it happens to be reasonable here.

What does not qualify is most of the rest. Competitor tracking, content research, lead discovery, reporting dashboards and newsletter sourcing all run happily on an hourly or daily pull, and all of them are routinely found running on a one minute timer because the constant was copied from an example.

The test is a single sentence you should be able to finish: a ten minute delay on this job costs us ____. If you cannot fill in the blank with something concrete, you are paying $1,612.80 a month more than a fifteen minute poll for a property you have never valued. That is not a case for going slow. It is a case for knowing which one you picked.

Start building with TwitterAPIs

$0.0008 a call, about $0.04 per 1,000 tweets at 20 tweets a page. $0.50 free credits. No credit card required.

Where the arithmetic goes wrong after it ships

A cost model that was correct on the day it was written stops being correct in five predictable ways. Every one of these has a tell you can check in an afternoon.

Five ways a monitoring cost model goes wrong after it ships
Where the arithmetic breaks

The roster grows and nobody re-runs the number. Accounts get added one at a time by people who are not thinking about the bill, and each addition is invisible in a monthly total. A roster that drifts from fifty to one hundred and twenty at a fifteen minute interval moves from $115.20 to $276.48 with no code change and no deploy. [Source: derived from the live per-call rate.] Print the roster size in your job's own logs on every run, so the number that drives the bill is visible to whoever reads them.

Retries multiply the interval without changing it. A retry policy with no ceiling turns one failed cycle into three billed calls, and failures cluster. A job with a three attempt retry on a bad afternoon bills at three times its configured cadence for the duration, which is exactly when nobody is looking at the invoice. Cap the retries, and count them separately from the successes so the two never blend into one number.

Pagination turns one call into many. A timeline read returns up to twenty posts. An account that posted thirty times since your last cycle needs two calls, not one. On a slow cadence with busy accounts this is a real correction and it is always in the same direction, so a model built on one call per account per cycle is a floor rather than an estimate. We covered the mechanics of this in the pagination guide, and the practical answer is to bound the depth rather than to loop until empty.

A second poller appears. The dashboard polls, and then the alerting service polls, and then somebody adds a daily report that polls the same accounts again. Three consumers of the same data each running their own timer is three times the bill for one product. The fix is a single fetch writing to your own store, with everything else reading from that.

The interval is tuned during an incident and never tuned back. Somebody drops the poll to thirty seconds to watch something unfold, the incident resolves, and the constant stays. This is the most common instance of all of them, and it is the reason the interval belongs in configuration with an owner rather than in a constant at the top of a file.

None of these is exotic and none is hard to check. What they have in common is that they are invisible in a monthly total and obvious in a per-cycle log, which is an argument for logging per call. Our own best practices guide covers the logging shape, and the rate limit guide covers what happens when a runaway poller meets a ceiling.

Reading the official rate card beside this one

The numbers above are ours. It is worth putting them next to the first-party route, because that market moved twice this year and the moves went in opposite directions for different developers.

X repriced owned reads in April, and a developer who received the announcement posted it verbatim:

https://x.com/Xclusiv/status/2045562091273077036

"We're excited to announce an update to our X API pricing that makes accessing your own data more affordable than ever."

The scope limit is in the announcement itself. Owned reads are requests your own app makes for your own posts, bookmarks, followers, likes and lists. A roster of fifty other people's accounts is not owned data, so the repricing does not reach the job in this post. That distinction is the whole of whether the April change applies to you, and it is the part most summaries of it dropped.

A five step procedure for choosing a poll interval you can defend in fifteen minutes
Pick the interval in fifteen minutes

The direction of travel is worth watching regardless. In September a further change moved X search billing from per-call to per-result:

https://x.com/XFreeze/status/2098114951076630711

"Instead of charging per search tool call, pricing will now be based on what the search actually returns"

X search billing moved from per-call to per-result in September

A change announced for September 21 prices X search on what a query returns rather than on the call itself. Under per-result billing an empty poll costs nothing, which removes the single largest source of waste in a polling design. It applies to that search surface and not to timeline reads, so for a named roster it is a development to track rather than a decision to make today.

X, 2026-09-10

If you have read this far the significance is immediate. Under per-result billing an empty poll costs nothing, which removes the single largest source of waste in a polling design. That does not make polling free, because you still pay for every post you do fetch and busy accounts get expensive, but it does change where the staircase bends. It applies to that search surface and not to timeline reads, so for a roster job it is a development to track rather than a decision to make.

The most instructive artifact in the whole corpus is what happened to a scheduled public bot when per-usage billing arrived:

https://x.com/ChartsKRbot/status/2058393174591324391

"Due to X's implementation of pay-per-usage pricing for the X API, our account is now charged every time the chart is updated. As a result, the bot has temporarily stopped operating."

Due to X's implementation of pay-per-usage pricing for the X API, our account is now charged every time the chart is updated. As a result, the bot has temporarily stopped operating.

A public scheduled job stopped because of its own refresh rate

A chart bot announced that under per-usage pricing it was billed every time its chart updated, and that it had therefore stopped operating. The rate it paid was not unusual. What killed it was that nobody had multiplied that rate by the update schedule before switching the job on, which is the same arithmetic this post sets out.

X, 2026-05-24, 422 favourites and 86,064 views

A running job, killed by the cost of its own refresh cadence, announcing it in public. That is this entire post stated by someone who paid for the lesson. The bot did not fail because the rate was high. It failed because nobody had multiplied the rate by the schedule.

I was paying $200/mo for X API so far. Now it's around ~$20. 10x cheaper thanks to pay-per-usage pricing.

i used to complain about the X API pricing and now im paying double what i used to

One pricing change, two developers, opposite bills

When X moved to pay per usage, one developer publicly reported dropping from about $200 a month to about $20, and another reported paying double what he had been paying. Neither misreported anything. A bill is a rate multiplied by a call volume, and only the rate appears on a price sheet, so the same change halves one bill and doubles another depending entirely on cadence and roster size.

X, 2026-02-26 and 2026-07-04

The same repricing produced flatly contradictory reports from developers who both told the truth. One reported going from about $200 a month to about $20. Another reported paying double. Both are correct, and the variable between them is call volume, which is cadence times roster. It is the clearest evidence available that a rate on its own predicts nothing about a bill.

For a fuller treatment of the first-party comparison, see official X API versus third party and the 2026 pricing change. The first-party rate card and the per-window ceilings are published by the platform itself, and our own read of both is in the rate limit guide and what rate limited means.

A short walkthrough of the monitoring shape, without the arithmetic, is here:

https://www.youtube.com/watch?v=D0Mr6bYHRWs

It is a competent three minute tutorial and it is also a good illustration of the gap this post fills. The title promises real time and the video never states an interval or a cost, which is the format the entire first page of this query shares.

Polling is sampling, and sampling has a known answer

There is an older discipline that has already solved the question this post is asking, and borrowing its vocabulary makes the interval decision much less arbitrary than picking a round number that feels responsive. Polling is sampling, sampling has a literature, and that literature says something surprising about how often you actually need to look.

Polling is sampling a signal at a fixed rate. The signal here is an account's posting behaviour. The Nyquist sampling theorem says that to reconstruct a signal you must sample at more than twice its highest frequency, and that sampling faster than that buys you nothing about the signal itself.

The analogy is not perfect and it is worth saying where it breaks. You are not reconstructing a waveform, you are detecting discrete events, and the timeline endpoint returns history rather than an instantaneous reading, so a slow poll still catches every post as long as it stays inside the page depth. That last clause is the important one and it inverts the usual intuition.

Because each read returns up to twenty posts of history, a slow poll does not miss posts. It batches them. An account posting five times a day is fully captured by a single daily call, because five is comfortably inside one page. The same account polled every minute yields exactly the same five posts and bills 1,440 times for them.

So the real sampling constraint is not frequency against posting rate. It is page depth against posting rate. The question to ask is not "how often do I need to look" but "how long can I wait before this account posts more than one page worth". For an account posting five times a day, twenty posts is four days of history, so a daily poll has a comfortable margin and even a two day interval would be safe on volume alone.

That reframing is worth more than any of the individual numbers in this post. Interval controls latency. Page depth controls completeness. Teams routinely shorten the interval when what they were worried about was completeness, and pay for latency they did not want.

The exception is the genuinely high volume account. A newswire or a busy automated account posting two hundred times a day exceeds twenty posts in under three hours, so a daily poll on that account needs pagination to stay complete, and pagination turns one call into ten. For rosters with a mix of quiet and loud accounts, the correct design is not one interval, it is a per-account interval derived from each account's own rate. That is more code, and on a large roster it is usually where the real saving is.

A cost function you can paste into a planning doc

Everything above is four multiplications on a published rate. Here it is as a function, which is easier to argue with than a table because you can change the inputs and watch which term dominates, and it runs before you have signed up for anything since nothing in it calls an API.

STANDARD_READ = 0.0008   # live rate, reads and simple write actions
PAGE_SIZE     = 20       # posts returned per timeline read

def monthly_cost(accounts, interval_minutes, days=30, posts_per_account_per_day=5):
    """Monthly data cost of polling a roster, and what it buys."""
    cycles_per_day = 1440 / interval_minutes
    pages = max(1, -(-posts_per_account_per_day * interval_minutes // (PAGE_SIZE * 1440)))
    calls = cycles_per_day * accounts * days * pages
    cost = calls * STANDARD_READ

    captured = posts_per_account_per_day * accounts * days
    productive = min(cycles_per_day, posts_per_account_per_day)

    return {
        "calls_per_month":   round(calls),
        "monthly_cost":      round(cost, 4),
        "mean_delay_min":    interval_minutes / 2,
        "cost_per_post":     round(cost / captured, 6),
        "empty_cycle_share": round(1 - productive / cycles_per_day, 4),
    }

The inputs belong in configuration rather than in the code, so the two numbers that drive the bill are visible to whoever reads the repo:

{
  "roster": ["account_a", "account_b", "account_c"],
  "interval_minutes": 15,
  "max_pages_per_cycle": 2,
  "max_retries": 2,
  "owner": "growth-team",
  "reviewed": "2026-09-12"
}

And the schedule belongs somewhere a person can find it, not buried in a sleep call:

# Watch the roster every 15 minutes. 96 cycles a day.
# 50 accounts at $0.0008 a read is $115.20 a month. Raising this to
# every 5 minutes costs $345.60. Ask the owner before changing it.
*/15 * * * * /usr/local/bin/roster-watch --config /etc/roster-watch.json

Running it for the fifty account roster reproduces the table above: a fifteen minute interval returns 144,000 calls, $115.20, a 7.5 minute mean delay, $0.01536 per captured post and a 0.9479 empty share. A one minute interval returns 2,160,000 calls and $1,728.00. [Source: derived from the live per-call rate in lib/endpoint-costs.ts.]

The pages term is the pagination correction described earlier, and it is why the function is worth having rather than a mental estimate. It is one for every configuration in this post, because five posts a day never exceeds a twenty post page at any interval under four days. Raise posts_per_account_per_day to two hundred and the term starts biting at the slow end, which is the behaviour the previous section described.

Nothing in that function calls an API. It is arithmetic on a published rate, so you can run it before you sign up for anything, and you should, because the answer frequently changes what you build.

Two guards keep the job from drifting off its own model. The first bounds pagination so one catastrophic backlog cannot bill unbounded:

def fetch_new(account, seen, max_pages=2):
    """Bounded read. A backlog drains over several cycles rather than in one."""
    out, cursor = [], None
    for _ in range(max_pages):          # never `while True`
        page = client.user_tweets(account, cursor=cursor)
        fresh = [p for p in page.items if p.id not in seen]
        out.extend(fresh)
        seen.update(p.id for p in page.items)
        if not page.next_cursor or len(fresh) < len(page.items):
            break                        # caught up, stop paying
        cursor = page.next_cursor
    return out

The second stops a permanently failing account from being retried forever, which is how a roster of two hundred quietly triples its own call count when one account is suspended:

PERMANENT = {401, 403, 404, 410}

def should_retry(status, attempt, max_retries=2):
    if status in PERMANENT:
        return False                     # will never succeed, stop billing for it
    return attempt < max_retries and status in {429, 500, 502, 503}

If you take the push route instead, the receiving end is smaller than most teams expect, and nothing in it is billed:

@app.post("/x-events")
def receive(request):
    if not valid_signature(request):
        return 401
    for event in request.json["events"]:
        store(event)                     # the delivery itself costs nothing
    return 200

And if you only want the number before you build anything, it is one line:

# accounts * (1440 / interval_minutes) * 30 * 0.0008
python3 -c "print(50 * (1440/15) * 30 * 0.0008)"   # -> 115.19999999999999

A worked brand watch, at two hundred accounts

The fifty account roster is a clean number for a table and a poor model of an actual brand watch. Real rosters are bigger, they contain accounts nobody has reviewed in months, and their posting rates vary by an order of magnitude, so here is one worked end to end with the two audits applied in the order that saves the most money first.

Two hundred accounts: forty competitors, sixty journalists and analysts, sixty industry voices, and forty accounts added during past campaigns that nobody has reviewed. Posting rates vary from two a day to thirty.

At a five minute interval, which is what this kind of job is usually found running, the bill is 288 cycles times 200 accounts times 30 days times $0.0008, which is $1,382.40 a month. At fifteen minutes it is $460.80. At hourly it is $115.20. [Source: derived from the live per-call rate in lib/endpoint-costs.ts.]

Now apply the two audits in order. First the roster. The forty campaign accounts are removed, because nobody has read an alert from them in four months. Two hundred becomes one hundred and sixty, and the five minute bill drops to $1,105.92 without any change to the product.

Second the interval. Brand mentions are not incident response. A mention that matters at nine in the morning still matters at nine fifteen, and the team reads the digest twice a day regardless. Moving to hourly takes the bill to $92.16. [Source: derived from the live per-call rate in lib/endpoint-costs.ts.]

Worked example

Two hundred accounts, two audits, in order

Before, 5 minute poll: $1,382.40 · After both audits: $92.16 · Reduction: 93.3%

☑ Audit the roster first: 40 campaign accounts nobody reads, removed · ☑ Then the interval: brand mentions are not incident response · ☑ The product got better, not worse · ☐ The webhook route would reach about $30.72

An illustration of the worked roster in this post, not a customer account. All four figures are derived from the live per-call rate in lib/endpoint-costs.ts on 2026-09-12, at the stated account counts and intervals.

That is a 93.3 percent reduction from $1,382.40, achieved with a roster review and one configuration change, and the product got better rather than worse because the forty dead accounts were the ones generating the noise that made people stop reading the alerts. [Source: derived from the live per-call rate in lib/endpoint-costs.ts, roster and cadence inputs as stated in the table methodology.]

The route change would take it further. One hundred and sixty accounts at a mixed rate of roughly eight posts a day is about 38,400 deliveries a month, or $30.72 if every one triggers a billed fetch, with no detection delay at all. [Source: derived from the live per-call rate in lib/endpoint-costs.ts.] Whether that is worth the engineering depends on how much delivery handling you want to own, and at $92.16 against $30.72 the honest answer for many teams is not yet.

That last sentence is the one most cost posts will not write. The saving has to clear the engineering, and at an hourly cadence on a medium roster it often does not.

What to log, so this stays true

A cost model is correct on the day it is written and drifts from there. Four lines in your own logs keep it honest, and none of them requires a vendor dashboard.

Log the roster size on every run. This is the multiplier that grows without a deploy, and printing it makes a silent change visible to whoever next reads the logs.

Log calls attempted against calls that returned something new. That ratio is your empty share, and it is the single number that tells you whether the interval is earning its money. If it sits above ninety five percent on a job where latency is not critical, you have found a saving.

Log retries separately from successes. A retry policy with backoff is correct engineering and it is also a multiplier on your bill during exactly the periods nobody is watching. Blended into one counter it is invisible.

Log the interval itself, as a value rather than an assumption. The most expensive intervals in production are the ones changed during an incident and never changed back, and a logged value is the only thing that surfaces that.

With those four you can recompute this post's arithmetic against your own job at any time, which is the difference between a model and a guess.

Picking an interval you can defend, in fifteen minutes

This is the procedure, and it takes about as long as one cycle of the job it is deciding. Five steps, four of them arithmetic, and the only judgement call is the second one. Run it once when you build the watch and again whenever somebody asks to make it faster.

Step one, write down the roster size and stop guessing it. Count the accounts the job actually watches today, not the number in the original ticket. On most jobs older than six months this number is larger than the person who owns it expects, and it is a direct multiplier on everything that follows.

Step two, state what a ten minute delay costs. Not whether it feels slow. What it costs, in money, in a customer outcome, or in a decision that would have gone differently. If the honest answer is nothing, you have already found your interval and it is hourly or slower.

Step three, multiply. Cycles per day times accounts times thirty times $0.0008. Do it for the interval you run now and the one you are considering. The difference between those two numbers is the entire budget of the conversation.

Step four, check whether you need a poll at all. If the job is "tell me when these accounts post", the webhook route bills nothing for the watch and removes the latency question. If the job is "give me everything these accounts said, on a schedule, for analysis", polling is correct and it should be slow.

Step five, put the interval in configuration with a name and an owner. The most expensive intervals in production are the ones that live as an unnamed constant, because nobody can be asked about a number that has no owner.

What to change first in an existing monitoring job, ranked by money saved per hour of work
What to change first

If you are auditing an existing job rather than designing a new one, the order of operations is different, because the cheapest wins come first. Audit the roster before you touch the interval, since removing fourteen accounts nobody reads is a smaller argument than slowing down a job people rely on, and it saves the same money. Then check for duplicate pollers. Then move the interval. Then consider the route change, which is the largest saving and the most work.

Four routes, side by side

Everything in this post reduces to a choice between four shapes, and it is worth seeing them on one axis before the objections, because the rows that separate them are not the ones most comparisons lead with. Latency and price get the attention; how each route behaves during silence is what decides the bill.

Route selection

Four ways to watch a roster, against what each one actually bills

Fast pollSlow pollWebhookVendor seat
Cost scales with roster sizeYes, steeplyYes, gentlyOnly with real postsUsually by tier
Cost scales with silenceYesYesNoNo
Detection delay you controlYesYesNot neededNo
Cost at fifty accounts$1,728.00$115.20$6.00Seat price
You own the parsingYesYesYesNo
Poll and webhook figures are derived from the live per-call rates for a fifty account roster over a thirty day month, fast poll being a one minute interval and slow poll fifteen minutes. Vendor seat is left unpriced on purpose because seat pricing is not a function of roster size and cannot be placed on the same axis honestly.

The row that decides most builds is "cost scales with silence". A poll bills for silence and a webhook does not, and on a roster where accounts are quiet most of the time, silence is nearly the entire bill. That is the same 94.79 percent from earlier, stated as a property of the route rather than as a number.

The row nobody expects is "detection delay you control". It reads like an advantage of polling and it is really a liability. Controlling the delay means owning it, tuning it, and paying for every reduction. A push route removes the parameter, which means there is nothing to get wrong and nothing to leave at thirty seconds after an incident.

The vendor seat column is deliberately left unpriced, and that is not evasion. Seat pricing is not a function of roster size, so it cannot honestly be placed on the same axis as three routes that are. A seat that covers fifty accounts and a seat that covers five hundred are frequently the same price, which is precisely why a vendor page cannot answer the question this post is asking and why a large roster is where buying tends to win.

The cheapest pay-as-you-go Twitter API. Try it free.

$0.0008 a call, about $0.04 per 1,000 tweets at 20 tweets a page. $0.50 free credits. No credit card required.

Deduplication is a cost control, not a correctness detail

Every poller needs to know which posts it has already seen. Most treat that as a correctness problem, which it is, and miss that it is also the place where a cost bug hides.

The naive design stores the id of the newest post seen per account and requests everything after it. That works until an account deletes a post, or until your store is rebuilt, or until an edit changes what the newest id means. The failure mode is a poller that walks backwards through history on every cycle, paginating deeply, and the symptom is a bill rather than an error.

We have seen this shape often enough to name the tell: a job whose call count is roughly stable and whose cost jumps by an order of magnitude overnight with no configuration change. That is pagination, not cadence, and no amount of interval tuning fixes it.

Two guards remove the class. Bound the pagination depth per cycle to a fixed number of pages and accept that a catastrophic backlog takes a few cycles to drain, rather than letting one cycle run unbounded. And keep the seen-set keyed on post id rather than on a high-water mark, so a deletion or an edit cannot reset your position in history. The pagination guide covers the mechanics; the cost argument for bounding it is the one made here.

There is a related trap in handling errors. A poller that treats every non-200 as retryable will hammer a permanently failing account forever, and a roster of two hundred where one account was suspended can quietly triple its own call count. Classify the errors, and stop retrying the ones that will never succeed.

Three questions to ask before you buy a monitoring seat

Buying is frequently right, particularly on large rosters where a seat price stops scaling and your call count does not. These three questions establish whether the offer in front of you is actually cheaper.

What interval does the plan actually poll at, as a number? Real time is not a number. If the answer is fifteen minutes and you were about to build a fifteen minute poller, you now have a like for like comparison against $115.20 on a fifty account roster. If they will not state it, that is informative too.

Is the roster capped, and what happens at the cap? This is where seat pricing and call pricing diverge most sharply. A plan that covers fifty accounts and charges a tier step at fifty one behaves like per-account pricing with worse granularity. A plan with no cap is genuinely a different cost shape from anything you can build.

Do I get the raw payload? A seat that delivers alerts and not data is a different product from one that delivers structured records you can store and re-query. The second is a substitute for building; the first is a substitute for reading. Teams frequently buy the first while budgeting against the second, then build the poller anyway and pay for both.

Our own comparison of the seat-based route against the API route is in what you pay for X data, and a broader view of the decision is in how to choose an X API.

Why the push route exists at all

It is worth a paragraph on why a webhook can bill nothing when a poll cannot, because it sounds like a pricing quirk that some vendor might withdraw next quarter, and it is not. The asymmetry is structural, it predates this market by decades, and understanding it tells you when the route will keep winning.

A poll costs the provider a request, a lookup and a response every time you ask, whether or not anything changed. Those are real and they are why the call is billed. A webhook inverts the direction: the provider already knows a post landed, because it is the provider, so telling you costs it a delivery it was going to compute anyway. There is no repeated lookup to charge for because there is no repeated question.

That asymmetry is old and well understood outside this domain. The tradeoffs were documented for HTTP generally in RFC 6202, and the same push against pull decision shows up in every message queue, including the pull and push subscription models in Pub/Sub. The general pattern has its own name, push technology, and its browser-facing form, server-sent events, makes the same trade for the same reason. The conclusion is consistent across all of them: pull is simpler to operate and wasteful at low event rates, push is more work to operate and efficient at low event rates.

A roster of accounts that post a handful of times a day is a textbook low event rate. That is why the arithmetic in this post lands where it does, and it is why the answer is not a clever trick specific to one vendor. It is the shape of the problem.

Objections worth taking seriously

"Our data cost is tiny, this is not worth an afternoon." It may well be, and the test is not the size of the number but whether the mechanism producing it is bounded. A small bill produced by a fixed roster on a fixed interval is genuinely finished. A small bill produced by a roster anyone can add to, with retries that have no ceiling and pagination that loops until empty, is a large bill that has not happened yet. The difference is invisible in a monthly total. Write down which lines are bounded by your own configuration and which are bounded by other people's behaviour, and if every line is in the first group, stop.

"Thirty day months are not real months." Correct, and the correction is small and predictable. A thirty one day month is 3.33 percent more than the figures here and February is about 6.7 percent less. Every number in this post scales linearly with day count, so multiply by your own figure if the precision matters. The reason to model on thirty is that it makes the cadence comparison clean, which is the comparison the post exists to make.

"Five posts a day is not what our accounts do." Almost certainly not, and the capture table is explicitly a worked example rather than a measurement. The shape survives the substitution: every posting rate produces the same staircase, because the empty cycle share is one minus posts over cycles. Busier accounts raise cost per post at slow cadences and lower the empty share everywhere, quieter accounts do the reverse and make the case for polling slowly stronger. Put your own number in.

"We need one minute because our competitor has one minute." That is a real reason and it is worth pricing rather than dismissing. On a fifty account roster the difference between a one minute and a fifteen minute poll is $1,612.80 a month, which is $19,353.60 a year. [Source: derived from the live per-call rate.] If matching that claim wins deals worth more than that, it is a good trade, and you should make it deliberately. Note also that the webhook route beats a one minute poll on latency outright while costing about $6.00, so the competitive answer and the cheap answer are frequently the same answer.

"Polling is simpler than webhooks and simple is worth money." Often true. A poller has no public endpoint, no delivery retries to handle, no signature to verify and no ordering questions. On a small roster with a slow cadence, the difference is $1.20 a month against $6.00 and you should take the simpler one without a meeting. The route change earns its complexity somewhere between an hourly and a five minute cadence, and the point at which it does is a number you can now compute rather than a matter of taste.

"We will just cache and that solves it." Caching is genuinely powerful on the lookups around a watch, profile details, follower counts, post detail on anything already seen, and those should all be cached hard. It does nothing for the poll itself, and the reason is definitional rather than technical. The entire purpose of a poll is to discover something you do not have, so a cache hit on the poll means you did not look. Model the poll separately from the lookups, cache the lookups aggressively, and spend what you save on the interval where it changes the product.

"Our accounts post far more than five times a day." Then the cost per post figures improve at every interval and the empty share drops, which strengthens the case for polling rather than weakening it. What changes is completeness: a busy account exceeds a twenty post page sooner, so a slow interval starts needing pagination, and the per-account interval design from the sampling section becomes the right answer instead of a refinement. Busy rosters make polling more efficient and more complicated at the same time.

"Rate limits will stop us before cost does." They constrain a different thing and they bind at a different place. A ceiling is per window and per credential, and the bill is per call regardless of whether you are near a ceiling. Most rosters hit an uncomfortable monthly figure well before they hit a limit, which is the opposite of what most teams expect. What rate limited means covers the mechanics, and the short version is that cost and limits are separate constraints that happen to be driven by the same multiplier.

The keyword watch bills differently, and worse

Everything so far assumes a named roster, which is the well behaved case. A large share of monitoring jobs watch a search term instead, and for those the arithmetic changes in two ways that both push the cost up and make it harder to predict in advance, so the roster figures above are a floor rather than a guide.

The first is that a keyword watch has no natural unit. A roster has fifty accounts, so a cycle is fifty calls and the number is knowable in advance. A term has as many results as it has, so a cycle is one call if the term is quiet and ten if it is not, and the busy days are exactly the days you cared about. Your bill correlates with the thing you are monitoring for, which is an uncomfortable property in a budget.

The second is completeness. A timeline read returns what an account posted. A search returns what the ranking decided to return, which is not the same set, and the gap is neither documented nor stable. We have written the honest version of that in the monitoring coverage post, and the practical consequence for cost is that teams compensate for uncertain completeness by polling more often, which is the most expensive possible response to a problem that frequency does not fix.

If a term watch is what you need, three things keep it bounded. Narrow the query with operators rather than filtering client side, because a filtered-out result was still billed; the operator reference covers the set. Bound the pages per cycle so a viral day cannot run away. And where the thing you actually care about is a set of known accounts saying something, prefer the roster shape, because it is cheaper, complete, and predictable, and it is what most keyword watches were really trying to express.

A hybrid is usually correct on a brand watch: a roster for the accounts that matter, polled slowly or pushed, plus one narrow term query for everything else, polled hourly with a page cap. That splits a job with unbounded cost into a bounded part and a small part.

Two extremes worth checking your instinct against

One account, watched closely. A founder tracking a single competitor at a one minute interval pays 1,440 calls a day, 43,200 a month, which is $34.56. [Source: derived from the live per-call rate.] That is genuinely cheap, and it is the case where the fast poll is fine, because the multiplier that makes cadence expensive is the roster and there is no roster. If you have been extrapolating from a personal project to a product, this is the number that misled you.

The wide-and-slow shape is also what people ask for when they describe the job in their own words rather than in product language. A developer in r/webscraping put the whole specification in two sentences:

https://www.reddit.com/r/webscraping/comments/1937al7

"I'm looking to do a daily scrape of say, 10-20 accounts, and collect tweets from the past 24hrs from each one. I think this should not add up to many requests"

That instinct is correct and the arithmetic confirms it. Twenty accounts pulled once a day is 600 calls a month, which is $0.48, and it fits inside the free signup credit with room to spare. [Source: derived from the live per-call rate and the $0.50 signup credit.] The same thread also notes that the packaged options were "simply WAY too expensive for my small test case", which is what happens when a seat price meets a job this small.

Five hundred accounts, watched slowly. A research corpus pulled once daily is 500 calls a day, 15,000 a month, which is $12.00 for a roster ten times the size of the one used throughout this post. [Source: derived from the live per-call rate.] Wide and slow is the cheapest useful shape in the entire space, and it is the one most often ruled out early because "daily is not monitoring". For a great many jobs, daily is exactly monitoring, and calling it something else has cost teams real money.

Between those two poles sits every configuration in the tables above. The instinct that a bigger roster means a bigger bill is right. The instinct that a bigger roster means you need a faster poll is backwards, and it is the expensive one, because the two multipliers compound.

Operator noteEvery rate here is read from the biller, not a marketing page. Roster size and posting rate are stated models, so substitute your own., Methodology

What this post is not claiming

Three limits, stated plainly, because a cost model that overstates its own reach is worse than no model at all. Each one narrows what the numbers above can be used for, and none of them changes the conclusion about intervals, which is the only claim this post is actually making.

These are our rates, not the market's. Every figure here is computed from the per-call price that bills on our own platform. A different provider will produce a different column of numbers, and the interesting claim is not that ours are lower, it is that the SHAPE holds everywhere. Cadence is a multiplier on any per-call rate, so the 1,440 times spread between a daily and a one minute poll survives whatever rate you substitute. Run the function above with somebody else's number and the conclusion does not move.

The posting rate is modelled, not measured. Five posts a day per account is a stated assumption used consistently throughout so the tables compare like with like. It is not a measurement of any real roster, and any real roster will have a distribution rather than a constant. The rows marked as derived in each table say so explicitly, and substituting your own rate changes the cost-per-post column materially while leaving the monthly cost column untouched, because monthly cost does not depend on posting rate at all.

Nothing here prices the rest of the job. Compute, storage, the queue, the alerting, the human who reads the alerts, and the engineering time to build any of it are all excluded. On a small roster the data cost is frequently not the largest line, and a team that saves $80 a month by restructuring a job that took two days to restructure has made a poor trade unless the job was going to grow. That $80 is an illustrative saving, roughly the gap between a fifteen minute and a thirty minute poll on this roster at the rates on the pricing page. The arithmetic tells you what the data costs. It does not tell you whether the data cost is your problem, and for plenty of teams reading this, it is not.

That last point deserves the weight. The reason to run these numbers is not that they are always large. It is that they are always knowable, and a knowable number that nobody has computed is exactly where an unpleasant surprise lives.

What to do with this

If you run a watch today, the useful next step is not a rewrite. It is four numbers on one line: how many accounts, how often, what that multiplies to, and what a ten minute delay costs. Most jobs we see are one interval step away from a materially smaller bill and nobody has run the multiplication, because the setting lives in a file that has not been opened since the job shipped.

If you are building one, the decision is which shape rather than which vendor. A roster watch that needs to know when something happened wants the webhook route and costs almost nothing. A roster pull that needs everything those accounts said, for analysis later, wants a slow poll and costs almost nothing either. The expensive configuration is the middle one, a fast poll doing the first job with the second job's tool, and it is the default in most codebases precisely because it is nobody's decision.

The rates used throughout are the live ones, published in full on the pricing page: $0.0008 per standard read call covering reads and the simple write actions, $0.0016 for tweet creation and direct message sends and reads, $0.0024 for a full account history page, $0.0040 for a full thread expansion, and $0.50 of signup credit with no card. At twenty posts to a full page that is $0.04 per thousand posts on the read path. The full table is on the pricing page, the endpoint reference is at the API reference, and if you want to start with the roster rather than the docs, the quickstart is the shortest path to a first call.

One last time, because it is the only sentence in this post that matters: the vendor moves your monitoring bill by a few percent, and the interval moves it by a factor of 1,440.

Frequently Asked Questions

It depends entirely on the poll interval, and the spread is wider than most people expect. Watching a fixed fifty account roster with one timeline read per account per cycle, on the standard $0.0008 read rate, costs $1.20 a month at a daily cadence, $28.80 an hour, $115.20 every fifteen minutes, $345.60 every five minutes and $1,728.00 every minute. That is a 1,440 times range across the same roster, the same endpoint and the same rate. The vendor you pick moves this number by a few percent. The interval you pick moves it by three orders of magnitude, which is why the interval is the only part of the decision worth arguing about.

Fourteen minutes and thirty seconds of mean detection delay, and $1,612.80 a month on a fifty account roster. Mean delay is half the interval, so a one minute poll finds a post thirty seconds after it lands on average and a fifteen minute poll finds it seven minutes and thirty seconds after. Buying those fourteen minutes costs $46.08 per minute of mean delay removed at the fifteen to five minute step, and $691.20 per minute at the five to one minute step. The price of latency is not linear, it is a staircase that gets steeper at every step, which is the fact that should decide where you stop.

Yes, and it is the part missing from every page currently ranking for this query. The monitor and webhook surfaces sit in the biller's zero price set, alongside account and session endpoints, so registering a watch and receiving a delivery bills nothing at all. You pay only when you fetch something, which means you pay for signal and never for silence. On the fifty account roster used throughout this post, a webhook route costs $6.00 a month against $115.20 for a fifteen minute poll covering the same accounts with worse latency. The saving is exactly the empty poll share, because those are the same calls.

Not as far as a production watch, which is the honest answer and the useful one. The $0.50 signup credit buys 625 standard calls. On a fifty account roster that is 12.5 poll cycles, so a one minute poller exhausts it in 12.5 minutes, a fifteen minute poller in about three hours and eight minutes, and a daily pull in 12.5 days. That is enough to build the job end to end, confirm the response shape, watch it fire and check your parsing. It is not enough to leave running, and any plan that assumes otherwise has an arithmetic error rather than a budget.

It scales linearly with account count, exactly as it does with cadence, because both are simple multipliers on the same call count. At a fifteen minute interval, ten accounts cost $23.04 a month, twenty five cost $57.60, fifty cost $115.20, one hundred cost $230.40, two hundred and fifty cost $576.00 and five hundred cost $1,152.00. The practical consequence is that roster growth and cadence are interchangeable levers on the same budget. Doubling the roster and halving the frequency leaves the bill where it was, which is often the correct trade when the new accounts are lower signal than the original ones.

Multiply four numbers: cycles per day, accounts in the roster, days in the month, and the billed rate for the endpoint you are calling. A fifteen minute interval is 96 cycles a day, so fifty accounts over thirty days is 144,000 calls, and at $0.0008 per call that is $115.20. Nothing else in a typical watch comes close to that term, because a poll is the only line in the job whose frequency is set by a clock rather than by a human. Change the interval and the bill moves proportionally. Change the endpoint and it moves by a few percent, unless you have accidentally picked a premium tier.

No. It catches the same posts sooner, and it pays for a great many empty responses to do it. An account posting five times a day gives a one minute poller 1,440 chances a day to find something and five of them return anything new, so 99.65 percent of those calls are billed for nothing. At a fifteen minute interval the same account leaves 94.79 percent of cycles empty. Cost per post actually captured makes this plain: $0.2304 per post at one minute against $0.01536 at fifteen minutes and $0.00016 at a daily pull. You are not buying coverage with a shorter interval, you are buying freshness, and it is worth being clear which one the product needs.

When a minute of delay has a cost you can name, and that is a much shorter list than habit suggests. Incident response and brand safety qualify, because a hostile post compounds while nobody is looking. Market and trading signals qualify, because the edge decays in seconds. Everything else, competitor tracking, content research, lead discovery, reporting, does not, and those are the jobs that most often run on a one minute timer because nobody wrote the number down. The test is simple: state what a ten minute delay costs you in dollars. If you cannot, you are paying $1,612.80 a month more than a fifteen minute poll for something you have not valued.

For a named roster, poll the timeline. One timeline read per account per cycle is the cheapest correct shape, it returns up to twenty posts per call at the standard $0.0008 rate, and it cannot miss a post the way a keyword query can. Search is the right tool when the thing you are watching is a term rather than an account, and it carries a different failure mode: results are ranked and filtered rather than exhaustive, so absence from a search result is not evidence the post does not exist. Picking search for a roster job is the most common way a monitoring build ends up both more expensive and less complete.

Because a per call rate multiplied by a call volume is the bill, and only one of those two numbers appears on a price sheet. When X moved to pay per usage, one developer publicly reported a drop from about $200 a month to about $20, and another reported paying double what he used to. Neither is wrong. The variable between them is call volume, which is set by cadence and roster size, so the same rate change halves one bill and doubles another. It is the clearest available evidence that arguing about rates while ignoring intervals answers the wrong question.

Check out similar blogs

More guides on the Twitter/X API, scraping, and pricing.

Cost comparison for acquiring one million tweets in 2026 across metered API, scraper marketplace, public archive and dataset vendor routes
twitter api pricingtweet dataset

What a 1 Million Tweet Dataset Actually Costs in 2026: Every Route Priced

Ten results rank for the cost of a tweet dataset and one states a price. We fix the quantity at a million tweets and cost every route, with each number's source named.

Emma·
The health and coverage fields a Twitter monitoring API should expose so a caller can tell a dead collector from a quiet week
twitter monitoring apix api monitoring

What a Twitter Monitoring API Should Tell You When It Is Failing

Seven of the ten pages ranking for twitter monitoring api sell the happy path. None documents the fields that let you tell nothing matched from nothing was fetched.

Emma·
Why X advanced search returns no results for posts that exist, with measured recall rates across 17 posts published between 2015 and 2026
Twitter Advanced SearchX API

Why X Advanced Search Misses Posts You Know Exist (2026)

A query that returns nothing is not proof that nothing exists. We searched for 17 posts confirmed to exist, published between 2015 and 2026, and measured which query forms found them and which did not.

Emma·
X and Twitter platform statistics for 2026, showing which figures are measurable through a public API and which are not published by any source
twitter statisticsx statistics

X/Twitter Statistics in 2026: What an API Can Actually Measure, and What Nobody Can

Most X statistics roundups re-cite the same handful of numbers. We measured what a public API can and cannot see across 34 accounts, printed the query behind every figure, and traced the rest to their real sources.

Emma·
One normalized X API price sheet for 2026 converting the official rate card and every third-party vendor to dollars per 1,000 tweets read and per 1,000 posts written
X API costTwitter API pricing

X API Cost in 2026: Every Tier and Alternative on One Sheet

X bills per resource in 2026. Here is every official rate and every vendor converted to one unit, dollars per 1,000 tweets, with a worked bill.

TwitterAPIs·
Sprout Social, Brandwatch and a metered Twitter data API compared in one unit, dollars per 1,000 mentions retrieved, with every rate read from the vendor's own live pricing page in 2026
sprout social alternativebrandwatch pricing

Sprout Social Alternative 2026: What Twitter Data Really Costs

Sprout is $199 a seat. Brandwatch publishes no price. Here is what Twitter data costs per 1,000 mentions across all three, read live on 2026-09-09.

TwitterAPIs·
Measured Twitter API failure distribution across 5.16 million production calls in 2026, broken down by status code, endpoint and week
twitter api error ratetwitter api errors

Twitter API Reliability, Measured: What Actually Fails Across 5.16 Million Calls

Every vendor publishes an uptime promise. Nobody publishes the failure distribution. Here is what broke across 5,155,699 production calls, by status code, by endpoint and by week.

Emma·
What the Twitter firehose meant as a product, what replaced it after 2023, and what complete post coverage costs on per-call reads in 2026
twitter firehosetwitter firehose api

What the Twitter Firehose Actually Was, and What You Get Instead in 2026

The firehose was a real product with a precise meaning: every public post, in realtime, unsampled. It is not what anybody sells you today. Here is what the word meant, what replaced it, and what complete coverage costs on per-call reads.

Emma·