Skip to content
CaptiFi Connect

Behind the scenes8 min read

How fast can you send 10,000 texts?

GOV.UK Notify's API takes 3,000 texts a minute, so 10,000 need at least 3 min 20 s to submit. Rate limits, 429s, SMPP windows and how to plan a big send.

In short

  • GOV.UK Notify's API documentation limits a service to 3,000 messages a minute per API key type, so 10,000 texts sent one at a time take at least 3 minutes 20 seconds to submit.
  • GOV.UK Notify says the phone networks will block repeated texts to one number above 20 messages with the same content, or 100 with any content, in an hour.
  • GOV.UK Notify's performance page showed 8,520,425 texts sent on Wednesday 21 October 2026, an average of about 99 a second across the day.
  • RFC 6585, published in April 2012, defines the 429 Too Many Requests status and lets a server add a Retry-After header saying how long to wait.
  • CaptiFi Connect allows each API key 20 requests a second with bursts up to 40, and one send request can carry up to 1,000 typed numbers or a whole contact list.
3,000: texts a minute is GOV.UK Notify's API rate limit, so 10,000 take at least 3 min 20 s

3,000: texts a minute is GOV.UK Notify's API rate limit, so 10,000 take at least 3 min 20 s. Source: GOV.UK Notify, API documentation: rate limits.

How fast can you send 10,000 texts? There are two answers: how quickly a provider will take them from you, and how quickly the networks then get them to phones. The clearest published benchmark in the UK is the government's own platform. GOV.UK Notify's API documentation says "You're limited to sending 3,000 messages per minute", counted on a rolling basis for each type of API key, so 10,000 texts sent one request at a time take at least 3 minutes 20 seconds just to hand over. Notify then "commits to sending 95% of text messages within 10 seconds", and its provider keeps trying to deliver each one "for up to 72 hours".

So a big send is quick to submit and slower to finish, and the difference between the two is what catches people out when a campaign is still trickling in long after it left.

Where does the time go?

A text passes three places where its speed is capped. The first is the API you call, which refuses requests that come faster than its rate limit. The second is the provider's connection into the mobile networks, such as an SMPP link, where the message centre at the far end decides how many texts it will take at once. The third is the phone, which receives the text when it's switched on and in coverage, and not before. (The glossary entry on throughput covers the term.)

You control the first, and only partly. The other two are why a campaign that leaves your system in seconds can still be landing in pockets well afterwards, and the odd one the next morning.

What GOV.UK Notify publishes

Notify is worth reading closely because it publishes both its limits and its volumes. The API documentation sets out four things that matter for a big send.

  • A rate limit of 3,000 messages a minute per API key type, with a 429 RateLimitError if you go over. It adds: "You should avoid sending messages in large spikes."
  • A daily limit for a live service of 250,000 text messages, "including a default 100 international text messages", resetting at midnight UTC.
  • No bulk endpoint. "You cannot use a single API call to send messages in bulk", so you loop over the list one message at a time and stay under the rate limit. Through the website, a spreadsheet upload can send "a batch of up to 100,000 messages at once".
  • Phone network limits. If you text the same number repeatedly, "the phone networks will block them", and Notify puts the hourly ceiling at 20 messages with the same content and 100 messages with any content.

The last one is easy to skim past. It's a limit per phone number that sits with the networks, so it applies whoever you send through, and a test loop that fires a few hundred texts an hour at one developer's phone will run into it.

Then the volumes. Notify's performance page shows the latest seven days, and on 22 October 2026 it looked like this.

Text messages sent by GOV.UK Notify each day, 15 to 21 October 2026
0 m2.5 m5 m7.5 m10 mThu 15 Oct, Texts sent: 5.23 mThu 15 OctFri 16 Oct, Texts sent: 3.65 mFri 16 OctSat 17 Oct, Texts sent: 1.29 mSat 17 OctSun 18 Oct, Texts sent: 1.5 mSun 18 OctMon 19 Oct, Texts sent: 4.6 mMon 19 OctTue 20 Oct, Texts sent: 5.06 mTue 20 OctWed 21 Oct, Texts sent: 8.52 m8.52 mWed 21 Oct

Daily counts rounded to two decimal places of a million (21 October was 8,520,425). The page shows only the latest seven days, so these figures will have moved on.

Source: GOV.UK Notify, performance data, read 22 October 2026

See the figures as a table
 Texts sent (m)
Thu 15 Oct5.23
Fri 16 Oct3.65
Sat 17 Oct1.29
Sun 18 Oct1.5
Mon 19 Oct4.6
Tue 20 Oct5.06
Wed 21 Oct8.52

Wednesday 21 October was the busiest day of the week, with 8,520,425 texts. Spread evenly over 24 hours that's about 99 a second, and the traffic won't have been even (Saturday's 1,294,223 was under a sixth of it). The same page counts 1,764 organisations and 12,924 services using Notify, and the documentation describes the 3,000-a-minute limit as yours, counted per API key type (its error message even allows for a custom limit), which is how the platform as a whole can move eight and a half million texts in a day.

What a 429 means, and how to handle one

The status code comes from RFC 6585, which the IETF published in April 2012. Section 4 says 429 Too Many Requests "indicates that the user has sent too many requests in a given amount of time", and that the response "MAY include a Retry-After header indicating how long to wait before making a new request". The RFC leaves the counting to each server on purpose: it "does not define how the origin server identifies the user, nor how it counts requests". RFC 9110, the June 2022 edition of HTTP Semantics, defines Retry-After as either an HTTP date or "a number of seconds to delay after receiving the response"; its own example, Retry-After: 120, means two minutes.

In code that comes down to three habits. Read Retry-After and wait at least that long before trying again. Send the same request again, with the same idempotency key if the API takes one, so a request that did get through isn't sent twice. And don't let every worker retry at the same instant, or they'll all hit the limit together again; a little random jitter added to each wait spreads them out.

One detail catches people out. Because RFC 9110 allows either form, a client that runs Number(res.headers.get('Retry-After')) gets 120 for Retry-After: 120 and NaN for a date. Handle both: if the value isn't a number, pass it to Date.parse() and subtract the current time. CaptiFi Connect always sends whole seconds, rounded up and never less than one, but a client written for one API tends to end up talking to several.

How much does batching help?

A lot, because a rate limit counts requests and an API that accepts many numbers per request turns 10,000 sends into a handful. Here's the arithmetic for 10,000 texts under different shapes of request, using Notify's published limit and our own.

How the 10,000 are sentRequestsLeast time the rate limit allows
One text a request, at 3,000 a minute (GOV.UK Notify)10,0003 minutes 20 seconds
One text a request, at 20 a second with bursts of 40 (CaptiFi Connect)10,000about 8 minutes 18 seconds
1,000 numbers a request (CaptiFi Connect)10well inside one burst
One request naming a contact list (CaptiFi Connect)1one request

The second row works out as the first 40 requests at once and the remaining 9,960 at 20 a second, which is 498 seconds. Batching doesn't mean every text is identical, either: in a list send, merge fields such as {first_name} are filled in for each recipient from the contact record. None of these figures is a delivery time. They're the least time it takes the provider to accept the whole job, and everything after acceptance happens on the provider's side and the networks'.

Why a campaign still spreads over minutes

Behind the API, a provider hands texts on to the networks' message centres, and if that link is SMPP, the protocol has throttles of its own. The 1999 specification for version 3.4 leaves the number of unacknowledged requests to each message centre but recommends "no more than 10 (ten) SMPP messages are outstanding at any time". It also defines an error code for a sender that pushes too hard: ESME_RTHROTTLED, "ESME has exceeded allowed message limits". Version 5.0 (February 2003) added a congestion_state value a message centre can return with each response, and its worked example has a sender holding at 120 requests a second while the far end reports an optimum load, then easing back to 100 when it nears congestion. Our post on SMPP goes through the windows and throttles in detail.

Then the phones. A text to a phone that's off or out of signal waits in the network's message centre until the phone comes back, which is why the tail of any big send stretches out over hours. Notify's provider allows up to 72 hours. Our post on why a text can arrive late explains the store and forward mechanism behind that.

Put those together and a send to 10,000 people looks like this: a few seconds or minutes to accept, a short burst as the bulk goes out, and a long tail of phones picking their texts up when they reappear. The delivery reports fill in over the same curve.

Planning a send to 10,000

A few habits make a big send predictable.

  1. Send it as one job. A list or a batch of numbers in one request uses one slot of the rate limit and gets one answer back. A loop of 10,000 single sends spends minutes pressed against the rate limit and has 10,000 chances to fail halfway.
  2. Use an idempotency key on the batch request. If the connection drops after you've sent it, a retry with the same key returns the original answer, and nothing goes out twice.
  3. Price it first. Check the balance or ask the API for a quote before the real send, so a large job doesn't stop for lack of credit.
  4. Schedule it ahead. A send that has to land by 9am should be queued well before, so the long tail has time to arrive.
  5. Keep a test loop off a single real phone. The network limit Notify quotes, 100 texts an hour to one number, applies to your developers too, and a test key that sends nothing is the better tool.
  6. Watch the delivery reports by the hour. A rising count of permanent failures early in a send often points to a problem with the list, and it's cheaper to stop and look than to finish.

Sending 10,000 with CaptiFi Connect

Each CaptiFi Connect API key can make 20 requests a second, with bursts up to 40, and a request over that gets a 429 with a Retry-After header. You rarely need to get near it for a big send. POST /messages takes up to 1,000 typed numbers in one request, or a set of contact ids, or a contact list, and a single send can have up to 50,000 recipients. The whole send has to be covered by your balance: if it isn't, you get a 402 with the credits needed and nothing is sent, and numbers we refuse (landlines, numbers outside the UK, Guernsey, Jersey and the Isle of Man, and opted-out contacts) are listed and never charged. A list send started inside your quiet hours waits for them to end unless you tell it otherwise, and a queued text that hasn't gone within 24 hours is marked failed and refunded, so nothing goes out days late. Campaigns go through a licensed aggregator route built for volume, and we don't publish a messages-per-second figure for delivery. Until an account is approved, a person reads each of its texts before it goes out, so plan a first big send for after approval. The bulk SMS page has the rest, and the errors reference lists every response a send can return.

Sources

Read for this post on 22 October 2026.

Written by the CaptiFi Connect team. Published 22 October 2026. More in Behind the scenes

Send your first text this week

Set up your account and contacts now. Until we've approved it, a person reads each text before it goes out.